KSquare Utilities
KKStrParser.cpp
Go to the documentation of this file.
1 /* KKStrParser.cpp -- Class used to parse string into tokens.
2  * Copyright (C) 1994-2014 Kurt Kramer
3  * For conditions of distribution and use, see copyright notice in KKB.h
4  */
5 
6 #include "FirstIncludes.h"
7 #include <ctype.h>
8 #include <math.h>
9 #include <stdio.h>
10 #include <iostream>
11 #include <string.h>
12 #include <string>
13 #include <vector>
14 
15 #include "MemoryDebug.h"
16 using namespace std;
17 
18 #include "KKBaseTypes.h"
19 #include "DateTime.h"
20 #include "KKStr.h"
21 using namespace KKB;
22 
23 
24 #include "KKStrParser.h"
25 
26 
27 
28 KKStrParser::KKStrParser (const KKStrParser& _strParser):
30  nextPos (_strParser.nextPos),
31  str (_strParser.str),
32  trimWhiteSpace (_strParser.trimWhiteSpace),
33  weOwnStr (false),
34  whiteSpace (NULL)
35 {
36  if (_strParser.whiteSpace)
37  whiteSpace = STRDUP (_strParser.whiteSpace);
38 }
39 
40 
41 
42 KKStrParser::KKStrParser (const KKStr& _str):
43  len (_str.Len ()),
44  nextPos (0),
45  str (_str.Str ()),
46  trimWhiteSpace (false),
47  weOwnStr (false),
48  whiteSpace (NULL)
49 {
50 }
51 
52 
53 
54 KKStrParser::KKStrParser (const char* _str):
55  len ((kkuint16)strlen (_str)),
56  nextPos (0),
57  str (_str),
58  trimWhiteSpace (false),
59  weOwnStr (false),
60  whiteSpace (NULL)
61 {
62 }
63 
64 
65 
67  len (_str.Len ()),
68  nextPos (0),
69  str (_str.Str ()),
70  trimWhiteSpace (false),
71  weOwnStr (true),
72  whiteSpace (NULL)
73 {
74  str = KKB::STRDUP (_str.Str ());
75  weOwnStr = true;
76 }
77 
78 
79 
80 
81 
83 {
84  delete whiteSpace;
85  if (weOwnStr)
86  {
87  delete str;
88  str = NULL;
89  }
90 }
91 
92 
93 
94 
95 void KKStrParser::TrimWhiteSpace (const char* _whiteSpace)
96 {
97  delete whiteSpace;
98  whiteSpace = NULL;
99 
100  trimWhiteSpace = true;
101  if (_whiteSpace)
102  whiteSpace = STRDUP (_whiteSpace);
103  else
104  whiteSpace = STRDUP (" ");
105 
106  SkipWhiteSpace (whiteSpace);
107 }
108 
109 
110 
111 void KKStrParser::SkipWhiteSpace (const char* whiteSpace)
112 {
113  while ((nextPos < len) && (strchr (whiteSpace, str[nextPos]) != NULL))
114  nextPos++;
115 } /* SkipWhiteSpce */
116 
117 
118 
119 VectorKKStr KKStrParser::Split (const char* delStr)
120 {
121  VectorKKStr tokens;
122  while (MoreTokens ())
123  tokens.push_back (this->GetNextToken (delStr));
124  return tokens;
125 }
126 
127 
128 
129 
130 
131 KKStr KKStrParser::GetNextToken (const char* delStr)
132 {
133  lastDelimiter = 0;
134 
135  if (trimWhiteSpace)
136  {
137  while ((nextPos < len) && (strchr (whiteSpace, str[nextPos]) != NULL))
138  nextPos++;
139  }
140 
141  if (nextPos >= len)
142  return KKStr::EmptyStr ();
143 
144  kkuint32 startPos = nextPos;
145  kkuint32 endPos = startPos;
146 
147  char ch = str[endPos];
148  if ((ch == '\'') || (ch == '"'))
149  {
150  KKStr token (30);
151  // Token is a string
152  char quoteChar = ch;
153 
154  // We have a quoted String need to skip to end of quote.
155 
156  ++endPos; // Skipped past initial quote character.
157  while (endPos < len)
158  {
159  ch = str[endPos];
160  if (ch == quoteChar)
161  break;
162 
163  if ((ch == '\\') && (endPos < (len - 1)))
164  {
165  ++endPos;
166  char ec = str[endPos];
167  switch (ec)
168  {
169  case '\\': ch = '\\'; break;
170  case '"': ch = '"'; break;
171  case 'r': ch = '\r'; break;
172  case 'n': ch = '\n'; break;
173  case 't': ch = '\t'; break;
174  }
175  }
176 
177  token.Append (ch);
178  ++endPos;
179  }
180 
181  if (endPos >= len)
182  {
183  nextPos = len;
184  }
185  else
186  {
187  // Now that we are at the end of the quoted String we need set the next character pointer to just past the following delimiter character.
188  nextPos = endPos + 1;
189  if (trimWhiteSpace)
190  {
191  while ((nextPos < len) && (strchr (whiteSpace, str[nextPos]) != NULL))
192  nextPos++;
193  }
194 
195  if ((nextPos < len) && (strchr (delStr, str[nextPos]) != NULL))
196  {
197  lastDelimiter = str[nextPos];
198  ++nextPos;
199  }
200  }
201  return token;
202  }
203  else
204  {
205  // scan until end of string or next delimiter
206  kkuint32 delimeterIdx = 0;
207  bool delimeterFound = false;
208  while (endPos < len)
209  {
210  ch = str[endPos];
211  if (strchr (delStr, ch) != NULL)
212  {
213  lastDelimiter = ch;
214  delimeterFound = true;
215  delimeterIdx = endPos;
216  break;
217  }
218  ++endPos;
219  }
220 
221  endPos--; // Move endPos back to last character in token.
222 
223  if (trimWhiteSpace)
224  {
225  while ((endPos >= startPos) && (strchr (whiteSpace, str[endPos]) != NULL))
226  endPos--;
227  }
228 
229 
230  if (delimeterFound)
231  nextPos = delimeterIdx + 1;
232 
233  else if (endPos >= len)
234  nextPos = len;
235 
236  else
237  nextPos = endPos + 1;
238 
239  if (trimWhiteSpace)
240  {
241  while ((nextPos < len) && (strchr (whiteSpace, str[nextPos]) != NULL))
242  ++nextPos;
243  }
244 
245  return KKStr (str, startPos, endPos);
246  }
247 } /* GetNextToken */
248 
249 
250 
251 
252 /**
253  *@brief Returns what the next token that 'GetNextToken' will without updating the position in the string buffer.
254  *@details Allows you to see what the token would be without updating the KKStrParser instance.
255  *@param[in] delStr List of delimiting characters.
256  *@returns Next Token to be returned by 'GetNextToken'.
257  */
258 KKStr KKStrParser::PeekNextToken (const char* delStr) const
259 {
260  kkuint32 nextPosP = nextPos;
261 
262  if (trimWhiteSpace)
263  {
264  while ((nextPos < len) && (strchr (whiteSpace, str[nextPosP]) != NULL))
265  nextPosP++;
266  }
267 
268  if (nextPosP >= len)
269  return KKStr::EmptyStr ();
270 
271  kkuint32 startPos = nextPosP;
272  kkuint32 endPos = startPos;
273 
274  char ch = str[endPos];
275  if ((ch == '\'') || (ch == '"'))
276  {
277  KKStr token (30);
278  // Token is a string
279  char quoteChar = ch;
280  // We have a quoted String need to skip to end of quote.
281  ++endPos;
282  while (endPos < len)
283  {
284  ch = str[endPos];
285  if (ch == quoteChar)
286  {
287  ++endPos;
288  break;
289  }
290 
291  if ((ch == '\\') && (endPos < (len - 1)))
292  {
293  ++endPos;
294  char ec = str[endPos];
295  switch (ec)
296  {
297  case '"': ch = '"'; break;
298  case '\\': ch = '\\'; break;
299  case 'r': ch = '\r'; break;
300  case 'n': ch = '\n'; break;
301  case 't': ch = '\t'; break;
302  }
303  }
304 
305  token.Append (ch);
306  ++endPos;
307  }
308  return token;
309  }
310  else
311  {
312  // scan until end of string or next delimiter
313  while (endPos < len)
314  {
315  ch = str[endPos];
316  if (strchr (delStr, ch) != NULL)
317  {
318  break;
319  }
320  ++endPos;
321  }
322 
323  endPos--; // Move endPos back to last character in token.
324 
325  if (trimWhiteSpace)
326  {
327  while ((endPos >= startPos) && (strchr (whiteSpace, str[endPos]) != NULL))
328  endPos--;
329  }
330 
331  return KKStr (str, startPos, endPos);
332  }
333 } /* PeekNextToken */
334 
335 
336 
338 {
339  char nextChar = 0;
340  if (nextPos < len)
341  {
342  nextChar = str[nextPos];
343  ++nextPos;
344  }
345  return nextChar;
346 }
347 
348 
349 
351 {
352  char lastChar = 0;
353  if (nextPos < len)
354  {
355  --len;
356  lastChar = str[len];
357  }
358  return lastChar;
359 }
360 
361 
362 
363 char KKStrParser::PeekNextChar () const
364 {
365  char nextChar = 0;
366  if (nextPos < len)
367  {
368  nextChar = str[nextPos];
369  }
370  return nextChar;
371 }
372 
373 
374 
375 char KKStrParser::PeekLastChar () const
376 {
377  char lastChar = 0;
378  if (nextPos < len)
379  {
380  lastChar = str[len - 1];
381  }
382  return lastChar;
383 }
384 
385 
386 
387 
388 char KKStrParser::GetNextTokenChar (const char* delStr)
389 {
390  KKStr nextToken = GetNextToken (delStr);
391  char nextTokenChar = nextToken[0];
392  return nextTokenChar;
393 }
394 
395 
397 {
398  return KKB::DateTime (GetNextToken (delStr));
399 }
400 
401 
402 
403 
404 kkint32 KKStrParser::GetNextTokenInt (const char* delStr)
405 {
406  return GetNextToken (delStr).ToInt ();
407 }
408 
409 
410 
411 long KKStrParser::GetNextTokenLong (const char* delStr)
412 {
413  return GetNextToken (delStr).ToLong ();
414 }
415 
416 
417 
418 double KKStrParser::GetNextTokenDouble (const char* delStr)
419 {
420  return GetNextToken (delStr).ToDouble ();
421 }
422 
423 
424 float KKStrParser::GetNextTokenFloat (const char* delStr)
425 {
426  return GetNextToken (delStr).ToFloat ();
427 }
428 
429 
430 
431 kkuint32 KKStrParser::GetNextTokenUint (const char* delStr)
432 {
433  return GetNextToken (delStr).ToUint ();
434 }
435 
436 
437 
438 bool KKStrParser::GetNextTokenBool (const char* delStr)
439 {
440  return GetNextToken (delStr).ToBool ();
441 }
442 
443 
444 
446 {
447  if (trimWhiteSpace)
448  {
449  while ((nextPos < len) && (strchr (whiteSpace, str[nextPos]) != NULL))
450  nextPos++;
451  }
452 
453  if (nextPos >= len)
454  return KKStr::EmptyStr ();
455 
456  KKStr result (1 + len - nextPos);
457  char lastChar = 0;
458 
459  while (nextPos < len)
460  {
461  lastChar = str[nextPos];
462  if (lastChar == '\n')
463  break;
464 
465  else if (lastChar == '\r')
466  break;
467 
468  result.Append (lastChar);
469  nextPos++;
470  }
471 
472  if (nextPos < len)
473  {
474  if (lastChar == '\n')
475  {
476  if (str[nextPos] == '\r')
477  nextPos++;
478  }
479  else if (lastChar == '\r')
480  {
481  if (str[nextPos] == '\n')
482  nextPos ++;
483  }
484  }
485 
486  if (trimWhiteSpace)
487  result.TrimRight (whiteSpace);
488 
489  return result;
490 } /* GetRestOfLine */
491 
492 
493 
495 {
496  if (trimWhiteSpace)
497  {
498  while ((nextPos < len) && (strchr (whiteSpace, str[nextPos]) != NULL))
499  nextPos++;
500  }
501 
502  if (nextPos >= len)
503  return KKStr::EmptyStr ();
504 
505  KKStr result (1 + len - nextPos);
506  while (nextPos < len)
507  {
508  result.Append (str[nextPos]);
509  nextPos++;
510  }
511 
512  if (trimWhiteSpace)
513  result.TrimRight (whiteSpace);
514 
515  return result;
516 } /* GetRestOfStr */
517 
518 
519 
521 {
522  nextPos = 0;
523 }
524 
525 
526 
527 
529  kkuint32 lastChar
530  ) const
531 {
532  if (lastChar < firstChar)
533  return KKStr::EmptyStr ();
534 
535  kkuint32 subStrLen = (1 + lastChar - firstChar);
536  KKStr result (subStrLen + 1);
537 
538  if (lastChar >= len)
539  lastChar = len - 1;
540 
541  kkuint32 idx = 0;
542  for (idx = firstChar; idx <= lastChar; idx++)
543  result.Append (str[idx]);
544 
545  return result;
546 }
KKStr(kkint32 size)
Creates a KKStr object that pre-allocates space for &#39;size&#39; characters.
Definition: KKStr.cpp:655
bool GetNextTokenBool(const char *delStr="\n\t\r ")
char * STRDUP(const char *src)
Definition: KKStr.cpp:62
KKStr SubStrPart(kkuint32 firstChar, kkuint32 lastChar) const
__int32 kkint32
Definition: KKBaseTypes.h:88
void TrimWhiteSpace(const char *_whiteSpace=" ")
After this call all leading and trailing whitespace will be trimmed from tokens.
Definition: KKStrParser.cpp:95
KKStrParser(const KKStrParser &_strParser)
Definition: KKStrParser.cpp:28
KKStr & TrimRight(const char *whiteSpaceChars="\n\r\t ")
Definition: KKStr.cpp:1695
KKStr GetNextToken(const char *delStr="\n\t\r ")
Extract next Token from string, tokens will be separated by delimiter characters. ...
KKStrParser(KKStr &&_str)
Definition: KKStrParser.cpp:66
DateTime(const KKStr &s)
Definition: DateTime.cpp:1043
kkint32 ToInt() const
Definition: KKStr.cpp:3565
long GetNextTokenLong(const char *delStr="\n\t\r ")
unsigned __int32 kkuint32
Definition: KKBaseTypes.h:89
float GetNextTokenFloat(const char *delStr="\n\t\r ")
kkuint32 Len() const
Returns the number of characters in the string.
Definition: KKStr.h:366
char PeekNextChar() const
KKTHread * KKTHreadPtr
void Append(char ch)
Definition: KKStr.cpp:1863
KKStrParser(const KKStr &_str)
Definition: KKStrParser.cpp:42
kkuint32 ToUint() const
Definition: KKStr.cpp:3636
void SkipWhiteSpace(const char *whiteSpace=" ")
Advances the next-character pointer to the next NOT white space character.
char PeekLastChar() const
VectorKKStr Split(const char *delStr="\n\t\r ")
KKStr PeekNextToken(const char *delStr="\n\t\r ") const
Will use the same rules as "GetNextToken" to retrieve the next token n the string but will not advanc...
kkuint32 GetNextTokenUint(const char *delStr="\n\t\r ")
static KKStr Concat(const std::vector< std::string > &values)
Concatenates the list of &#39;std::string&#39; strings.
Definition: KKStr.cpp:1082
KKStr(const char *src, kkuint32 startPos, kkuint32 endPos)
Constructs a KKStr instance from a sub-string of &#39;src&#39;.
Definition: KKStr.cpp:693
KKB::DateTime GetNextTokenDateTime(const char *delStr="\n\t\r ")
static const KKStr & EmptyStr()
Static method that returns an Empty String.
Definition: KKStr.cpp:3453
long ToLong() const
Definition: KKStr.cpp:3611
double GetNextTokenDouble(const char *delStr="\n\t\r ")
kkint32 GetNextTokenInt(const char *delStr="\n\t\r ")
double ToDouble() const
Definition: KKStr.cpp:3541
const char * Str() const
Returns a pointer to a ascii string.
Definition: KKStr.h:422
char operator[](kkint32 i) const
Definition: KKStr.cpp:3413
Class that manages the extraction of tokens from a String without being destructive to the original s...
Definition: KKStrParser.h:18
float ToFloat() const
Definition: KKStr.cpp:3553
bool ToBool() const
Returns the bool equivalent of the string, ex &#39;Yes&#39; = true, &#39;No&#39; = false, &#39;True&#39; = true...
Definition: KKStr.cpp:3523
char GetNextTokenChar(const char *delStr="\n\t\r ")
KKStrParser(const char *_str)
Definition: KKStrParser.cpp:54