All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
StringTool.cpp
Go to the documentation of this file.
1 /*
2  * StringTool.cpp
3  *
4  * This file is part of the HausmiSEP project
5  *
6  * Copyright (C) 2012, 2013 Marco Alvarado (malvcr@gmail.com)
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <HSEP/StringTool.h>
23 
24 #include <string.h>
25 
26 using namespace std;
27 
28 namespace HSEP {
29 
30  ErrorCode StringTool::split(char* pSourcePtr, const char* pSepLevelsPtr, StringDictionary& pDestRef) {
31 
33 
34  if (strlen(pSepLevelsPtr) < 2) {
35  vResult = EC::IncompleteParameter;
36  }
37  else {
38 
39  char vThisName [MAXTOKEN_SIZE+1];
40  char vThisValue [MAXVALUE_SIZE+1];
41  memset(vThisName ,0,MAXTOKEN_SIZE+1);
42  memset(vThisValue,0,MAXVALUE_SIZE+1);
43 
44  int vTokenIdx = 0;
45 
46  char vSepFirstLevel = pSepLevelsPtr[0];
47  char vSepSecondLevel = pSepLevelsPtr[1];
48 
49  bool vCheckingName = true;
50  bool vCheckingValue = false;
51 
52  size_t vSourceLen = strlen(pSourcePtr);
53 
54  for (size_t vIdx=0; vIdx<vSourceLen; vIdx++) {
55 
56  char vAt = pSourcePtr[vIdx];
57 
58  if (vCheckingName) {
59  if (vAt == vSepSecondLevel) {
60  vCheckingName = false;
61  vCheckingValue = true;
62  vTokenIdx = 0;
63  }
64  else {
65  if ((vTokenIdx > MAXTOKEN_SIZE) && (vAt != '\0')) { // short circuit type of evaluation
66  vResult = EC::BufferOverflow;
67  break;
68  }
69  vThisName[vTokenIdx] = vAt;
70  vTokenIdx++;
71  }
72  } // if (vCheckingName) {
73  else if (vCheckingValue) {
74  if (vAt == vSepFirstLevel) {
75  vCheckingName = true;
76  vCheckingValue = false;
77  vTokenIdx = 0;
78 
79  string vThisNameStr(vThisName);
80  string vThisValueStr(vThisValue);
81 
82  pDestRef.put(vThisNameStr,vThisValueStr);
83 
84  memset(vThisName ,0,MAXTOKEN_SIZE+1 );
85  memset(vThisValue,0,MAXVALUE_SIZE+1);
86  }
87  else {
88  if ((vTokenIdx > MAXVALUE_SIZE) && (vAt != '\0')) { // short circuit type of evaluation
89  vResult = EC::BufferOverflow;
90  break;
91  }
92  vThisValue[vTokenIdx] = vAt;
93  vTokenIdx++;
94  }
95 
96  } // else if (vCheckingValue) {
97 
98  } // for (unsigned int vIdx=0; vIdx<pSource.length(); vIdx++) {
99 
100  if (EC::IncompleteProcessing == vResult) {
101  vResult = EC::OK;
102  }
103  }
104  return vResult;
105 
106  } // StringTool::split
107 
108  ErrorCode StringTool::split(string& pSourceRef, const string pSeparator, StringArray& pDestRef) {
109 
111 
112  pDestRef.clear();
113 
124  size_t vSourceLength = pSourceRef.length();
125 
126  if (0 == vSourceLength) { // trivial case
127  vResult = EC::OK;
128  }
129  else {
130 
131  size_t vSepSize = pSeparator.length();
132  size_t vCurrentPos = 0;
133  size_t vPreviousPos = 0;
134  size_t vMaxPos = vSourceLength - vSepSize;
135 
136  string vSample;
137 
143  while (vCurrentPos != string::npos) {
144 
145  vCurrentPos = pSourceRef.find(pSeparator,vPreviousPos);
146 
147  if (string::npos == vCurrentPos) {
148  vSample = pSourceRef.substr(vPreviousPos);
149  }
150  else {
151  vSample = pSourceRef.substr(vPreviousPos,vCurrentPos - vPreviousPos);
152 
153  if (vCurrentPos > vMaxPos) {
154  vCurrentPos = string::npos;
155  }
156  else {
157  vPreviousPos = vCurrentPos + vSepSize;
158  }
159  }
160  pDestRef.push(vSample);
161 
162  } // while (vCurrentPos != string::npos) {
163 
164  vResult = EC::OK;
165  }
166  return vResult;
167 
168  } // StringTool::split
169 
170 
171 
172  ErrorCode StringTool::toHex(void* pSource,size_t pSize,string& pDestination) {
173 
174  for (size_t vIdx=0; vIdx < pSize; vIdx++) {
175  unsigned char vValue = ((char*)pSource)[vIdx];
176  unsigned char vValueHex[3];
177  unsigned char vHigh = HEXVALUES[vValue>>4];
178  unsigned char vLow = HEXVALUES[vValue&0x0F];
179  vValueHex[0] = vHigh;
180  vValueHex[1] = vLow;
181  vValueHex[2] = '\0';
182  pDestination.append((char*)vValueHex);
183  }
184 
185  return EC::OK;
186 
187  } // StringTool::toHex
188 
189  ErrorCode StringTool::fromHex(string& pSource, void* pDestination, size_t pDestinationSize) {
190 
192 
193  size_t vSize = pSource.size();
194 
195  if (vSize % 2) {
196 
197  vResult = EC::EvenSizeExpected;
198 
199  } else if ((vSize / 2) > pDestinationSize) {
200 
201  vResult = EC::BufferOverflow;
202 
203  } else {
204 
205  char* vStr = (char*) (pSource.c_str());
206  char* vPtr = (char*) (pDestination);
207 
208  size_t vDataIdx = 0;
209 
210  for (size_t vPointer = 0; vPointer < vSize; vPointer += 2) {
211 
212  if (strchr(HEXVALUES, vStr[vPointer]) && strchr(HEXVALUES, vStr[vPointer + 1])) {
213  // All these conversions are included to work warnings about
214  // implicit conversion from char to int when applying bit operations.
215  // Also, as we use characters as REVHEX indexes, and the indexes must be of
216  // int type, a conversion must be performed.
217  //
218  char vHigh = static_cast<char>(REVHEX[(int)vStr[vPointer]] << 4);
219  char vLow = static_cast<char>(REVHEX[(int)vStr[vPointer + 1]]);
220  char vValue = static_cast<char>(vHigh + vLow);
221  vPtr[vDataIdx] = vValue;
222  vDataIdx++;
223  } else {
224  vResult = EC::InvalidHexValue;
225  break;
226  }
227  vResult = EC::OK;
228  }
229  }
230 
231  return vResult;
232 
233  } // StringTool::fromHex
234 
235 
236  ErrorCode StringTool::ltrim(string& pStringRef) {
237 
239 
240  size_t vTotal = pStringRef.size();
241 
242  // Don't work on empty strings, that will produce invalid access exceptions.
243  //
244  if (vTotal > 0) {
245 
246  const char* vPtr = pStringRef.c_str();
247 
248  bool vEndLoop = false;
249 
250  // The vIndex must start with zero, because it is used as a counter.
251  // When starting with 1, will discard the important case where no
252  // spaces are in the beginning of the string.
253  //
254  size_t vIndex = 0;
255 
256  while (!vEndLoop) {
257 
258  // When arrive to the end, the string was empty.
259  //
260  if (vIndex == vTotal) {
261  pStringRef.clear();
262  vEndLoop = true;
263  vResult = EC::OK;
264  }
265  else {
266  if (isspace(vPtr[vIndex])) {
267  vIndex++;
268  }
269  else {
270  pStringRef.erase(0,vIndex);
271  vEndLoop = true;
272  vResult = EC::OK;
273  }
274  }
275  }
276  }
277 
278  return vResult;
279 
280  } // StringTool::ltrim
281 
282  ErrorCode StringTool::drop(string& pStringRef, const char* pDropHead) {
283 
285 
286  // Don't work on empty strings
287  //
288  if (pStringRef.size()>0) {
289  size_t vPos = pStringRef.find(pDropHead);
290 
291  if (pStringRef.npos != vPos) {
292  pStringRef.erase(vPos,pStringRef.npos);
293  }
294  }
295  vResult = EC::OK; // not yet an exception to this behavior have been found
296 
297  return vResult;
298 
299  } // StringTool:drop
300 
301 } // HSEP namespace