version 0.1.8
[fms.git] / src / stringfunctions.cpp
1 #include "../include/stringfunctions.h"\r
2 \r
3 #include <algorithm>\r
4 \r
5 #ifdef XMEM\r
6         #include <xmem.h>\r
7 #endif\r
8 \r
9 namespace StringFunctions\r
10 {\r
11 \r
12 std::string Replace(const std::string &input, const std::string &find, const std::string &replace)\r
13 {\r
14         std::string returnstr=input;\r
15         std::string::size_type pos=returnstr.find(find);\r
16 \r
17         while(pos!=std::string::npos)\r
18         {\r
19                 returnstr.replace(pos,find.size(),replace);\r
20                 pos=returnstr.find(find,pos+replace.size());\r
21         }\r
22 \r
23         return returnstr;\r
24 \r
25 }\r
26 \r
27 void Split(const std::string &str, const std::string &delim, std::vector<std::string> &output)\r
28 {\r
29         std::string::size_type offset = 0;\r
30         std::string::size_type delimIndex = 0;\r
31     \r
32     delimIndex = str.find(delim, offset);\r
33 \r
34     while (delimIndex != std::string::npos)\r
35     {\r
36         output.push_back(str.substr(offset, delimIndex - offset));\r
37         offset += delimIndex - offset + delim.length();\r
38         delimIndex = str.find(delim, offset);\r
39     }\r
40 \r
41     output.push_back(str.substr(offset));\r
42 }\r
43 \r
44 void SplitMultiple(const std::string &str, const std::string &delim, std::vector<std::string> &output)\r
45 {\r
46         std::string::size_type offset = 0;\r
47         std::string::size_type delimIndex = 0;\r
48     \r
49     delimIndex = str.find_first_of(delim, offset);\r
50 \r
51     while (delimIndex != std::string::npos)\r
52     {\r
53         output.push_back(str.substr(offset, delimIndex - offset));\r
54         offset += delimIndex - offset + 1;\r
55         delimIndex = str.find_first_of(delim, offset);\r
56     }\r
57 \r
58     output.push_back(str.substr(offset));\r
59 }\r
60 \r
61 std::string TrimWhitespace(const std::string &str)\r
62 {\r
63         std::string returnstring=str;\r
64 \r
65         while(returnstring.size()>0 && returnstring.find_first_of(" \t\r\n")==0)\r
66         {\r
67                 returnstring.erase(0,1);\r
68         }\r
69         while(returnstring.size()>0 && returnstring.find_last_of(" \t\r\n")==returnstring.size()-1)\r
70         {\r
71                 returnstring.erase(returnstring.size()-1,1);\r
72         }\r
73 \r
74         return returnstring;\r
75 }\r
76 \r
77 void UpperCase(const std::string &str, std::string &output)\r
78 {\r
79         output=str;\r
80         std::transform(str.begin(),str.end(),output.begin(),toupper);\r
81 }\r
82 \r
83 std::string UriDecode(const std::string & sSrc)\r
84 {\r
85    // Note from RFC1630: "Sequences which start with a percent\r
86    // sign but are not followed by two hexadecimal characters\r
87    // (0-9, A-F) are reserved for future extension"\r
88    \r
89 static const char HEX2DEC[256] = \r
90 {\r
91     /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */\r
92     /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
93     /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
94     /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
95     /* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,\r
96     \r
97     /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
98     /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
99     /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
100     /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
101     \r
102     /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
103     /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
104     /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
105     /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
106     \r
107     /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
108     /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
109     /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,\r
110     /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1\r
111 };\r
112 \r
113    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();\r
114    const int SRC_LEN = sSrc.length();\r
115    const unsigned char * const SRC_END = pSrc + SRC_LEN;\r
116    // last decodable '%'\r
117    const unsigned char * const SRC_LAST_DEC = SRC_END - 2;\r
118 \r
119    char * const pStart = new char[SRC_LEN];\r
120    char * pEnd = pStart;\r
121 \r
122    while (pSrc < SRC_LAST_DEC)\r
123    {\r
124       if (*pSrc == '%')\r
125       {\r
126          char dec1, dec2;\r
127          if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)])\r
128             && -1 != (dec2 = HEX2DEC[*(pSrc + 2)]))\r
129          {\r
130             *pEnd++ = (dec1 << 4) + dec2;\r
131             pSrc += 3;\r
132             continue;\r
133          }\r
134       }\r
135 \r
136       *pEnd++ = *pSrc++;\r
137    }\r
138 \r
139    // the last 2- chars\r
140    while (pSrc < SRC_END)\r
141       *pEnd++ = *pSrc++;\r
142 \r
143    std::string sResult(pStart, pEnd);\r
144    delete [] pStart;\r
145    return sResult;\r
146 }\r
147 \r
148 std::string UriEncode(const std::string & sSrc)\r
149 {\r
150         \r
151 // Only alphanum is safe.\r
152 static const char SAFE[256] =\r
153 {\r
154     /*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */\r
155     /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
156     /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
157     /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
158     /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,\r
159     \r
160     /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,\r
161     /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,\r
162     /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,\r
163     /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,\r
164     \r
165     /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
166     /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
167     /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
168     /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
169     \r
170     /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
171     /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
172     /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,\r
173     /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0\r
174 };\r
175         \r
176    const char DEC2HEX[16 + 1] = "0123456789ABCDEF";\r
177    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();\r
178    const int SRC_LEN = sSrc.length();\r
179    unsigned char * const pStart = new unsigned char[SRC_LEN * 3];\r
180    unsigned char * pEnd = pStart;\r
181    const unsigned char * const SRC_END = pSrc + SRC_LEN;\r
182 \r
183    for (; pSrc < SRC_END; ++pSrc)\r
184    {\r
185       if (SAFE[*pSrc])\r
186          *pEnd++ = *pSrc;\r
187       else\r
188       {\r
189          // escape this char\r
190          *pEnd++ = '%';\r
191          *pEnd++ = DEC2HEX[*pSrc >> 4];\r
192          *pEnd++ = DEC2HEX[*pSrc & 0x0F];\r
193       }\r
194    }\r
195 \r
196    std::string sResult((char *)pStart, (char *)pEnd);\r
197    delete [] pStart;\r
198    return sResult;\r
199 }\r
200 \r
201 }       // namespace\r