KSquare Utilities
KKStr.cpp
Go to the documentation of this file.
1 /* Str.cpp -- String Management Class
2  * Copyright (C) 1994-2011 Kurt Kramer
3  * For conditions of distribution and use, see copyright notice in KKB.h
4  */
5 #include "FirstIncludes.h"
6 #include <ctype.h>
7 #include <limits.h>
8 #include <math.h>
9 #include <stdio.h>
10 #include <iostream>
11 #include <memory>
12 #include <sstream>
13 #include <string>
14 #include <vector>
15 #include <string.h>
16 
17 #include "MemoryDebug.h"
18 using namespace std;
19 
20 #include "KKQueue.h"
21 
22 #include "KKStr.h"
23 #include "KKException.h"
24 #include "KKStrParser.h"
25 #include "RunLog.h"
26 #include "XmlStream.h"
27 using namespace KKB;
28 
29 
30 
31 char* KKB::STRCOPY (char* dest,
32  kkuint16 destSize,
33  const char* src
34  )
35 {
36 # ifdef USE_SECURE_FUNCS
37  strcpy_s (dest, destSize, src);
38 # else
39  strcpy (dest, src);
40 # endif
41  return dest;
42 } /* STRCOPY */
43 
44 
45 
46 char* KKB::STRCOPY (char* dest,
47  kkint32 destSize,
48  const char* src
49  )
50 {
51 # ifdef USE_SECURE_FUNCS
52  strcpy_s (dest, destSize, src);
53 # else
54  strcpy (dest, src);
55 # endif
56  return dest;
57 } /* STRCOPY */
58 
59 
60 
61 
62 char* KKB::STRDUP (const char* src)
63 {
64 # ifdef USE_SECURE_FUNCS
65  return _strdup (src);
66 # else
67  return strdup (src);
68 # endif
69 } /* STRDUP */
70 
71 
72 
73 
74 char* KKB::STRCAT (char* dest,
75  kkint32 destSize,
76  const char* src
77  )
78 {
79 # ifdef USE_SECURE_FUNCS
80  strcat_s (dest, destSize, src);
81 # else
82  strcat (dest, src);
83 # endif
84 
85  return dest;
86 } /* STRCAT */
87 
88 
89 
90 
91 
92 kkint32 KKB::STRICMP (const char* left,
93  const char* right
94  )
95 {
96  if (left == NULL)
97  {
98  if (right == NULL)
99  return 0;
100  else
101  return -1;
102  }
103  else if (!right)
104  return 1;
105 
106  kkint32 zed = (toupper (*left)) - (toupper (*right));
107 
108  while ((zed == 0) && (*left != 0))
109  {
110  left++; right++;
111  zed = (toupper (*left)) - (toupper (*right));
112  }
113 
114  if (zed < 0)
115  return -1;
116  else if (zed == 0)
117  return 0;
118  else
119  return 1;
120 
121 } /* STRICMP */
122 
123 
124 
125 
126 kkint32 KKB::STRNICMP (const char* left,
127  const char* right,
128  kkint32 len
129  )
130 {
131  if (left == NULL)
132  {
133  if (right == NULL)
134  return 0;
135  else
136  return -1;
137  }
138  else if (!right)
139  return 1;
140 
141  if (len < 1)
142  return 0;
143 
144  kkint32 x = 0;
145  kkint32 zed = (toupper (*left)) - (toupper (*right));
146  while ((zed == 0) && (*left != 0) && (x < len))
147  {
148  ++left; ++right; ++x;
149  zed = (toupper (*left)) - (toupper (*right));
150  }
151 
152  if (zed < 0)
153  return -1;
154  else if (zed == 0)
155  return 0;
156  else
157  return 1;
158 } /* STRNICMP */
159 
160 
161 
162 kkint32 KKB::SPRINTF (char* buff,
163  kkint32 buffSize,
164  const char* formatSpec,
165  kkint16 right
166  )
167 {
168 # ifdef USE_SECURE_FUNCS
169  return sprintf_s (buff, buffSize, formatSpec, right);
170 # else
171  return sprintf (buff, formatSpec, right);
172 # endif
173 }
174 
175 
176 
177 kkint32 KKB::SPRINTF (char* buff,
178  kkint32 buffSize,
179  const char* formatSpec,
180  kkuint16 right
181  )
182 {
183 # ifdef USE_SECURE_FUNCS
184  return sprintf_s (buff, buffSize, formatSpec, right);
185 # else
186  return sprintf (buff, formatSpec, right);
187 #endif
188 }
189 
190 
191 
192 
193 kkint32 KKB::SPRINTF (char* buff,
194  kkint32 buffSize,
195  const char* formatSpec,
196  kkint32 right
197  )
198 {
199 # ifdef USE_SECURE_FUNCS
200  return sprintf_s (buff, buffSize, formatSpec, right);
201 # else
202  return sprintf (buff, formatSpec, right);
203 # endif
204 }
205 
206 
207 
208 kkint32 KKB::SPRINTF (char* buff,
209  kkint32 buffSize,
210  const char* formatSpec,
211  kkuint32 right
212  )
213 {
214 # ifdef USE_SECURE_FUNCS
215  return sprintf_s (buff, buffSize, formatSpec, right);
216 # else
217  return sprintf (buff, formatSpec, right);
218 #endif
219 }
220 
221 
222 
223 kkint32 KKB::SPRINTF (char* buff,
224  kkint32 buffSize,
225  const char* formatSpec,
226  kkint64 right
227  )
228 {
229 
230 # ifdef USE_SECURE_FUNCS
231  return sprintf_s (buff, buffSize, formatSpec, right);
232 # else
233  return sprintf (buff, formatSpec, right);
234 # endif
235 }
236 
237 
238 
239 kkint32 KKB::SPRINTF (char* buff,
240  kkint32 buffSize,
241  const char* formatSpec,
242  kkuint64 right
243  )
244 {
245 
246 # ifdef USE_SECURE_FUNCS
247  return sprintf_s (buff, buffSize, formatSpec, right);
248 # else
249  return sprintf (buff, formatSpec, right);
250 # endif
251 }
252 
253 
254 
255 kkint32 KKB::SPRINTF (char* buff,
256  kkint32 buffSize,
257  const char* formatSpec,
258  kkint32 precision,
259  double d
260  )
261 {
262 #ifdef USE_SECURE_FUNCS
263  return sprintf_s (buff, buffSize, formatSpec, precision, d);
264 #else
265  return sprintf (buff, formatSpec, precision, d);
266 #endif
267 }
268 
269 
270 
271 kkint32 KKB::SPRINTF (char* buff,
272  kkint32 buffSize,
273  char const* formatSpec,
274  double d
275  )
276 {
277  #ifdef USE_SECURE_FUNCS
278  return sprintf_s (buff, buffSize, formatSpec, d);
279  #else
280  return sprintf (buff, formatSpec, d);
281  #endif
282 }
283 
284 
285 
286 const char* KKStr::Str (const char* s)
287 {
288  if (!s)
289  return "";
290  else
291  return s;
292 }
293 
294 
295 
296 void KKStr::StrDelete (char** str)
297 {
298  if (*str)
299  {
300  delete [] *str;
301  *str = NULL;
302  }
303 }
304 
305 
306 
307 
308 const char* KKStr::StrChr (const char* str,
309  int ch
310  )
311 {
312  return strchr (str, ch);
313 }
314 
315 
316 
317 
319  const char* s2
320  )
321 {
322  if (s1 == NULL)
323  {
324  if (s2 == NULL)
325  return 0;
326  else
327  return -1;
328  }
329  else if (s2 == NULL)
330  return 1;
331 
332 
333  while ((*s1) && (*s2) && (toupper (*s1) == toupper (*s2)))
334  {
335  s1++;
336  s2++;
337  }
338 
339  if (*s1 == 0)
340  {
341  if (*s2 == 0)
342  {
343  return 0;
344  }
345  else
346  {
347  // s1 < s2
348  return -1;
349  }
350  }
351  else
352  {
353  if (*s2 == 0)
354  {
355  return 1;
356  }
357  else
358  {
359  if (*s1 < *s2)
360  return -1;
361  else
362  return 1;
363  }
364  }
365 
366 
367  //return _stricmp (s1, s2);
368 } /* StrCompareIgnoreCase */
369 
370 
371 
372 
373 bool KKStr::StrEqual (const char* s1,
374  const char* s2
375  )
376 {
377  if ((!s1) && (!s2))
378  return true;
379 
380  if ((!s1) || (!s2))
381  return false;
382 
383  return (strcmp (s1, s2) == 0);
384 }
385 
386 
387 
388 bool KKStr::StrEqualN (const char* s1,
389  const char* s2,
390  kkuint32 len
391  )
392 {
393  if ((!s1) && (!s2))
394  return true;
395 
396  if ((!s1) || (!s2))
397  return false;
398 
399  for (kkuint32 x = 0; x < len; ++x)
400  if (s1[x] != s2[x])
401  return false;
402 
403  return true;
404 }
405 
406 
407 
408 bool KKStr::StrEqualNoCase (const char* s1,
409  const char* s2
410  )
411 {
412  if ((!s1) && (!s2))
413  return true;
414 
415  if ((!s1) || (!s2))
416  return false;
417 
418  size_t l1 = strlen (s1);
419  size_t l2 = strlen (s2);
420 
421  if (l1 != l2)
422  return false;
423 
424 
425  for (size_t i = 0; i < l1; i++)
426  {
427  if (toupper (s1[i]) != toupper (s2[i]))
428  return false;
429  }
430 
431  return true;
432 } /* StrEqualNoCase */
433 
434 
435 
436 bool KKStr::StrEqualNoCaseN (const char* s1,
437  const char* s2,
438  kkuint32 len
439  )
440 {
441  if ((!s1) && (!s2))
442  return true;
443 
444  if ((!s1) || (!s2))
445  return false;
446 
447  for (kkuint32 x = 0; x < len; ++x)
448  if (toupper (s1[x]) != toupper (s2[x]))
449  return false;
450 
451  return true;
452 }
453 
454 
455 
456 void KKStr::StrReplace (char** dest,
457  const char* src
458  )
459 {
460  if (*dest)
461  delete [] *dest;
462 
463  kkint32 spaceNeeded;
464 
465  if (src)
466  {
467  spaceNeeded = (kkint32)strlen (src) + 1;
468  *dest = new char[spaceNeeded];
469 
470  if (*dest == NULL)
471  {
472  KKStr errMsg = "KKStr::StrReplace ***ERROR*** Failed to allocate SpaceNeeded[" + StrFormatInt (spaceNeeded, "#####0") + "].";
473  cerr << errMsg << std::endl << std::endl;
474  throw errMsg;
475  }
476 
477  STRCOPY (*dest, spaceNeeded, src);
478  }
479  else
480  {
481  *dest = new char[1];
482 
483  if (*dest == NULL)
484  {
485  KKStr errMsg = "StrReplace ***ERROR*** Failed to allocate Empty KKStr.";
486  cerr << std::endl << errMsg << std::endl;
487  throw errMsg;
488  }
489 
490  (*dest)[0] = 0;
491  }
492 } /* StrReplace */
493 
494 
495 
497 {}
498 
499 
500 
502  const KKStr& s2
503  )
504 {
505  char* s1Ptr = (char*)s1.Str ();
506  char* s2Ptr = (char*)s2.Str ();
507 
508  if (s1Ptr == NULL)
509  return (s2Ptr != NULL);
510 
511  if (s2Ptr == NULL)
512  return false;
513 
514  while ((*s1Ptr != 0) && (tolower (*s1Ptr) == tolower (*s2Ptr)))
515  {
516  ++s1Ptr;
517  ++s2Ptr;
518  }
519 
520  return (*s1Ptr) < (*s2Ptr);
521 }
522 
523 
524 
525 
526 
528  val (NULL)
529 {
530  AllocateStrSpace (10);
531  val[0] = 0;
532  len = 0;
533 }
534 
535 
536 
537 KKStr::KKStr (const char* str):
538  val (NULL)
539 {
540  if (!str)
541  {
542  AllocateStrSpace (1);
543  val[0] = 0;
544  len = 0;
545  return;
546  }
547 
548  kkuint32 newLen = (kkuint32)strlen (str);
549  AllocateStrSpace (newLen + 1);
550 
551  STRCOPY (val, (kkuint16)allocatedSize, str);
552 
553  len = (kkuint16)newLen;
554 }
555 
556 
557 
558 /**
559  *@brief Copy Constructor.
560  */
561 KKStr::KKStr (const KKStr& str):
562  val (NULL)
563 {
564  if (!str.val)
565  {
566  AllocateStrSpace (1);
567  len = 0;
568  return;
569  }
570 
571  if (str.val[str.len] != 0)
572  {
573  std::cerr << std::endl
574  << "KKStr::KKStr ***ERROR*** Missing terminating NULL" << std::endl
575  << std::endl;
576  }
577 
578  kkuint16 neededSpace = str.len + 1;
579  if (neededSpace > str.allocatedSize)
580  {
581  KKStr errMsg = "KKStr::KKStr (const KKStr& str) AllocatedSize[" + ::StrFromUint16(str.allocatedSize) + "] on Source KKStr is to Short";
582  std::cerr << endl << errMsg << " ***ERROR***" << std::endl << std::endl;
583  throw new KKException (errMsg);
584  }
585 
586  AllocateStrSpace (str.allocatedSize);
587  if (!val) {
588  std::cerr << std::endl << "KKStr::KKStr ***ERROR*** Allocation Failed." << std::endl << std::endl;
589  throw KKException("KKStr::KKStr ***ERROR*** Allocation Failed.");
590  }
591 
592  std::memcpy (val, str.val, str.len);
593  len = str.len;
594 }
595 
596 
597 
598 
599  KKStr::KKStr (KKStr&& str):
600  allocatedSize (str.allocatedSize),
601  len (str.len),
602  val (str.val)
603 {
604  str.allocatedSize = 0;
605  str.len = 0;
606  str.val = NULL;
607 }
608 
609 
610 
611 
612 
613 
614 /**
615  *@brief Creates a String that is populated with 'd' as displayable characters and precision of 'precision'.
616  */
617 KKStr::KKStr (double d,
618  kkint32 precision
619  ):
620  val (NULL)
621 {
622  char buff[60];
623 
624  if ((precision < 0) || (precision > 10))
625  {
626  SPRINTF (buff, sizeof (buff), "%f", d);
627  }
628  else
629  {
630  SPRINTF (buff, sizeof (buff), "%.*f", precision, d);
631  }
632 
633  kkuint16 newLen = (kkuint16)strlen (buff);
634  AllocateStrSpace (newLen + 1);
635 
636  STRCOPY (val, allocatedSize, buff);
637 
638  len = newLen;
639 }
640 
641 
642 
643 //KKStr::KKStr (KKStr str):
644 // val (NULL)
645 //{
646 // StrReplace (&val, str.val);
647 //}
648 
649 
650 
651 
652 /**
653  *@brief Creates a KKStr object that has 'size' characters preallocated; and set to empty string.
654  */
656  val (NULL)
657 {
658  if (size <= 0)
659  size = 1;
660 
661  else if ((kkuint32)size >= KKStrIntMax)
662  {
663  cerr << std::endl
664  << "KKStr::KKStr ***WARNNING*** Trying to allocate Size[" << size << "] which is >= KKStrIntMax[" << KKStrIntMax << "]." << std::endl
665  << std::endl;
666  size = KKStrIntMax - 1;
667  }
668 
669  AllocateStrSpace (size);
670  val[0] = 0;
671  len = 0;
672 }
673 
674 
675 
676 
677 KKStr::KKStr (const std::string& s):
678  allocatedSize (0),
679  len (0),
680  val (NULL)
681 {
682  AllocateStrSpace ((kkint32)(s.size () + 1));
683 
684  len = (kkuint16)s.size ();
685  for (kkint32 x = 0; x < len; ++x)
686  val[x] = s[x];
687  val[len] = 0;
688 }
689 
690 
691 
692 /** @brief Constructs a KKStr instance from a sub-string of 'src'. */
693 KKStr::KKStr (const char* src,
694  kkuint32 startPos,
695  kkuint32 endPos
696  ):
697  allocatedSize (0),
698  len (0),
699  val (NULL)
700 {
701  if (startPos > endPos)
702  {
703  AllocateStrSpace (1);
704  return;
705  }
706 
707  kkuint32 subStrLen = 1 + endPos - startPos;
708  if (subStrLen > (KKStrIntMax - 1))
709  {
710  cerr << "KKStr::KKStr ***ERROR*** requested SubStr[" << startPos << ", " << endPos << "] len[" << subStrLen << "] is greater than KKStrIntMax[" << (KKStrIntMax - 1) << "]" << std::endl;
711  endPos = (startPos + KKStrIntMax - 2);
712  subStrLen = 1 + endPos - startPos;
713  }
714 
715  AllocateStrSpace (1 + subStrLen); // Need one extra byte for NULL terminating character.
716  if (!val)
717  throw KKException ("KKStr::KKStr Allocation Failed");
718 
719  memcpy (val, src + startPos, subStrLen);
720  len = (kkuint16)subStrLen;
721  val[subStrLen] = 0;
722 }
723 
724 
725 
726 void KKStr::AllocateStrSpace (kkuint32 size)
727 {
728  if (size < 1)
729  size = 1;
730 
731  if (val)
732  {
733  cerr << std::endl
734  << "KKStr::AllocateStrSpace ***ERROR*** Previous val was not deleted."
735  << std::endl;
736  }
737 
738  if (size >= KKStrIntMax)
739  {
740  // Can not allocate this much space; This string has gotten out of control.
741  cerr << "KKStr::AllocateStrSpace ***ERROR*** Size[" << size << "] is larger than KKStrIntMax[" << KKStrIntMax << "]" << std::endl;
742  KKStr errStr (150);
743  errStr << "KKStr::AllocateStrSpace ***ERROR*** Size[" << size << "] is larger than KKStrIntMax[" << KKStrIntMax << "]";
744  throw KKException (errStr);
745  }
746 
747  val = new char[size];
748  if (val == NULL)
749  {
750  cerr << std::endl;
751  cerr << "KKStr::AllocateStrSpace ***ERROR***" << std::endl;
752  cerr << "Could not allocate Memory for KKStr, size[" << size << "]." << std::endl;
753  throw "KKStr::AllocateStrSpace Allocation of memory failed.";
754  }
755 
756  memset (val, 0, size);
757 
758  val[0] = 0;
759  allocatedSize = (kkuint16)size;
760  len = 0;
761 } /* AllocateStrSpace */
762 
763 
764 
765 
767 {
768  return sizeof (char*) + 2 * sizeof (kkuint16) + allocatedSize;
769 }
770 
771 
772 
773 void KKStr::GrowAllocatedStrSpace (kkuint32 newAllocatedSize)
774 {
775  if (newAllocatedSize < allocatedSize)
776  {
777  KKStr errMsg (128);
778  errMsg << "KKStr::GrowAllocatedStrSpace ***ERROR*** newAllocatedSize[" << newAllocatedSize << "] is smaller than allocatedSize[" << allocatedSize << "]";
779  cerr << std::endl << std::endl << errMsg << std::endl << std::endl;
780  throw KKException (errMsg);
781  }
782 
783  if (newAllocatedSize >= (KKStrIntMax - 5))
784  {
785  // Can not allocate this much space; This string has gotten out of control.
786  KKStr errMsg (128);
787  errMsg << "KKStr::GrowAllocatedStrSpace ***ERROR*** NewAllocatedSize[" << newAllocatedSize << "] is larger than KKStrIntMax[" << (KKStrIntMax - 5) << "]";
788  throw KKException (errMsg);
789  }
790 
791  newAllocatedSize += 5; // Lets allocate a little extra space on the hope that we will save a lot of cycles reallocating again this string.
792  {
793  // Will check to see if reasonable to grow by 25% over current len.
794  kkuint32 newAllocatedWithExtraRoomForGrowth = Min ((kkuint32)(len + (len / 4)), (KKStrIntMax - 1));
795  if ((newAllocatedWithExtraRoomForGrowth > newAllocatedSize) && (newAllocatedSize < KKStrIntMax))
796  newAllocatedSize = newAllocatedWithExtraRoomForGrowth;
797  }
798 
799  if (val == NULL)
800  {
801  val = new char[newAllocatedSize];
802  if (val == NULL)
803  {
804  KKStr errMsg(128);
805  errMsg << "KKStr::GrowAllocatedStrSpace ***ERROR*** Allocation of NewAllocatedSize[" << newAllocatedSize << "] characters failed.";
806  cerr << endl << errMsg << endl <<endl;
807  throw KKException(errMsg);
808  }
809  memset (val, 0, newAllocatedSize);
810  allocatedSize = (kkuint16)newAllocatedSize;
811  }
812  else
813  {
814  char* newVal = new char[newAllocatedSize];
815  if (newVal == NULL)
816  {
817  KKStr errMsg(128);
818  errMsg << "KKStr::GrowAllocatedStrSpace ***ERROR*** Allocation of NewAllocatedSize[" << newAllocatedSize << "] characters failed.";
819  cerr << endl << errMsg << endl << endl;
820  throw KKException(errMsg);
821  }
822 
823  memset (newVal, 0, newAllocatedSize);
824  memcpy (newVal, val, allocatedSize);
825  delete[] val;
826  val = newVal;
827  allocatedSize = (kkuint16)newAllocatedSize;
828  }
829 } /* GrowAllocatedStrSpace */
830 
831 
832 
834 {
835  if (val)
836  {
837  delete [] val;
838  val = NULL;
839  }
840 }
841 
842 
843 
844 kkint32 KKStr::Compare (const KKStr& s2) const
845 {
846  kkint32 zed = Min (len, s2.len);
847 
848  const char* s1Ptr = val;
849  const char* s2Ptr = s2.val;
850 
851  for (kkint32 x = 0; x < zed; x++)
852  {
853  if ((*s1Ptr) < (*s2Ptr))
854  return -1;
855 
856  else if ((*s1Ptr) > (*s2Ptr))
857  return 1;
858 
859  s1Ptr++;
860  s2Ptr++;
861  }
862 
863  if (len == s2.len)
864  return 0;
865 
866  else if (len < s2.len)
867  return -1;
868 
869  else
870  return 1;
871 
872 } /* Compare */
873 
874 
875 
876 /**
877  *@brief Compares with STL string.
878  *@param[in] s2 STL String std::string that we will compare with.
879  *@return -1=less, 0=equal, 1=greater, -1, 0, or 1, indicating if less than, equal, or greater.
880  */
881 kkint32 KKStr::Compare (const std::string& s2) const
882 {
883  kkuint16 s2Len = (kkuint16)s2.size ();
884  kkint32 zed = Min (len, s2Len);
885 
886  const char* s1Ptr = val;
887  const char* s2Ptr = s2.c_str ();
888 
889  for (kkint32 x = 0; x < zed; x++)
890  {
891  if ((*s1Ptr) < (*s2Ptr))
892  return -1;
893 
894  else if ((*s1Ptr) > (*s2Ptr))
895  return 1;
896 
897  s1Ptr++;
898  s2Ptr++;
899  }
900 
901  if (len == s2Len)
902  return 0;
903 
904  else if (len < s2Len)
905  return -1;
906 
907  else
908  return 1;
909 
910 } /* Compare */
911 
912 
913 
914 /**
915  *@brief Compares with another KKStr, ignoring case.
916  *@param[in] s2 Other String to compare with.
917  *@return -1=less, 0=equal, 1=greater, -1, 0, or 1, indicating if less than, equal, or greater.
918  */
920 {
921  kkint32 zed = Min (len, s2.len);
922 
923  const char* s1Ptr = val;
924  const char* s2Ptr = s2.val;
925 
926  for (kkint32 x = 0; x < zed; x++)
927  {
928  if (toupper (*s1Ptr) < toupper (*s2Ptr))
929  return -1;
930 
931  else if (toupper (*s1Ptr) > toupper (*s2Ptr))
932  return 1;
933 
934  s1Ptr++;
935  s2Ptr++;
936  }
937 
938  if (len == s2.len)
939  return 0;
940 
941  else if (len < s2.len)
942  return -1;
943 
944  else
945  return 1;
946 } /* CompareIgnoreCase */
947 
948 
949 
950 /**
951  *@brief Compares with ascii-z string ignoring case.
952  *@param[in] s2 Ascii-z string to compare with.
953  *@return -1=less, 0=equal, 1=greater, -1, 0, or 1, indicating if less than, equal, or greater.
954  */
955 kkint32 KKStr::CompareIgnoreCase (const char* s2) const
956 {
957  if (s2 == NULL)
958  {
959  if (len == 0)
960  return 0;
961  else
962  return 1;
963  }
964 
965  kkuint32 s2Len = 0;
966  if (s2 != NULL)
967  s2Len = (kkuint32)strlen (s2);
968  kkuint32 zed = Min ((kkuint32)len, s2Len);
969 
970  const char* s1Ptr = val;
971  const char* s2Ptr = s2;
972 
973  for (kkuint16 x = 0; x < zed; x++)
974  {
975  if (toupper (*s1Ptr) < toupper (*s2Ptr))
976  return -1;
977 
978  else if (toupper (*s1Ptr) > toupper (*s2Ptr))
979  return 1;
980 
981  s1Ptr++;
982  s2Ptr++;
983  }
984 
985  if (len == s2Len)
986  return 0;
987 
988  else if (len < s2Len)
989  return -1;
990 
991  else
992  return 1;
993 } /* CompareIgnoreCase */
994 
995 
996 
997 
998 kkint32 KKStr::CompareIgnoreCase (const std::string& s2) const
999 {
1000  kkuint16 s2Len = (kkuint16)s2.size ();
1001  kkint32 zed = Min (len, s2Len);
1002 
1003  const char* s1Ptr = val;
1004  const char* s2Ptr = s2.c_str ();
1005 
1006  for (kkint32 x = 0; x < zed; x++)
1007  {
1008  if (toupper (*s1Ptr) < toupper (*s2Ptr))
1009  return -1;
1010 
1011  else if (toupper (*s1Ptr) > toupper (*s2Ptr))
1012  return 1;
1013 
1014  s1Ptr++;
1015  s2Ptr++;
1016  }
1017 
1018  if (len == s2Len)
1019  return 0;
1020 
1021  else if (len < s2Len)
1022  return -1;
1023 
1024  else
1025  return 1;
1026 
1027 } /* CompareIgnoreCase */
1028 
1029 
1030 
1031 KKStr KKStr::Concat(const char** values)
1032 {
1033  if (values == NULL)
1034  return "";
1035 
1036  kkuint32 len = 0;
1037  kkint32 x = 0;
1038  while (values[x] != NULL)
1039  {
1040  len += (kkuint32)strlen (values[x]);
1041  x++;
1042  }
1043 
1044  KKStr result (len);
1045  x = 0;
1046  while (values[x] != NULL)
1047  {
1048  result.Append (values[x]);
1049  x++;
1050  }
1051 
1052  return result;
1053 } /* Concat */
1054 
1055 
1056 
1057 KKStr KKStr::Concat (const VectorKKStr& values)
1058 {
1059  kkuint32 x = 0;
1060  kkint32 len = 0;
1061 
1062  for (x = 0; x < values.size (); x++)
1063  len += (kkint32)values.size ();
1064 
1065  KKStr result (len);
1066  x = 0;
1067  for (x = 0; x < values.size (); x++)
1068  {
1069  result.Append (values[x]);
1070  x++;
1071  }
1072 
1073  return result;
1074 } /* Concat */
1075 
1076 
1077 
1078 /**
1079  *@brief Concatenates the list of 'std::string' strings.
1080  *@details Iterates through values Concatenating each one onto a result string.
1081  */
1082 KKStr KKStr::Concat (const std::vector<std::string>& values)
1083 {
1084  kkuint32 x = 0;
1085  kkint32 len = 0;
1086 
1087  for (x = 0; x < values.size (); x++)
1088  len += (kkint32)values.size ();
1089 
1090  KKStr result (len);
1091  x = 0;
1092  for (x = 0; x < values.size (); x++)
1093  {
1094  result.Append (values[x]);
1095  x++;
1096  }
1097 
1098  return result;
1099 } /* Concat */
1100 
1101 
1102 
1103 bool KKStr::Contains (const KKStr& value)
1104 {
1105  if (value.Empty ())
1106  return true;
1107  else
1108  return StrInStr (value);
1109 }
1110 
1111 
1112 bool KKStr::Contains (const char* value)
1113 {
1114  if ((value == NULL) || (*value == 0))
1115  return true;
1116  else
1117  return (Find (value, 0) >= 0);
1118 }
1119 
1120 
1121 
1123 {
1124  if (!val)
1125  return 0;
1126  kkint32 count = 0;
1127  for (kkint32 x = 0; x < len; ++x)
1128  {
1129  if (val[x] == ch)
1130  ++count;
1131  }
1132  return count;
1133 }
1134 
1135 
1136 
1137 bool KKStr::StartsWith (const KKStr& value) const
1138 {
1139  return StartsWith (value, false);
1140 }
1141 
1142 
1143 
1144 bool KKStr::StartsWith (const char* value) const
1145 {
1146  return StartsWith (value, false);
1147 }
1148 
1149 
1150 bool KKStr::StartsWith (const KKStr& value,
1151  bool ignoreCase
1152  ) const
1153 {
1154  if (value.len == 0)
1155  return true;
1156 
1157  if (value.len > len)
1158  return false;
1159 
1160  if (ignoreCase)
1161  return StrEqualNoCaseN (val, value.val, value.len);
1162  else
1163  return StrEqualN (val, value.val, value.len);
1164 }
1165 
1166 
1167 
1168 
1169 bool KKStr::StartsWith (const char* value,
1170  bool ignoreCase
1171  ) const
1172 {
1173  if (value == NULL)
1174  return true;
1175 
1176  kkint32 valueLen = (kkint32)strlen (value);
1177 
1178  if (ignoreCase)
1179  return StrEqualNoCaseN (val, value, valueLen);
1180  else
1181  return StrEqualN (val, value, valueLen);
1182 }
1183 
1184 
1185 
1186 
1187 
1188 
1189 
1190 bool KKStr::EndsWith (const KKStr& value)
1191 {
1192  return EndsWith (value, false);
1193 }
1194 
1195 
1196 
1197 bool KKStr::EndsWith (const char* value)
1198 {
1199  return EndsWith (value, false);
1200 }
1201 
1202 
1203 
1204 bool KKStr::EndsWith (const KKStr& value,
1205  bool ignoreCase
1206  )
1207 {
1208  if (value.len == 0)
1209  return true;
1210 
1211  kkint32 startPos = 1 + len - value.Len ();
1212  if (startPos < 0)
1213  return false;
1214 
1215  if (ignoreCase)
1216  return StrEqualNoCase (val + startPos, value.val);
1217  else
1218  return StrEqual (val + startPos, value.val);
1219 }
1220 
1221 
1222 
1223 bool KKStr::EndsWith (const char* value,
1224  bool ignoreCase
1225  )
1226 {
1227  if (value == NULL)
1228  return true;
1229 
1230  kkint32 valueLen = (kkint32)strlen (value);
1231 
1232  kkint32 startPos = 1 + len - valueLen;
1233  if (startPos < 0)
1234  return false;
1235 
1236  if (ignoreCase)
1237  return StrEqualNoCase (val + startPos, value);
1238  else
1239  return StrEqual (val + startPos, value);
1240 }
1241 
1242 
1243 
1244 bool KKStr::EqualIgnoreCase (const KKStrConstPtr s2) const
1245 {
1246  return EqualIgnoreCase (s2->Str ());
1247 }
1248 
1249 
1250 bool KKStr::EqualIgnoreCase (const KKStr& s2) const
1251 {
1252  return (CompareIgnoreCase (s2) == 0);
1253 } /* EqualIgnoreCase */
1254 
1255 
1256 
1257 bool KKStr::EqualIgnoreCase (const char* s2) const
1258 {
1259  return (StrCompareIgnoreCase (val, s2) == 0);
1260 } /* EqualIgnoreCase */
1261 
1262 
1263 
1264 wchar_t* KKStr::StrWide () const
1265 {
1266  wchar_t* w = NULL;
1267 
1268  if (!val)
1269  {
1270  w = new wchar_t[1];
1271  w[0] = 0;
1272  return w;
1273  }
1274 
1275  kkint32 x;
1276  w = new wchar_t[len + 1];
1277  for (x = 0; x < len; x++)
1278  w[x] = (wchar_t) val[x];
1279  return w;
1280 } /* StrWide */
1281 
1282 
1283 
1284 
1285 void KKStr::ValidateLen () const
1286 {
1287  if (!val)
1288  {
1289  if (len < 1)
1290  {
1291  return;
1292  }
1293  else
1294  {
1295  cerr << std::endl
1296  << std::endl
1297  << std::endl
1298  << " *** ERROR ***" << std::endl
1299  << std::endl
1300  << "'KKStr::ValidateLen' Something has gone very Wrong with the KKStr Library." << std::endl
1301  << std::endl
1302  << "len[" << len << "]" << std::endl
1303  << "strlen (val)[" << strlen (val) << "]" << std::endl
1304  << std::endl
1305  << std::endl
1306  << "Press Enter to Continue." << std::endl;
1307 
1308  char buff[100];
1309  cin >> buff;
1310  }
1311  }
1312 
1313  if (val[len] != 0)
1314  {
1315  cerr << std::endl
1316  << std::endl
1317  << "'KKStr::ValidateLen' Something has gone very Wrong with the KKStr Library." << std::endl
1318  << std::endl
1319  << "len[" << len << "]" << std::endl
1320  << "strlen (val)[" << strlen (val) << "]" << std::endl
1321  << std::endl
1322  << std::endl
1323  << "Press Enter to Continue." << std::endl;
1324  }
1325 }
1326 
1327 /*
1328 KKStr& KKStr::operator= (const KKStrConstPtr src)
1329 {
1330  if (src == this)
1331  {
1332  // We are assigning our selves to our selves; there is nothing to do.
1333  return *this;
1334  }
1335 
1336  if (src == NULL)
1337  {
1338  len = 0;
1339  if ((val != NULL) && (allocatedSize > 0))
1340  val[0] = 0;
1341  }
1342  else
1343  {
1344  kkuint16 spaceNeeded = src->len + 1;
1345  if ((spaceNeeded > allocatedSize) || (!val))
1346  {
1347  delete val;
1348  val = NULL;
1349  allocatedSize = 0;
1350  AllocateStrSpace (spaceNeeded);
1351  }
1352  else
1353  {
1354  memset (val, 0, allocatedSize);
1355  }
1356 
1357  if (src->val)
1358  memcpy (val, src->val, src->len);
1359 
1360  len = src->len;
1361  val[len] = 0;
1362  }
1363  return *this;
1364 }
1365 */
1366 
1367 
1368 
1370 {
1371  #ifdef KKDEBUG
1372  ValidateLen ();
1373  src.ValidateLen ();
1374  #endif
1375 
1376  delete val;
1377  val = src.val;
1378  allocatedSize = src.allocatedSize;
1379  len = src.len;
1380  src.val = NULL;
1381  src.allocatedSize = 0;
1382  src.len = 0;
1383 
1384  return *this;
1385 }
1386 
1387 
1388 
1389 
1390 KKStr& KKStr::operator= (const KKStr& src)
1391 {
1392  #ifdef KKDEBUG
1393  ValidateLen ();
1394  src.ValidateLen ();
1395  #endif
1396 
1397  if (&src == this)
1398  {
1399  // We are assigning our selves to our selves; there is nothing to do.
1400  return *this;
1401  }
1402 
1403  kkuint16 spaceNeeded = src.len + 1;
1404  if ((spaceNeeded > allocatedSize) || (!val))
1405  {
1406  delete val;
1407  val = NULL;
1408  allocatedSize = 0;
1409  AllocateStrSpace (spaceNeeded);
1410  if (!val)
1411  throw KKException ("KKStr::operator=");
1412  }
1413  else
1414  {
1415  memset (val, 0, allocatedSize);
1416  }
1417 
1418  if (src.val)
1419  memcpy (val, src.val, src.len);
1420 
1421  len = src.len;
1422  val[len] = 0;
1423 
1424  return *this;
1425 }
1426 
1427 
1428 
1429 
1430 
1431 
1432 //KKStr& KKStr::operator= (KKStr src)
1433 //{
1434 // StrReplace (&val, src.val);
1435 // return *this;
1436 //}
1437 
1438 
1439 
1440 
1441 
1442 KKStr& KKStr::operator= (const char* src)
1443 {
1444  #ifdef KKDEBUG
1445  ValidateLen ();
1446  #endif
1447 
1448  if (!src)
1449  {
1450  delete val;
1451  val = NULL;
1452  allocatedSize = 0;
1453  AllocateStrSpace (10);
1454  len = 0;
1455  return *this;
1456  }
1457 
1458  kkuint16 newLen = (kkuint16)strlen (src);
1459  kkuint16 spaceNeeded = newLen + 1;
1460 
1461  if (spaceNeeded > allocatedSize)
1462  {
1463  delete val;
1464  val = NULL;
1465  allocatedSize = 0;
1466  AllocateStrSpace (spaceNeeded);
1467  }
1468 
1469  STRCOPY (val, allocatedSize, src);
1470  len = newLen;
1471 
1472  return *this;
1473 }
1474 
1475 
1476 
1477 
1479 {
1480  #ifdef KKDEBUG
1481  ValidateLen ();
1482  #endif
1483 
1484  char buff[60];
1485  SPRINTF (buff, sizeof (buff), "%d", right);
1486 
1487  kkuint16 newLen = (kkuint16)strlen (buff);
1488 
1489  kkuint16 spaceNeeded = newLen + 1;
1490 
1491  if (spaceNeeded > allocatedSize)
1492  {
1493  delete val;
1494  val = NULL;
1495  allocatedSize = 0;
1496  AllocateStrSpace (spaceNeeded);
1497  }
1498 
1499  memset (val, 0, allocatedSize);
1500 
1501  STRCOPY (val, allocatedSize, buff);
1502  len = newLen;
1503 
1504  return *this;
1505 }
1506 
1507 
1508 
1509 KKStr& KKStr::operator= (const std::vector<KKStr>& right)
1510 {
1511  kkint32 spaceNeeded = 2; /* Start with 2 bytes for overhead. */
1512  kkuint32 x = 0;
1513  for (x = 0; x < right.size (); x++)
1514  spaceNeeded += right[x].Len ();
1515 
1516  if (spaceNeeded > allocatedSize)
1517  {
1518  delete val;
1519  val = NULL;
1520  allocatedSize = 0;
1521  AllocateStrSpace (spaceNeeded);
1522  }
1523 
1524  if (!val)
1525  {
1526  KKStr errMsg = "KKStr::operator= (const std::vector<KKStr>& right) ***ERROR*** Space for string not allocatd!";
1527  cerr << endl << errMsg << endl <<endl;
1528  throw KKException (errMsg);
1529  }
1530 
1531  char* ptr = val;
1532  kkint32 allocatedSpaceNotUsed = allocatedSize - 1;
1533  for (x = 0; x < right.size (); x++)
1534  {
1535  kkint32 rightLen = right[x].Len ();
1536 #ifdef USE_SECURE_FUNCS
1537  strncpy_s (ptr, allocatedSpaceNotUsed, right[x].Str (), rightLen);
1538 #else
1539  strncpy (ptr, right[x].Str (), rightLen);
1540 #endif
1541  ptr = ptr + rightLen;
1542  allocatedSpaceNotUsed -= rightLen;
1543  *ptr = 0;
1544  }
1545  return *this;
1546 }
1547 
1548 
1549 
1550 bool KKStr::operator== (const KKStr& right) const
1551 {
1552  return (Compare (right) == 0);
1553 }
1554 
1555 
1556 
1557 
1558 bool KKStr::operator!= (const KKStr& right) const
1559 {
1560  return (Compare (right) != 0);
1561 }
1562 
1563 
1564 
1565 
1566 bool KKStr::operator== (KKStrConstPtr right) const
1567 {
1568  if (!right)
1569  return false;
1570 
1571  return (Compare (*right) == 0);
1572 }
1573 
1574 
1575 
1576 
1577 bool KKStr::operator!= (KKStrConstPtr right) const
1578 {
1579  if (!right)
1580  return true;
1581 
1582  return (Compare (*right) != 0);
1583 }
1584 
1585 
1586 
1587 
1588 bool KKStr::operator== (const char* rtStr) const
1589 {
1590  return StrEqual (val, rtStr);
1591 }
1592 
1593 
1594 
1595 
1596 bool KKStr::operator!= (const char* rtStr) const
1597 {
1598  return (!StrEqual (val, rtStr));
1599 }
1600 
1601 
1602 
1603 bool KKStr::operator== (const std::string right) const
1604 {
1605  return (Compare (right) == 0);
1606 }
1607 
1608 
1609 
1610 
1611 bool KKStr::operator!= (const std::string right) const
1612 {
1613  return (Compare (right) != 0);
1614 }
1615 
1616 
1617 
1618 
1619 bool KKStr::operator> (const KKStr& right) const
1620 {
1621  return (Compare (right) > 0);
1622 }
1623 
1624 
1625 
1626 
1627 bool KKStr::operator>= (const KKStr& right) const
1628 {
1629  return (Compare (right) >= 0);
1630 }
1631 
1632 
1633 
1634 
1635 bool KKStr::operator< (const KKStr& right) const
1636 {
1637  return (Compare (right) < 0);
1638 }
1639 
1640 
1641 
1642 bool KKStr::operator<= (const KKStr& right) const
1643 {
1644  return (Compare (right) <= 0);
1645 }
1646 
1647 
1648 
1650 {
1651  #ifdef KKDEBUG
1652  ValidateLen ();
1653  #endif
1654 
1655  if (!val) return;
1656 
1657  if (len > 0)
1658  {
1659  for (int x = 0; x < len; ++x)
1660  val[x] = val[x + 1];
1661  len--;
1662  val[len] = 0;
1663  }
1664 } /* ChopLastChar */
1665 
1666 
1667 
1669 {
1670  #ifdef KKDEBUG
1671  ValidateLen ();
1672  #endif
1673 
1674  if (!val) return;
1675 
1676  if (len > 0)
1677  {
1678  len--;
1679  val[len] = 0;
1680  }
1681 } /* ChopLastChar */
1682 
1683 
1684 
1685 
1686 KKStr& KKStr::Trim (const char* whiteSpaceChars)
1687 {
1688  TrimRight (whiteSpaceChars);
1689  TrimLeft(whiteSpaceChars);
1690  return *this;
1691 } /* Trim */
1692 
1693 
1694 
1695 KKStr& KKStr::TrimRight (const char* whiteSpaceChars)
1696 {
1697  #ifdef KKDEBUG
1698  ValidateLen ();
1699  #endif
1700 
1701  if (!val)
1702  {
1703  AllocateStrSpace (1);
1704  len = 0;
1705  return *this;
1706  }
1707 
1708  kkint32 x = len - 1;
1709  while ((len > 0) && (strchr (whiteSpaceChars, val[x])))
1710  {
1711  val[x] = 0;
1712  x--;
1713  len--;
1714  }
1715 
1716  return *this;
1717 } /* TrimRight */
1718 
1719 
1720 
1721 
1722 
1724 {
1725  #ifdef KKDEBUG
1726  ValidateLen ();
1727  #endif
1728 
1729  if (!val)
1730  {
1731  AllocateStrSpace (1);
1732  len = 0;
1733  return;
1734  }
1735 
1736  if (len > 0)
1737  {
1738  len--;
1739  val[len] = 0;
1740  }
1741 } /* TrimRightChar */
1742 
1743 
1744 
1745 void KKStr::TrimLeft (const char* whiteSpaceChars)
1746 {
1747  #ifdef KKDEBUG
1748  ValidateLen ();
1749  #endif
1750 
1751 
1752  if (!val)
1753  {
1754  AllocateStrSpace (1);
1755  len = 0;
1756  return;
1757  }
1758 
1759  kkuint16 x = 0;
1760 
1761  while ((strchr (whiteSpaceChars, val[x])) && (val[x] != 0))
1762  x++;
1763 
1764  if (x == 0)
1765  return;
1766 
1767  kkuint16 y = 0;
1768 
1769  while (x < len)
1770  {
1771  val[y] = val[x];
1772  x++;
1773  y++;
1774  }
1775 
1776  len = y;
1777  val[len] = 0;
1778 } /* TrimLeft */
1779 
1780 
1781 
1782 
1783 void KKStr::Append (const char* buff)
1784 {
1785  #ifdef KKDEBUG
1786  ValidateLen ();
1787  #endif
1788 
1789  if (!buff)
1790  return;
1791 
1792  kkuint32 buffLen = (kkuint32)strlen (buff);
1793  kkuint32 newLen = len + buffLen;
1794  kkuint32 neededSpace = newLen + 1;
1795 
1796  if (neededSpace > allocatedSize)
1797  {
1798  if (neededSpace >= KKStrIntMax)
1799  {
1800  cerr << std::endl
1801  << "KKStr::Append ***ERROR*** Size of buffer can not fit into String." << std::endl
1802  << " buffLen[" << buffLen << "]" << std::endl
1803  << " neededSpace[" << neededSpace << "]" << std::endl
1804  << std::endl;
1805  throw KKException ("KKStr::Append Length will exceed what KKStr can managed; neededSpace: " + StrFromUint32 (neededSpace));
1806  }
1807  GrowAllocatedStrSpace (neededSpace);
1808  }
1809 
1810  kkuint32 x = 0;
1811  for (x = 0; x < buffLen; x++)
1812  {
1813  val[len] = buff[x];
1814  len++;
1815  }
1816  val[len] = 0;
1817 } /* Append */
1818 
1819 
1820 
1821 void KKStr::Append (const char* buff,
1822  kkuint32 buffLen
1823  )
1824 {
1825  #ifdef KKDEBUG
1826  ValidateLen ();
1827  #endif
1828 
1829  if (buffLen == 0)
1830  return;
1831 
1832  kkuint32 newLen = len + buffLen;
1833  kkuint32 neededSpace = newLen + 1;
1834 
1835  if (neededSpace > allocatedSize)
1836  {
1837  if (neededSpace >= KKStrIntMax)
1838  {
1839  cerr << std::endl
1840  << "KKStr::Append ***ERROR*** Size of buffer can not fit into String." << std::endl
1841  << " buffLen[" << buffLen << "]" << std::endl
1842  << " neededSpace[" << neededSpace << "]" << std::endl
1843  << std::endl;
1844  throw KKException("KKStr::Append Length will exceed what KKStr can managed; neededSpace: " + StrFromUint32(neededSpace));
1845  }
1846  GrowAllocatedStrSpace (neededSpace);
1847  }
1848 
1849  kkuint32 x = 0;
1850  for (x = 0; x < buffLen; x++)
1851  {
1852  val[len] = buff[x];
1853  len++;
1854  }
1855 
1856  val[len] = 0;
1857 } /* Append*/
1858 
1859 
1860 
1861 
1862 
1863 void KKStr::Append (char ch)
1864 {
1865  kkuint32 neededSpace = len + 2;
1866  if (neededSpace > allocatedSize)
1867  {
1868  if (neededSpace >= KKStrIntMax)
1869  {
1870  cerr << std::endl
1871  << "KKStr::Append ***ERROR*** Size of buffer can not fit into String." << std::endl
1872  << " neededSpace[" << neededSpace << "]" << std::endl
1873  << std::endl;
1874  throw KKException("KKStr::Append (char ch) Length will exceed what KKStr can managed; neededSpace: " + StrFromUint32(neededSpace));
1875  }
1876  GrowAllocatedStrSpace (neededSpace);
1877  }
1878  val[len] = ch;
1879  len++;
1880  val[len] = 0;
1881 } /* Append */
1882 
1883 
1884 
1885 
1886 
1887 void KKStr::Append (const KKStr& str)
1888 {
1889  Append (str.val, str.len);
1890 }
1891 
1892 
1893 
1894 void KKStr::Append (const std::string& str)
1895 {
1896  Append (str.c_str ());
1897 }
1898 
1899 
1900 
1902 {
1903  if (i == 0)
1904  {
1905  Append ('0');
1906  return;
1907  }
1908 
1909  char buff[64];
1910  kkint16 bi = sizeof (buff) - 1;
1911  buff[bi] = 0;
1912 
1913  bool negative = false;
1914  if (i < 0)
1915  {
1916  negative = true;
1917  i = 0 - i;
1918  }
1919 
1920  while (i > 0)
1921  {
1922  --bi;
1923  kkint16 digit = i % 10;
1924  i = i / 10;
1925  buff[bi] = '0' + (char)digit;
1926  }
1927 
1928  if (negative)
1929  {
1930  --bi;
1931  buff[bi] = '-';
1932  }
1933 
1934  Append (buff + bi);
1935  return;
1936 } /* AppendInt32 */
1937 
1938 
1939 
1941 {
1942  if (i == 0)
1943  {
1944  Append ('0');
1945  return;
1946  }
1947 
1948  char buff[64];
1949  kkint16 bi = sizeof (buff) - 1;
1950  buff[bi] = 0;
1951 
1952  while (i > 0)
1953  {
1954  --bi;
1955  kkint16 digit = i % 10;
1956  i = i / 10;
1957  buff[bi] = '0' + (char)digit;
1958  }
1959 
1960  Append (buff + bi);
1961  return;
1962 } /* AppendUInt32 */
1963 
1964 
1965 
1966 
1967 
1968 
1969 
1970 char KKStr::FirstChar () const
1971 {
1972  if (val == NULL)
1973  return 0;
1974 
1975  return val[0];
1976 }
1977 
1978 
1979 
1981 {
1982  kkuint32 unUsedSpace = allocatedSize - (len + 1);
1983  kkuint32 acceptableWaist = allocatedSize / 5;
1984  if (unUsedSpace > acceptableWaist)
1985  {
1986  kkuint32 neededSpace = len + 1;
1987  char* newVal = new char[neededSpace];
1988  if (newVal == NULL)
1989  {
1990  KKStr errMsg(128);
1991  errMsg << "KKStr::FreeUpUnUsedSpace ***ERROR*** Allocation of NeededSpace[" << neededSpace << "] characters failed.";
1992  cerr << endl << errMsg << endl << endl;
1993  throw KKException(errMsg);
1994  }
1995 
1996  memcpy(newVal, val, len);
1997  newVal[len] = 0;
1998  delete[] val;
1999  val = newVal;
2000  allocatedSize = (kkuint16)neededSpace;
2001  }
2002 }
2003 
2004 
2005 
2006 
2007 char KKStr::LastChar () const
2008 {
2009  if (!val)
2010  return 0;
2011 
2012  if (val[0] == 0)
2013  return 0;
2014  else
2015  return val[len - 1];
2016 } /* LastChar */
2017 
2018 
2019 
2020 
2022 {
2023  if (!val)
2024  return -1;
2025 
2026  kkint32 idx = 0;
2027 
2028  while (idx < len)
2029  {
2030  if (val[idx] == ch)
2031  return idx;
2032  idx++;
2033  }
2034 
2035  return -1;
2036 } /* LocateCharacter */
2037 
2038 
2039 
2040 
2042 {
2043  #ifdef KKDEBUG
2044  ValidateLen ();
2045  #endif
2046 
2047  if (val == NULL)
2048  return 0;
2049 
2050  kkint32 count = 0;
2051 
2052  for (kkuint16 x = 0; x < len; x++)
2053  {
2054  if (val[x] == ch)
2055  count++;
2056  }
2057 
2058  return count;
2059 } /* InstancesOfChar */
2060 
2061 
2062 
2063 kkint32 MemCompare (const char* s1,
2064  const char* s2,
2065  kkint32 s1Idx,
2066  kkint32 s2Idx,
2067  kkint32 len
2068  )
2069 {
2070  for (kkint32 x = 0; x < len; x++)
2071  {
2072  if (s1[s1Idx] < s2[s2Idx])
2073  return -1;
2074 
2075  else if (s1[s1Idx] > s2[s2Idx])
2076  return 1;
2077 
2078  s1Idx++;
2079  s2Idx++;
2080  }
2081 
2082  return 0;
2083 } /* MemCompare */
2084 
2085 
2086 
2087 /**
2088  *@brief returns the position of the 1st occurrence of the string 'searchStr'.
2089  *@details A return of -1 indicates that there is no occurrence of 'searchStr' in the string.
2090  */
2091 kkint32 KKStr::LocateStr (const KKStr& searchStr) const
2092 {
2093  if ((!val) || (!(searchStr.val)))
2094  return -1;
2095 
2096  kkint32 idx = 0;
2097 
2098  kkint32 lastIdx = len - searchStr.len;
2099 
2100  while (idx <= lastIdx)
2101  {
2102  if (MemCompare (val, searchStr.val, idx, 0, searchStr.len) == 0)
2103  return idx;
2104  idx++;
2105  }
2106 
2107  return -1;
2108 }; // LocateStr
2109 
2110 
2111 
2112 
2113 
2114 /**
2115  *@brief Returns the position of the last occurrence of the character 'ch'.
2116  *@details A return of -1 indicates that there is no occurrence of 'ch' in the string.
2117  */
2119 {
2120  #ifdef KKDEBUG
2121  ValidateLen ();
2122  #endif
2123 
2124  if (!val)
2125  return -1;
2126 
2127  bool found = false;
2128  kkint32 idx = len - 1;
2129 
2130  while ((idx >= 0) && (!found))
2131  {
2132  if (val[idx] == ch)
2133  found = true;
2134  else
2135  idx--;
2136  }
2137 
2138  if (found)
2139  return idx;
2140  else
2141  return -1;
2142 } /* LocateLastOccurrence */
2143 
2144 
2145 
2146 
2147 /**
2148  *@brief Returns the position of the last occurrence of the string 's'.
2149  *@details A return of -1 indicates that there is no occurrence of 's' in the string.
2150  */
2152 {
2153  kkint32 sLen = s.Len ();
2154 
2155  if ((!val) || (!s.val) || (sLen <= 0) || (sLen > len))
2156  return -1;
2157 
2158  bool found = false;
2159  kkint32 idx = len - sLen;
2160 
2161  char* sVal = s.val;
2162 
2163  while ((idx >= 0) && (!found))
2164  {
2165  if (strncmp (val + idx, sVal, sLen) == 0)
2166  found = true;
2167  else
2168  idx--;
2169  }
2170 
2171  if (found)
2172  return idx;
2173  else
2174  return -1;
2175 } /* LocateLastOccurrence */
2176 
2177 
2178 
2180 {
2181  if (!val)
2182  return -1;
2183 
2184  kkint32 numInstances = 0;
2185  kkint32 x = 0;
2186  while ((x < len) && (numInstances < n))
2187  {
2188  if (val[x] == ch)
2189  ++numInstances;
2190  ++x;
2191  }
2192 
2193  if (numInstances < n)
2194  return -1;
2195  else
2196  return (x - 1);
2197 }
2198 
2199 
2200 
2201 
2202 
2204  char dir
2205  ) const
2206 {
2207  #ifdef KKDEBUG
2208  ValidateLen ();
2209  #endif
2210 
2211 
2212  KKStr str (val);
2213  if ((dir == 'L') || (dir == 'l'))
2214  str.LeftPad (width, ' ');
2215 
2216  else if ((dir == 'C') || (dir == 'c'))
2217  {
2218  str.TrimRight ();
2219  str.TrimLeft ();
2220 
2221  kkint32 x = (width - str.Len ()) / 2;
2222 
2223  if (x > 0)
2224  {
2225  str = Spaces (x).Str () + str;
2226  str.RightPad (width, ' ');
2227  }
2228  }
2229 
2230  else
2231  str.RightPad (width, ' ');
2232 
2233  return str;
2234 } /* Wide */
2235 
2236 
2237 
2238 
2239 void KKStr::RightPad (kkint32 width,
2240  char ch
2241  )
2242 {
2243  #ifdef KKDEBUG
2244  ValidateLen ();
2245  #endif
2246 
2247  if (width < 0)
2248  {
2249  KKStr errMsg = "KKStr::RightPad (kkint32 width, char ch) ***ERROR*** width[" + StrFromInt32 (width) + "] invalid.";
2250  cerr << endl << errMsg << endl << endl;
2251  throw KKException(errMsg);
2252  }
2253 
2254  if ((kkuint32)width > MaxLenSupported ()) {
2255  KKStr errMsg = "KKStr::RightPad (kkint32 width, char ch) ***ERROR*** width[" + StrFromInt32 (width) + "] greater-than KKStr suppotrts.";
2256  cerr << endl << errMsg << endl << endl;
2257  throw KKException(errMsg);
2258  }
2259 
2260  if (!val)
2261  {
2262  AllocateStrSpace (width + 1);
2263  len = 0;
2264  }
2265 
2266  if (len > (kkuint16)width)
2267  {
2268  len = (kkuint16)width;
2269  for (kkint32 x = len; x < allocatedSize; x++)
2270  val[x] = 0;
2271  }
2272 
2273  else
2274  {
2275  kkuint32 neededSpace = width + 1;
2276 
2277  if (neededSpace > allocatedSize)
2278  {
2279  if (neededSpace >= KKStrIntMax)
2280  {
2281  cerr << std::endl
2282  << "KKStr::RightPad ***ERROR*** Size of buffer can not fit into String." << std::endl
2283  << " neededSpace[" << neededSpace << "]" << std::endl
2284  << std::endl;
2285  return;
2286  }
2287  GrowAllocatedStrSpace (neededSpace);
2288  }
2289 
2290  while (len < (kkuint16)width)
2291  {
2292  val[len] = ch;
2293  len++;
2294  }
2295 
2296  val[len] = 0;
2297  }
2298 } /* RightPad */
2299 
2300 
2301 
2302 
2303 void KKStr::LeftPad (kkint32 width,
2304  uchar ch
2305  )
2306 {
2307  #ifdef KKDEBUG
2308  ValidateLen ();
2309  #endif
2310 
2311  if (width < 0)
2312  {
2313  cerr << std::endl;
2314  cerr << "KKStr::LeftPad (kkint32 width, char ch) **** ERROR ****" << std::endl;
2315  cerr << " width[" << width << "] invalid." << std::endl;
2316  cerr << std::endl;
2317  width = 0;
2318  }
2319 
2320  kkuint32 neededSpace = (kkuint32)width + 1;
2321  if (neededSpace >= KKStrIntMax)
2322  {
2323  KKStr errMsg(128);
2324  errMsg << "KKStr::LeftPad ***ERROR*** Size of buffer can not fit into String; neededSpace[" << neededSpace << "].";
2325  cerr << std::endl << errMsg << endl << endl;
2326  throw KKException(errMsg);
2327  }
2328 
2329  if (!val)
2330  {
2331  len = 0;
2332  allocatedSize = 0;
2333  }
2334 
2335  if (neededSpace > allocatedSize)
2336  {
2337  GrowAllocatedStrSpace(neededSpace);
2338  }
2339 
2340  if (val == NULL)
2341  {
2342  KKStr errMsg(128);
2343  errMsg << "KKStr::LeftPad ***ERROR*** val == NULL; couuld not allocate neededSpace[" << neededSpace << "].";
2344  cerr << std::endl << errMsg << endl << endl;
2345  throw KKException(errMsg);
2346  }
2347 
2348 
2349  if (len >= (kkuint16)width)
2350  {
2351  // 2010-04-20
2352  // This code has never been debugged. So the first time we run it
2353  // we want to make sure that it is doing what I say it is doing.
2354  /** @todo Need to properly debug through 'KKStr::LeftPad; */
2355  kkuint16 toIdx = 0;
2356  kkuint16 fromIdx = len - (kkuint16)width;
2357  while (fromIdx < len)
2358  {
2359  val[toIdx] = val[fromIdx];
2360  val[fromIdx] = 0;
2361  ++toIdx;
2362  ++fromIdx;
2363  }
2364  len = (kkuint16)width;
2365  val[len] = 0;
2366  }
2367  else
2368  {
2369  kkint32 fromIdx = len - 1;
2370  kkint32 toIdx = width - 1;
2371  while (fromIdx >= 0)
2372  {
2373  val[toIdx] = val[fromIdx];
2374  --fromIdx;
2375  --toIdx;
2376  }
2377 
2378  while (toIdx >= 0)
2379  {
2380  val[toIdx] = ch;
2381  --toIdx;
2382  }
2383 
2384  len = (kkuint16)width;
2385  val[len] = 0;
2386  }
2387  return;
2388 } /* LeftPad */
2389 
2390 
2391 
2392 
2393 
2394 char KKStr::EnterStr ()
2395 {
2396  kkint32 bp = 0;
2397  char buff[256];
2398  uchar ch;
2399 
2400  ch = (uchar)getchar ();
2401  if (ch == 10)
2402  ch = EnterChar;
2403 
2404  while ((ch != EnterChar) && (ch != EscapeChar))
2405  {
2406  if (ch == 8)
2407  {
2408  // Back Space
2409  if (bp > 0) {
2410  bp--;
2411  buff[bp] = 0;
2412  putchar (ch);
2413  }
2414  }
2415 
2416  else if (ch == 0)
2417  {
2418  // We have a control character.
2419  ch = (uchar)getchar ();
2420  }
2421 
2422  else
2423  {
2424  // putchar (ch);
2425  buff[bp] = ch;
2426  bp++;
2427  }
2428 
2429  ch = (uchar)getchar ();
2430  if (ch == 10)
2431  ch = EnterChar;
2432  }
2433 
2434  buff[bp] = 0;
2435 
2436  kkuint16 newLen = (kkuint16)strlen (buff);
2437 
2438  kkuint16 neededSpace = newLen + 1;
2439 
2440  if (neededSpace > allocatedSize)
2441  {
2442  delete [] val;
2443  val = NULL;
2444  AllocateStrSpace (neededSpace);
2445  }
2446 
2447  STRCOPY (val, allocatedSize, buff);
2448  len = newLen;
2449 
2450  return ch;
2451 } /* EnterStr */
2452 
2453 
2454 
2455 
2456 
2457 /**
2458  *@brief Converts all characters in string to their Upper case equivalents via 'toupper'.
2459  *@see ToUpper
2460  */
2461 void KKStr::Upper ()
2462 {
2463  #ifdef KKDEBUG
2464  ValidateLen ();
2465  #endif
2466 
2467  if (!val)
2468  return;
2469 
2470  kkuint32 x;
2471 
2472  for (x = 0; x < len; x++)
2473  val[x] = (uchar)toupper (val[x]);
2474 } /* Upper */
2475 
2476 
2477 
2478 /**
2479  *@brief Converts all characters in string to their Lower case equivalents via 'tolower'.
2480  *@see ToLower
2481  */
2482 void KKStr::Lower ()
2483 {
2484  #ifdef KKDEBUG
2485  ValidateLen ();
2486  #endif
2487 
2488  if (!val)
2489  return;
2490 
2491  kkuint32 x;
2492 
2493  for (x = 0; x < len; x++)
2494  val[x] = (uchar)tolower (val[x]);
2495 } /* Lower */
2496 
2497 
2498 
2499 KKStr KKStr::MaxLen (kkuint32 maxLen) const
2500 {
2501  maxLen = Max ((kkuint32)0, maxLen);
2502  if (len < maxLen)
2503  return *this;
2504  else
2505  return SubStrPart (0, maxLen - 1);
2506 }
2507 
2508 
2509 
2511 {
2512  return KKStrIntMax - 1;
2513 }
2514 
2515 
2516 
2518 {
2519  if (!val)
2520  return "";
2521 
2522  KKStr upperStr (*this);
2523  upperStr.Upper ();
2524  return upperStr;
2525 } /* ToUpper */
2526 
2527 
2528 
2530 {
2531  if (!val)
2532  return "";
2533 
2534  KKStr lowerStr (*this);
2535  lowerStr.Lower ();
2536  return lowerStr;
2537 } /* ToLower */
2538 
2539 
2540 
2541 KKStrPtr KKStr::ToKKStrPtr () const
2542 {
2543  return new KKStr (*this);
2544 }
2545 
2546 
2547 
2548 bool KKStr::ValidInt (kkint32 &value)
2549 {
2550 
2551  kkint32 sign = 1;
2552 
2553  value = 0;
2554 
2555  if (!val)
2556  return false;
2557  else
2558  {
2559  char* ch = val;
2560 
2561  // Skip over white space
2562 
2563  while ((strchr (" \n\t", *ch)) && (*ch))
2564  ch++;
2565 
2566  if (!(*ch))
2567  return false;
2568 
2569  if (*ch == '-')
2570  {
2571  ch++;
2572  sign = -1;
2573  }
2574 
2575  kkint32 digit;
2576 
2577  digit = (*ch - '0');
2578 
2579  while ((digit >= 0) && (digit <= 9))
2580  {
2581  value = value * 10 + digit;
2582  ch++;
2583  digit = (*ch - '0');
2584  }
2585 
2586  value = value * sign;
2587 
2588  return (*ch == 0);
2589  }
2590 }
2591 
2592 
2593 
2594 bool KKStr::ValidMoney (float &value) const
2595 {
2596  kkint32 digit = 0;
2597  kkint32 sign = 1;
2598  value = 0;
2599  if (!val)
2600  return false;
2601 
2602  char* ch = val;
2603 
2604  // Skip over white space
2605  while ((strchr (" \n\t", *ch)) && (*ch))
2606  ch++;
2607  if (!(*ch))
2608  return false;
2609 
2610  bool decimalFound = false;
2611  kkint32 decimalDigits = 0;
2612 
2613  if (*ch == '-')
2614  {
2615  ch++;
2616  sign = -1;
2617  }
2618 
2619  digit = (*ch - '0');
2620  while (((digit >= 0) && (digit <= 9)) || (*ch == '.'))
2621  {
2622  if (*ch == '.')
2623  {
2624  if (decimalFound)
2625  return false;
2626  decimalFound = true;
2627  }
2628  else
2629  {
2630  if (decimalFound)
2631  decimalDigits++;
2632  value = value * 10 + digit;
2633  }
2634  ch++;
2635  digit = (*ch - '0');
2636  }
2637 
2638  if (decimalDigits > 2)
2639  return false;
2640 
2641  while (decimalDigits > 0)
2642  {
2643  value = value / 10;
2644  decimalDigits--;
2645  }
2646 
2647  value = value * sign;
2648  return (*ch == 0);
2649 } // ValidMoney
2650 
2651 
2652 
2653 bool KKStr::ValidNum (double& value) const
2654 {
2655  kkint32 digit = 0;
2656  kkint32 sign = 1;
2657  value = 0.0;
2658  value = 0;
2659  if (!val)
2660  return false;
2661 
2662  char* ch = val;
2663 
2664  // Skip over white space
2665  while ((strchr (" \n\t", *ch)) && (*ch))
2666  ch++;
2667  if (!(*ch))
2668  return false;
2669 
2670  bool decimalFound = false;
2671  kkint32 decimalDigits = 0;
2672 
2673  if (*ch == '-')
2674  {
2675  ch++;
2676  sign = -1;
2677  }
2678 
2679  digit = (*ch - '0');
2680 
2681  while (((digit >= 0) && (digit <= 9)) || (*ch == '.'))
2682  {
2683  if (*ch == '.')
2684  {
2685  if (decimalFound)
2686  return false;
2687  decimalFound = true;
2688  }
2689  else
2690  {
2691  if (decimalFound)
2692  decimalDigits++;
2693  value = value * 10 + digit;
2694  }
2695  ch++;
2696  digit = (*ch - '0');
2697  }
2698 
2699  while (decimalDigits > 0)
2700  {
2701  value = value / 10;
2702  decimalDigits--;
2703  }
2704 
2705  value = value * sign;
2706  return (*ch == 0);
2707 } /* ValidNum */
2708 
2709 
2710 
2711 
2712 bool KKStr::CharInStr (char ch)
2713 {
2714  if (!val)
2715  return false;
2716 
2717  for (kkint32 x = 0; x < len; x++)
2718  {
2719  if (val[x] == ch)
2720  return true;
2721  }
2722  return false;
2723 }
2724 
2725 
2726 
2727 
2728 /**
2729  *@brief Searches for the occurrence of 'searchField' and where in the string. If found will return 'true' otherwise 'false'.
2730  */
2731 bool KKStr::StrInStr (const KKStr& searchField) const
2732 {
2733  return StrInStr (val, searchField.val);
2734 }
2735 
2736 
2737 
2738 /*
2739 KKStr KKStr::SubStr (kkint32 firstChar,
2740  kkint32 subStrLen
2741  )
2742 {
2743  kkuint32 lastChar;
2744  KKStr subStr;
2745  kkuint32 x;
2746  kkuint32 y;
2747 
2748 
2749  if ((subStrLen < 1) || (!val))
2750  {
2751  subStr = "";
2752  return subStr;
2753  }
2754 
2755 
2756  lastChar = firstChar + subStrLen - 1;
2757 
2758  if (lastChar >= len)
2759  lastChar = len - 1;
2760 
2761  kkint32 neededSpace = 1 + subStrLen;
2762 
2763  subStr.AllocateStrSpace (neededSpace);
2764 
2765  y = 0;
2766  for (x = firstChar; x <= lastChar; x++)
2767  {
2768  subStr.val[y] = val[x];
2769  y++;
2770  }
2771 
2772  subStr.val[subStrLen] = 0;
2773  subStr.len = subStrLen;
2774  return subStr;
2775 }
2776 */
2777 
2778 
2779 
2780 KKStr KKStr::SubStrPart (kkint32 firstChar) const
2781 {
2782  #ifdef KKDEBUG
2783  ValidateLen ();
2784  #endif
2785 
2786  if ((kkuint16)firstChar >= len)
2787  return "";
2788 
2789  if (firstChar < 0)
2790  firstChar = 0;
2791 
2792  kkuint16 subStrLen = len - (kkuint16)firstChar;
2793  KKStr subStr (subStrLen + 1);
2794  subStr.Append (((char*)&(val[firstChar])), subStrLen);
2795 
2796  return subStr;
2797 } /* SubStrPart */
2798 
2799 
2800 
2801 
2803  kkint32 lastChar
2804  ) const
2805 {
2806  #ifdef KKDEBUG
2807  ValidateLen ();
2808  #endif
2809 
2810  if (((kkuint16)firstChar >= len) || (lastChar < firstChar))
2811  return "";
2812 
2813  if (firstChar < 0)
2814  firstChar = 0;
2815 
2816  if (lastChar >= len)
2817  lastChar = len - 1;
2818 
2819 
2820  kkuint16 subStrLen = ((kkuint16)lastChar - (kkuint16)firstChar) + 1;
2821  KKStr subStr (subStrLen + 2);
2822 
2823  kkuint16 x = (kkuint16)firstChar;
2824  kkuint16 y = 0;
2825 
2826  for (x = (kkuint16)firstChar; x <= (kkuint16)lastChar; x++, y++)
2827  {
2828  subStr.val[y] = val[x];
2829  }
2830 
2831  subStr.val[y] = 0;
2832  subStr.len = subStrLen;
2833  return subStr;
2834 } /* SubStrPart */
2835 
2836 
2837 
2838 /**
2839  *@brief Returns a string consisting of the 'tailLen' characters from the end of the string.
2840  *@details
2841  *@code
2842  *ex:
2843  * if test = "Hello World.";
2844  * test.Tail (2) will return "d.".
2845  *@endcode
2846  */
2847 KKStr KKStr::Tail (kkint32 tailLen) const // Return back the last 'len' characters.
2848 {
2849  if (tailLen <= 0)
2850  return "";
2851 
2852  kkuint16 firstChar = Max ((kkuint16)(len - (kkuint16)tailLen), (kkuint16)0);
2853  return SubStrPart (firstChar);
2854 } /* Tail */
2855 
2856 
2857 
2858 
2859 /**
2860  *@brief Remove characters from the end of the string.
2861  *@details Removes characters from end of string starting at position 'lastCharPos'. If 'lastCharPos'
2862  * is greater than length of string will do nothing. If 'lastCharPos' is less than or
2863  * equal to '0' will delete all characters from string.
2864  *@param[in] lastCharPos Will remove all characters starting at 'lastCharPos' from end of string.
2865  */
2866 void KKStr::LopOff (kkint32 lastCharPos)
2867 {
2868  #ifdef KKDEBUG
2869  ValidateLen ();
2870  #endif
2871 
2872  if (lastCharPos >= len)
2873  return;
2874 
2875  if (lastCharPos < -1)
2876  lastCharPos = -1;
2877 
2878  kkuint16 newLen = (kkuint16)(lastCharPos + 1);
2879  while (len > newLen)
2880  {
2881  len--;
2882  val[len] = 0;
2883  }
2884 } /* LoppOff */
2885 
2886 
2887 
2888 
2889 
2891 {
2892  if ((!val) || (len < 1))
2893  {
2894  return "\"\"";
2895  }
2896 
2897 
2898  KKStr result (Len () + 5);
2899 
2900  result.Append ('"');
2901 
2902  kkint32 idx = 0;
2903 
2904  while (idx < len)
2905  {
2906  switch (val[idx])
2907  {
2908  case '\"': result.Append ("\\\""); break;
2909  case '\t': result.Append ("\\t"); break;
2910  case '\n': result.Append ("\\n"); break;
2911  case '\r': result.Append ("\\r"); break;
2912  case '\\': result.Append ("\\\\"); break;
2913  case 0: result.Append ("\\0"); break;
2914 
2915  default: result.Append (val[idx]); break;
2916  }
2917 
2918  idx++;
2919  }
2920 
2921  result.Append ('"');
2922 
2923  return result;
2924 } /* QuotedStr */
2925 
2926 
2927 
2928 
2930 {
2931  if ((!val) || (len < 1))
2932  {
2933  return KKStr::EmptyStr ();
2934  }
2935 
2936  KKStr result (Len () + 5);
2937 
2938  kkint32 idx = 0;
2939  while (idx < len)
2940  {
2941  switch (val[idx])
2942  {
2943  case '<' : result.Append ("&lt;"); break;
2944  case '>' : result.Append ("&gt;"); break;
2945  case '&' : result.Append ("&amp;"); break;
2946  case '\"': result.Append ("&quot;"); break;
2947  case '\'': result.Append ("&apos;"); break;
2948  case '\t': result.Append ("&tab;"); break;
2949  case '\n': result.Append ("&nl;"); break;
2950  case '\r': result.Append ("&cr;"); break;
2951  case '\\': result.Append ("&bs;"); break;
2952  case 0: result.Append ("&null;"); break;
2953 
2954  default: result.Append (val[idx]); break;
2955  }
2956 
2957  idx++;
2958  }
2959 
2960  return result;
2961 } /* ToXmlStr */
2962 
2963 
2964 
2965 
2966 
2967 
2968 
2969 KKStr KKStr::ExtractToken (const char* delStr)
2970 {
2971  if (!val)
2972  return "";
2973 
2974 
2975  #ifdef KKDEBUG
2976  ValidateLen ();
2977  #endif
2978 
2979  KKStr token;
2980 
2981  char* tokenStart = val;
2982 
2983  // Skip leading Delimiters
2984  while ((*tokenStart != 0) && (strchr (delStr, *tokenStart)))
2985  tokenStart++;
2986 
2987  if (*tokenStart == 0)
2988  {
2989  delete [] val;
2990  val = NULL;
2991  AllocateStrSpace (1);
2992  return token;
2993  }
2994 
2995  char* tokenNext = tokenStart;
2996 
2997  while ((*tokenNext != 0) && (!strchr (delStr, *tokenNext)))
2998  tokenNext++;
2999 
3000  if (*tokenNext)
3001  {
3002  *tokenNext = 0;
3003  token = tokenStart;
3004 
3005  *tokenNext = ' ';
3006  tokenNext++;
3007 
3008  len = (kkuint16)strlen (tokenNext);
3009  memmove (val, tokenNext, len);
3010  val[len] = 0;
3011  }
3012 
3013  else
3014  {
3015  token = tokenStart;
3016  memset (val, 0, allocatedSize);
3017  len = 0;
3018  }
3019 
3020  return token;
3021 } /* ExtractToken */
3022 
3023 
3024 
3025 
3026 KKStr KKStr::ExtractToken2 (const char* delStr)
3027 {
3028  #ifdef KKDEBUG
3029  ValidateLen ();
3030  #endif
3031 
3032 
3033  if (!val)
3034  return KKStr ();
3035 
3036  KKStr token;
3037 
3038  char* tokenStart = val;
3039 
3040  // Skip Leading Blanks
3041  while ((*tokenStart != 0) && (*tokenStart == ' '))
3042  tokenStart++;
3043 
3044  if (*tokenStart == 0)
3045  {
3046  delete [] val;
3047  val = NULL;
3048  AllocateStrSpace (1);
3049  return token;
3050  }
3051 
3052  char* tokenNext = tokenStart;
3053 
3054  while ((*tokenNext != 0) && (!strchr (delStr, *tokenNext)))
3055  tokenNext++;
3056 
3057  // Remove trailing spaces
3058  char* tokenEnd = tokenNext;
3059  tokenEnd--;
3060  while ((tokenEnd != tokenStart) && ((*tokenEnd == ' ') || (*tokenEnd == '\n') || (*tokenEnd == '\r')))
3061  *tokenEnd = 0;
3062 
3063  if (*tokenNext)
3064  {
3065  *tokenNext = 0;
3066  token = tokenStart;
3067 
3068  *tokenNext = ' ';
3069  tokenNext++;
3070 
3071  len = (kkuint16)strlen (tokenNext);
3072  memmove (val, tokenNext, len);
3073  val[len] = 0;
3074  }
3075 
3076  else
3077  {
3078  token = tokenStart;
3079  memset (val, 0, allocatedSize);
3080  len = 0;
3081  }
3082 
3083  return token;
3084 } /* ExtractToken2 */
3085 
3086 
3087 
3088 
3089 KKStr KKStr::GetNextToken2 (const char* delStr) const
3090 {
3091  #ifdef KKDEBUG
3092  ValidateLen ();
3093  #endif
3094 
3095  if (!val)
3096  return "";
3097 
3098  kkint32 startCharPos = 0;
3099 
3100  while (startCharPos < len)
3101  {
3102  if (val[startCharPos] != ' ')
3103  break;
3104  startCharPos++;
3105  }
3106 
3107  if (startCharPos >= len)
3108  return "";
3109 
3110  kkint32 lastCharPos = startCharPos;
3111 
3112  while (lastCharPos < len)
3113  {
3114  if (strchr (delStr, val[lastCharPos]) != NULL)
3115  {
3116  // We just found the first delimiter
3117  lastCharPos--;
3118  return SubStrPart (startCharPos, lastCharPos);
3119  }
3120  lastCharPos++;
3121  }
3122 
3123  return SubStrPart (startCharPos);
3124 } /* GetNextToken2 */
3125 
3126 
3127 
3128 
3129 kkint32 KKStr::ExtractTokenInt (const char* delStr)
3130 {
3131  #ifdef KKDEBUG
3132  ValidateLen ();
3133  #endif
3134 
3135  KKStr workStr = ExtractToken2 (delStr);
3136  return atoi (workStr.Str ());
3137 }
3138 
3139 
3140 
3141 kkuint32 KKStr::ExtractTokenUint (const char* delStr)
3142 {
3143  #ifdef KKDEBUG
3144  ValidateLen ();
3145  #endif
3146 
3147  KKStr workStr = ExtractToken2 (delStr);
3148  return (kkuint32)atol (workStr.Str ());
3149 }
3150 
3151 
3152 
3153 KKB::kkuint64 KKStr::ExtractTokenUint64 (const char* delStr)
3154 {
3155  #ifdef KKDEBUG
3156  ValidateLen ();
3157  #endif
3158 
3159  KKStr workStr = ExtractToken2 (delStr);
3160  return workStr.ToUint64 ();
3161 }
3162 
3163 
3164 
3165 bool KKStr::ExtractTokenBool (const char* delStr)
3166 {
3167  KKStr workStr = ExtractToken2 (delStr);
3168  workStr.Upper ();
3169 
3170  return ((workStr == "YES") ||
3171  (workStr == "Y") ||
3172  (workStr == "TRUE") ||
3173  (workStr == "T") ||
3174  (workStr == "1")
3175  );
3176 } /* ExtractTokenBool */
3177 
3178 
3179 
3180 double KKStr::ExtractTokenDouble (const char* delStr)
3181 {
3182  #ifdef KKDEBUG
3183  ValidateLen ();
3184  #endif
3185 
3186  KKStr workStr = ExtractToken2 (delStr);
3187 
3188  if (workStr.Len () == 0)
3189  return 0.0;
3190 
3191  return atof (workStr.Str ());
3192 }
3193 
3194 
3195 
3196 
3198 {
3199  #ifdef KKDEBUG
3200  ValidateLen ();
3201  #endif
3202 
3203  if (!val)
3204  return 0;
3205 
3206  if (len <= 0)
3207  return 0;
3208 
3209  char returnChar = val[0];
3210 
3211  kkuint16 newLen = len - 1;
3212 
3213  for (kkuint16 x = 0; x < newLen; x++)
3214  {
3215  val[x] = val[x + 1];
3216  }
3217 
3218  len = newLen;
3219  val[len] = 0;
3220 
3221  return returnChar;
3222 } /* ExtractChar */
3223 
3224 
3225 
3227 {
3228  #ifdef KKDEBUG
3229  ValidateLen ();
3230  #endif
3231 
3232  if ((!val) || (len < 1))
3233  return 0;
3234 
3235  --len;
3236 
3237  return val[len];
3238 } /* ExtractLastChar */
3239 
3240 
3241 
3242 
3244 {
3245  if ((!val) || (len == 0))
3246  return EmptyStr ();
3247 
3248  KKStr result (len + 4);
3249  kkint32 idx = 0;
3250 
3251  kkint32 lastCharPos = len - 1;
3252 
3253  if ((val[idx] == '"') && (val[len - 1] == '"'))
3254  {
3255  ++idx;
3256  --lastCharPos;
3257  }
3258 
3259  while (idx <= lastCharPos)
3260  {
3261  if (val[idx] == '\\')
3262  {
3263  ++idx;
3264  if (idx <= lastCharPos)
3265  {
3266  result.Append (val[idx]);
3267  ++idx;
3268  }
3269  }
3270  else
3271  {
3272  result.Append (val[idx]);
3273  ++idx;
3274  }
3275  }
3276 
3277  return result;
3278 } /* DecodeQuotedStr */
3279 
3280 
3281 
3282 KKStr KKStr::ExtractQuotedStr (const char* delChars,
3283  bool decodeEscapeCharacters
3284  )
3285 {
3286  if ((!val) || (len == 0))
3287  return EmptyStr ();
3288 
3289  KKStr result (len);
3290  kkint32 idx = 0;
3291 
3292  bool lookForTerminatingQuote = false;
3293 
3294  if (val[idx] == '"')
3295  {
3296  lookForTerminatingQuote = true;
3297  idx++;
3298  }
3299 
3300 
3301  if (idx >= len)
3302  {
3303  delete [] val;
3304  val = NULL;
3305  AllocateStrSpace (1);
3306  return result;
3307  }
3308 
3309  // Search for matching terminating Quote
3310  while (idx < len)
3311  {
3312  if (lookForTerminatingQuote)
3313  {
3314  if (val[idx] == '"')
3315  {
3316  idx++;
3317  if (idx < len)
3318  {
3319  if (strchr (delChars, val[idx]))
3320  idx++;
3321  }
3322 
3323  break;
3324  }
3325  }
3326 
3327  else
3328  {
3329  if (strchr (delChars, val[idx]))
3330  {
3331  idx++;
3332  break;
3333  }
3334  }
3335 
3336  if ((val[idx] == '\\') && (decodeEscapeCharacters))
3337  {
3338  idx++;
3339  if (idx < len)
3340  {
3341  switch (val[idx])
3342  {
3343  case '"': result.Append ('"'); break;
3344  case 't': result.Append ('\t'); break;
3345  case 'n': result.Append ('\n'); break;
3346  case 'r': result.Append ('\r'); break;
3347  case '\\': result.Append ('\\'); break;
3348  case '0': result.Append (char (0)); break;
3349  case 0: break;
3350  default: result.Append (val[idx]); break;
3351  }
3352  idx++;
3353  }
3354  }
3355  else
3356  {
3357  result.Append (val[idx]);
3358  idx++;
3359  }
3360  }
3361 
3362  if (idx < len)
3363  {
3364  len = (kkuint16)(len - idx);
3365  memmove (val, &(val[idx]), len);
3366  val[len] = 0;
3367  }
3368  else
3369  {
3370  val[0] = 0;
3371  len = 0;
3372  }
3373 
3374  return result;
3375 } /* ExtractQuotedStr */
3376 
3377 
3378 
3379 char KKStr::operator[] (kkint16 i) const
3380 {
3381  #ifdef KKDEBUG
3382  ValidateLen ();
3383  #endif
3384 
3385  if (!val)
3386  return 0;
3387 
3388  if ((i < 0) || ((kkuint16)i >= len))
3389  return 0;
3390  else
3391  return val[i];
3392 }
3393 
3394 
3395 
3396 char KKStr::operator[] (kkuint16 i) const
3397 {
3398  #ifdef KKDEBUG
3399  ValidateLen ();
3400  #endif
3401 
3402  if (!val)
3403  return 0;
3404 
3405  if (i >= len)
3406  return 0;
3407  else
3408  return val[i];
3409 }
3410 
3411 
3412 
3413 char KKStr::operator[] (kkint32 i) const
3414 {
3415  #ifdef KKDEBUG
3416  ValidateLen ();
3417  #endif
3418 
3419  if (!val)
3420  return 0;
3421 
3422  if ((i < 0) || ((kkuint16)i >= len))
3423  return 0;
3424  else
3425  return val[i];
3426 }
3427 
3428 
3429 
3430 char KKStr::operator[] (kkuint32 i) const
3431 {
3432  #ifdef KKDEBUG
3433  ValidateLen ();
3434  #endif
3435 
3436  if (!val)
3437  return 0;
3438 
3439  if (i >= len)
3440  return 0;
3441  else
3442  return val[i];
3443 }
3444 
3445 
3446 
3447 
3448 
3449 /**
3450  *@brief Static method that returns an Empty String.
3451  *@return a empty String.
3452  */
3454 {
3455  static KKStr emptyStr = "";
3456  return emptyStr;
3457 }
3458 
3459 
3460 
3461 VectorKKStr KKStr::Parse (const char* delStr) const
3462 {
3463  KKStr wrkStr (*this);
3464  wrkStr.TrimLeft (" ");
3465  wrkStr.TrimRight (" ");
3466 
3467  VectorKKStr result;
3468 
3469  while (!wrkStr.Empty ())
3470  {
3471  KKStr field = wrkStr.ExtractToken2 (delStr);
3472  result.push_back (field);
3473  }
3474 
3475  return result;
3476 } /* Parse */
3477 
3478 
3479 
3480 VectorKKStr KKStr::Split (const char* delStr) const
3481 {
3482  KKStr wrkStr (*this);
3483  wrkStr.TrimLeft (" ");
3484  wrkStr.TrimRight (" ");
3485 
3486  VectorKKStr result;
3487 
3488  while (!wrkStr.Empty ())
3489  {
3490  KKStr field = wrkStr.ExtractToken2 (delStr);
3491  result.push_back (field);
3492  }
3493 
3494  return result;
3495 } /* Split */
3496 
3497 
3498 
3499 
3500 VectorKKStr KKStr::Split (char del) const
3501 {
3502  char delStr[2];
3503  delStr[0] = del;
3504  delStr[1] = 0;
3505 
3506  KKStr wrkStr (*this);
3507  wrkStr.TrimLeft (" ");
3508  wrkStr.TrimRight (" ");
3509 
3510  VectorKKStr result;
3511 
3512  while (!wrkStr.Empty ())
3513  {
3514  KKStr field = wrkStr.ExtractToken2 (delStr);
3515  result.push_back (field);
3516  }
3517 
3518  return result;
3519 } /* Parse */
3520 
3521 
3522 
3523 bool KKStr::ToBool () const
3524 {
3525  if (len < 1)
3526  return false;
3527 
3528  if ((STRICMP (val, "y") == 0) ||
3529  (STRICMP (val, "yes") == 0) ||
3530  (STRICMP (val, "t") == 0) ||
3531  (STRICMP (val, "true") == 0) ||
3532  (STRICMP (val, "1") == 0)
3533  )
3534  return true;
3535  else
3536  return false;
3537 }
3538 
3539 
3540 
3541 double KKStr::ToDouble () const
3542 {
3543  if (!val)
3544  return 0.0;
3545 
3546  double d = atof (val);
3547  return d;
3548 } /* ToDouble */
3549 
3550 
3551 
3552 
3553 float KKStr::ToFloat () const
3554 {
3555  if (!val)
3556  return 0.0f;
3557 
3558  float f = (float)atof (val);
3559  return f;
3560 } /* ToFloat */
3561 
3562 
3563 
3564 
3566 {
3567  if (!val)
3568  return 0;
3569 
3570  kkint32 i = atoi (val);
3571  return i;
3572 } /* ToInt*/
3573 
3574 
3575 
3577 {
3578  if (!val)
3579  return 0;
3580 
3581  kkint16 i = (kkint16)atoi (val);
3582  return i;
3583 } /* ToInt32*/
3584 
3585 
3586 
3588 {
3589  if (!val)
3590  return 0;
3591 
3592  kkint32 i = atoi (val);
3593  return i;
3594 } /* ToInt32*/
3595 
3596 
3597 
3599 {
3600  if (!val) return 0;
3601 
3602  #if defined(__GNUC__)
3603  return atoll (val);
3604  #else
3605  return (kkint64)_atoi64 (val);
3606  #endif
3607 }
3608 
3609 
3610 
3611 long KKStr::ToLong () const
3612 {
3613  if (!val)
3614  return 0;
3615 
3616  long l = atol (val);
3617  return l;
3618 } /* ToLong */
3619 
3620 
3621 
3622 
3623 float KKStr::ToPercentage () const
3624 {
3625  if (LastChar () == '%')
3626  {
3627  KKStr workStr = this->SubStrPart (0, Len () - 2);
3628  return workStr.ToFloat ();
3629  }
3630 
3631  return 100.0f * ToFloat ();
3632 }
3633 
3634 
3635 
3637 {
3638  if (!val) return 0;
3639  return (kkuint32)atol (val);
3640 }
3641 
3642 
3643 
3645 {
3646  if (!val) return 0;
3647  return (ulong)atol (val);
3648 }
3649 
3650 
3651 
3653 {
3654  if (!val) return 0;
3655  return (kkuint32)atol (val);
3656 }
3657 
3658 
3659 
3661 {
3662  if (!val) return 0;
3663  #if defined(__GNUC__)
3664  return (kkuint64)atoll (val);
3665  #else
3666  return (kkuint64)_atoi64 (val);
3667  #endif
3668 }
3669 
3670 
3672 {
3673  VectorInt32* results = new VectorInt32 ();
3674 
3675  KKStrParser parser (val);
3676 
3677  KKStr field = parser.GetNextToken (",\t \n\r");
3678  while (!field.Empty ())
3679  {
3680  kkint32 dashPos = field.LocateCharacter ('-');
3681  if (dashPos < 0)
3682  {
3683  // This is not a range
3684  results->push_back (field.ToInt32 ());
3685  }
3686  else
3687  {
3688  // We are looking at a range
3689  kkint32 startNum = field.SubStrPart (0, dashPos - 1).ToInt32 ();
3690  kkint32 endNum = field.SubStrPart (dashPos + 1).ToInt32 ();
3691  for (kkint32 z = startNum; z <= endNum; ++z)
3692  results->push_back (z);
3693  }
3694  field = parser.GetNextToken (",\t \n\r");
3695  }
3696  return results;
3697 } /* ToVectorint32 */
3698 
3699 
3700 
3701 
3702 
3703 wchar_t* KKStr::ToWchar_t () const
3704 {
3705  wchar_t* wa = NULL;
3706  if (val == NULL)
3707  {
3708  wa = new wchar_t[1];
3709  mbstowcs (wa, "", 1);
3710  return wa;
3711  }
3712  else
3713  {
3714  size_t wideLen = len + 1;
3715  wa = new wchar_t[wideLen];
3716  mbstowcs (wa, val, wideLen);
3717  }
3718  return wa;
3719 }
3720 
3721 
3722 
3723 
3724 
3725 double KKStr::ToLatitude () const
3726 {
3727  KKStr latitudeStr (*this);
3728  latitudeStr.Trim ();
3729 
3730  bool north = true;
3731  char lastChar = (char)toupper (latitudeStr.LastChar ());
3732  if (lastChar == 'N')
3733  {
3734  north = true;
3735  latitudeStr.ChopLastChar ();
3736  }
3737  else if (lastChar == 'S')
3738  {
3739  north = false;
3740  latitudeStr.ChopLastChar ();
3741  }
3742  latitudeStr.TrimRight ();
3743 
3744  if (latitudeStr.FirstChar () == '-')
3745  {
3746  latitudeStr.ChopFirstChar ();
3747  north = !north;
3748  latitudeStr.TrimLeft ();
3749  }
3750 
3751  double degrees = 0.0;
3752  double minutes = 0.0;
3753  double seconds = 0.0;
3754 
3755  KKStr degreesStr = "";
3756  KKStr minutesStr = "";
3757  KKStr secondsStr = "";
3758 
3759  kkint32 x = latitudeStr.LocateCharacter (':');
3760  if (x >= 0)
3761  {
3762  degreesStr = latitudeStr.SubStrPart (0, x - 1);
3763  degreesStr.TrimRight ();
3764  minutesStr = latitudeStr.SubStrPart (x + 1);
3765  minutesStr.Trim ();
3766  }
3767  else
3768  {
3769  x = latitudeStr.LocateCharacter (' ');
3770  if (x >= 0)
3771  {
3772  degreesStr = latitudeStr.SubStrPart (0, x - 1);
3773  degreesStr.TrimRight ();
3774  minutesStr = latitudeStr.SubStrPart (x + 1);
3775  minutesStr.Trim ();
3776  }
3777  else
3778  {
3779  degreesStr = latitudeStr;
3780  minutesStr = "";
3781  }
3782  }
3783 
3784  x = minutesStr.LocateCharacter (':');
3785  if (x >= 0)
3786  {
3787  secondsStr = minutesStr.SubStrPart (x + 1);
3788  minutesStr = minutesStr.SubStrPart (0, x - 1);
3789  secondsStr.Trim ();
3790  }
3791  else
3792  {
3793  x = minutesStr.LocateCharacter (' ');
3794  if (x >= 0)
3795  {
3796  secondsStr = minutesStr.SubStrPart (x + 1);
3797  minutesStr = minutesStr.SubStrPart (0, x - 1);
3798  secondsStr.Trim ();
3799  }
3800  }
3801 
3802  degrees = degreesStr.ToDouble ();
3803  minutes = minutesStr.ToDouble ();
3804  seconds = secondsStr.ToDouble ();
3805 
3806  double latitude = degrees + (minutes / 60.0) + (seconds / 3600.0);
3807  while (latitude > 90.0)
3808  latitude = latitude - 180.0;
3809 
3810  if (!north)
3811  latitude = 0.0 - latitude;
3812 
3813  return latitude;
3814 } /* ToLatitude */
3815 
3816 
3817 
3818 
3819 double KKStr::ToLongitude () const
3820 {
3821  KKStr longitudeStr (*this);
3822  bool east = true;
3823  char lastChar = (char)toupper (longitudeStr.LastChar ());
3824  if (lastChar == 'E')
3825  {
3826  east = true;
3827  longitudeStr.ChopLastChar ();
3828  }
3829  else if (lastChar == 'W')
3830  {
3831  east = false;
3832  longitudeStr.ChopLastChar ();
3833  }
3834 
3835  if (longitudeStr.FirstChar () == '-')
3836  {
3837  longitudeStr.ChopFirstChar ();
3838  east = !east;
3839  }
3840 
3841  double degrees = 0.0;
3842  double minutes = 0.0;
3843  double seconds = 0.0;
3844 
3845  KKStr degreesStr = "";
3846  KKStr minutesStr = "";
3847  KKStr secondsStr = "";
3848 
3849  kkint32 x = longitudeStr.LocateCharacter (':');
3850  if (x >= 0)
3851  {
3852  degreesStr = longitudeStr.SubStrPart (0, x - 1);
3853  degreesStr.TrimRight ();
3854  minutesStr = longitudeStr.SubStrPart (x + 1);
3855  minutesStr.Trim ();
3856  }
3857  else
3858  {
3859  x = longitudeStr.LocateCharacter (' ');
3860  if (x >= 0)
3861  {
3862  degreesStr = longitudeStr.SubStrPart (0, x - 1);
3863  degreesStr.TrimRight ();
3864  minutesStr = longitudeStr.SubStrPart (x + 1);
3865  minutesStr.Trim ();
3866  }
3867  else
3868  {
3869  degreesStr = longitudeStr;
3870  minutesStr = "";
3871  }
3872  }
3873 
3874  x = minutesStr.LocateCharacter (':');
3875  if (x >= 0)
3876  {
3877  secondsStr = minutesStr.SubStrPart (x + 1);
3878  minutesStr = minutesStr.SubStrPart (0, x - 1);
3879  secondsStr.Trim ();
3880  }
3881  else
3882  {
3883  x = minutesStr.LocateCharacter (' ');
3884  if (x >= 0)
3885  {
3886  secondsStr = minutesStr.SubStrPart (x + 1);
3887  minutesStr = minutesStr.SubStrPart (0, x - 1);
3888  secondsStr.Trim ();
3889  }
3890  }
3891 
3892  degrees = degreesStr.ToDouble ();
3893  minutes = minutesStr.ToDouble ();
3894  seconds = secondsStr.ToDouble ();
3895 
3896  double longitude = degrees + (minutes / 60.0) + (seconds / 3600.0);
3897  while (longitude > 180.0)
3898  longitude = longitude - 360.0;
3899  if (!east)
3900  longitude = 0.0 - longitude;
3901 
3902  return longitude;
3903 } /* ToLongitude */
3904 
3905 
3906 
3907 kkint32 SearchStr (const char* src,
3908  kkint32 srcLen,
3909  kkint32 startPos,
3910  const char* srchStr,
3911  kkint32 srchStrLen
3912  )
3913 {
3914  if ((!src) || (!srchStr))
3915  return -1;
3916 
3917  kkint32 numIter = (srcLen - (startPos + srchStrLen - 1));
3918  const char* startCh = src + startPos;
3919 
3920  kkint32 x;
3921  for (x = 0; x < numIter; ++x, ++startCh)
3922  {
3923  if (strncmp (startCh, srchStr, srchStrLen) == 0)
3924  return startPos + x;
3925  }
3926  return -1;
3927 }
3928 
3929 
3930 
3931 kkint32 KKStr::Find (const KKStr& str, kkint32 pos) const
3932 {
3933  return SearchStr (val, len, pos, str.Str (), str.Len ());
3934 }
3935 
3936 
3937 
3938 kkint32 KKStr::Find (const char* s, kkint32 pos, kkint32 n) const
3939 {
3940  return SearchStr (val, len, pos, s, n);
3941 }
3942 
3943 
3944 
3945 kkint32 KKStr::Find (const char* s, kkint32 pos) const
3946 {
3947  return SearchStr (val, len, pos, s, (kkint32)strlen (s));
3948 }
3949 
3950 
3951 
3952 kkint32 KKStr::Find (char c, kkint32 pos) const
3953 {
3954  for (kkint32 x = pos; x < len; x++)
3955  {
3956  if (val[x] == c)
3957  return x;
3958  }
3959  return -1;
3960 }
3961 
3962 
3963 
3964 KKStr KKB::operator+ (const char left,
3965  const KKStr& right
3966  )
3967 {
3968  KKStr result (right.Len () + 3);
3969  result.Append (left);
3970  result.Append (right);
3971  return result;
3972 }
3973 
3974 
3975 
3976 KKStr KKB::operator+ (const char* left,
3977  const KKStr& right
3978  )
3979 {
3980  return KKStr (left) + right;
3981 }
3982 
3983 
3984 
3985 
3986 KKStr KKStr::operator+ (const char* right) const
3987 {
3988  kkint32 resultStrLen = len + (kkint32)strlen (right);
3989  KKStr result (resultStrLen + 1);
3990  result.Append (*this);
3991  result.Append (right);
3992  return result;
3993 }
3994 
3995 
3996 
3997 
3998 KKStr KKStr::operator+ (const KKStr& right) const
3999 {
4000  kkint32 resultStrLen = len + right.len;
4001 
4002  KKStr result (resultStrLen + 1);
4003  result.Append (*this);
4004  result.Append (right);
4005  return result;
4006 }
4007 
4008 
4009 
4010 KKStr KKStr::operator+ (kkint16 right) const
4011 {
4012  char buff[60];
4013  SPRINTF (buff, sizeof (buff), "%-ld", right);
4014  kkint32 resultStrLen = len + (kkint32)strlen (buff);
4015  KKStr result (resultStrLen + 1);
4016  result.Append (*this);
4017  result.Append (buff);
4018  return result;
4019 }
4020 
4021 
4022 KKStr KKStr::operator+ (kkuint16 right) const
4023 {
4024  char buff[30];
4025  SPRINTF (buff, sizeof (buff), "%u", right);
4026 
4027  kkint32 resultStrLen = len + (kkint32)strlen (buff);
4028  KKStr result (resultStrLen + 1);
4029  result.Append (*this);
4030  result.Append (buff);
4031  return result;
4032 }
4033 
4034 
4035 
4036 KKStr KKStr::operator+ (kkint32 right) const
4037 {
4038  char buff[60];
4039  SPRINTF (buff, sizeof (buff), "%-ld", right);
4040 
4041  kkint32 resultStrLen = len + (kkint32)strlen (buff);
4042  KKStr result (resultStrLen + 1);
4043  result.Append (*this);
4044  result.Append (buff);
4045  return result;
4046 }
4047 
4048 
4049 
4050 KKStr KKStr::operator+ (kkuint32 right) const
4051 {
4052  char buff[30];
4053  SPRINTF (buff, sizeof (buff), "%u", right);
4054 
4055  kkint32 resultStrLen = len + (kkint32)strlen (buff);
4056  KKStr result (resultStrLen + 1);
4057  result.Append (*this);
4058  result.Append (buff);
4059  return result;
4060 }
4061 
4062 
4063 
4064 KKStr KKStr::operator+ (kkint64 right) const
4065 {
4066  char buff[70];
4067  SPRINTF (buff, sizeof (buff), "%-lld", right);
4068 
4069  kkint32 resultStrLen = len + (kkint32)strlen (buff);
4070  KKStr result (resultStrLen + 1);
4071  result.Append (*this);
4072  result.Append (buff);
4073  return result;
4074 }
4075 
4076 
4077 
4078 KKStr KKStr::operator+ (kkuint64 right) const
4079 {
4080  char buff[70];
4081  SPRINTF (buff, sizeof (buff), "%-llu", right);
4082 
4083  kkint32 resultStrLen = len + (kkint32)strlen (buff);
4084  KKStr result (resultStrLen + 1);
4085  result.Append (*this);
4086  result.Append (buff);
4087  return result;
4088 }
4089 
4090 
4091 
4092 KKStr KKStr::operator+ (float right) const
4093 {
4094  char buff[60];
4095 
4096  SPRINTF (buff, sizeof (buff), "%.9g", right);
4097 
4098  kkint32 resultStrLen = len + (kkint32)strlen (buff);
4099  KKStr result (resultStrLen + 1);
4100  result.Append (*this);
4101  result.Append (buff);
4102  return result;
4103 }
4104 
4105 
4106 
4107 KKStr KKStr::operator+ (double right) const
4108 {
4109  char buff[60];
4110  SPRINTF (buff, sizeof (buff), "%.17g", right);
4111 
4112  kkint32 resultStrLen = len + (kkint32)strlen (buff);
4113  KKStr result (resultStrLen + 1);
4114  result.Append (*this);
4115  result.Append (buff);
4116  return result;
4117 }
4118 
4119 
4120 
4121 KKStr& KKStr::operator<< (char right)
4122 {
4123  Append (right);
4124  return *this;
4125 }
4126 
4127 
4128 
4129 KKStr& KKStr::operator<< (const char* right)
4130 {
4131  if (!right)
4132  {
4133  const char* msg = "KKStr& operator<<(const char* right) **** ERROR **** right==NULL";
4134  cerr << std::endl << msg << std::endl << std::endl;
4135  throw KKException (msg);
4136  }
4137 
4138  Append (right);
4139  return *this;
4140 }
4141 
4142 
4143 
4144 KKStr& KKStr::operator<< (const KKStr& right)
4145 {
4146  Append (right.Str ());
4147  return *this;
4148 }
4149 
4150 
4151 KKStr& KKStr::operator<< (KKStr&& right)
4152 {
4153  if (len < 1)
4154  {
4155  val = right.val;
4156  len = right.len;
4157  allocatedSize = right.allocatedSize;
4158 
4159  right.val = NULL;
4160  right.len = 0;
4161  right.allocatedSize = 0;
4162  }
4163  else
4164  {
4165  Append (right.Str ());
4166  }
4167 
4168  return *this;
4169 }
4170 
4171 
4172 
4173 
4174 KKStr& KKStr::operator<< (kkint16 right)
4175 {
4176  AppendInt32 (right);
4177  return *this;
4178 }
4179 
4180 
4181 
4182 KKStr& KKStr::operator<< (kkuint16 right)
4183 {
4184  AppendUInt32 (right);
4185  return *this;
4186 }
4187 
4188 
4189 
4190 KKStr& KKStr::operator<< (kkint32 right)
4191 {
4192  AppendInt32 (right);
4193  return *this;
4194 }
4195 
4196 
4197 
4198 KKStr& KKStr::operator<< (kkuint32 right)
4199 {
4200  AppendUInt32 (right);
4201  return *this;
4202 }
4203 
4204 
4205 
4206 KKStr& KKStr::operator<< (kkint64 right)
4207 {
4208  KKStr s (30);
4209  s = StrFormatInt64 (right, "0");
4210  Append (s.Str ());
4211  return *this;
4212 }
4213 
4214 
4215 
4216 KKStr& KKStr::operator<< (kkuint64 right)
4217 {
4218  KKStr s (30);
4219  s = StrFormatInt64 (right, "0");
4220  Append (s.Str ());
4221  return *this;
4222 }
4223 
4224 
4225 
4226 KKStr& KKStr::operator<< (float right)
4227 {
4228  char buff[60];
4229  SPRINTF (buff, sizeof (buff), "%.9g", right);
4230  if (strchr (buff, '.') != NULL)
4231  {
4232  // Remove trailing Zeros
4233  kkint32 buffLen = (kkint32)strlen (buff);
4234  while ((buffLen > 1) && (buff[buffLen - 1] == '0') && (buff[buffLen - 2] == '0'))
4235  {
4236  buffLen--;
4237  buff[buffLen] = 0;
4238  }
4239  }
4240  Append (buff);
4241  return *this;
4242 }
4243 
4244 
4245 
4246 KKStr& KKStr::operator<< (double right)
4247 {
4248  char buff[70];
4249  SPRINTF (buff, sizeof (buff), "%.17g", right);
4250  if (strchr (buff, '.') != NULL)
4251  {
4252  // Remove trailing Zeros
4253  kkint32 buffLen = (kkint32)strlen (buff);
4254  while ((buffLen > 1) && (buff[buffLen - 1] == '0') && (buff[buffLen - 2] == '0'))
4255  {
4256  buffLen--;
4257  buff[buffLen] = 0;
4258  }
4259  }
4260  Append (buff);
4261  return *this;
4262 }
4263 
4264 
4265 
4266 
4267 
4268 void Test2 (ostream& x1, const char* x2)
4269 {
4270  x1 << x2;
4271 }
4272 
4273 
4274 
4275 
4276 #ifdef WIN32
4277 ostream& __cdecl KKB::operator<< ( ostream& os,
4278  const KKStr& strng
4279  )
4280 {
4281  os << (strng.Str ());
4282  return os;
4283 }
4284 
4285 
4286 
4287 std::istream& __cdecl KKB::operator>> (std::istream& is,
4288  KKStr& str
4289  )
4290 {
4291  char buff[10240];
4292  is >> buff;
4293  str = buff;
4294  str.TrimLeft ();
4295  str.TrimRight ();
4296  return is;
4297 }
4298 
4299 
4300 #else
4301 
4302 std::ostream& KKB::operator<< ( std::ostream& os,
4303  const KKStr& strng
4304  )
4305 {
4306  Test2 (os, strng.Str ());
4307  // os << (strng.Str ());
4308  return os;
4309 }
4310 
4311 
4312 
4313 std::istream& KKB::operator>> (std::istream& is,
4314  KKStr& str
4315  )
4316 {
4317  char buff[10240];
4318  is >> buff;
4319  str = buff;
4320  str.TrimLeft ();
4321  str.TrimRight ();
4322  return is;
4323 }
4324 #endif
4325 
4326 
4327 
4328 
4330 {
4331  KKStr s;
4332  s.RightPad (c);
4333  return s;
4334 }
4335 
4336 
4337 
4338 void KKStr::MemCpy (void* dest,
4339  void* src,
4340  kkuint32 size
4341  )
4342 {
4343 
4344  if (dest == NULL)
4345  {
4346  cerr << endl << "KKStr::MemCpy ***ERROR*** (dest == NULL)" << endl << endl;
4347  }
4348 
4349  else if (src == NULL)
4350  {
4351  cerr << endl << "KKStr::MemCpy ***ERROR*** (src == NULL)" << endl << endl;
4352  }
4353 
4354  else
4355  {
4356  memcpy (dest, src, size);
4357  }
4358 }
4359 
4360 
4361 
4362 void KKStr::MemSet (void* dest, kkuint8 byte, kkuint32 size)
4363 {
4364  if (dest == NULL)
4365  {
4366  cerr << "KKStr::MemSet ***ERROR*** (dest == NULL)" << endl;
4367  return;
4368  }
4369 
4370  memset (dest, byte, size);
4371 }
4372 
4373 
4374 
4375 void KKStr::StrCapitalize (char* str)
4376 {
4377  if (!str)
4378  return;
4379 
4380  char* ch = str;
4381  while (*ch)
4382  {
4383  *ch = (char)toupper (*ch);
4384  ch++;
4385  }
4386 }
4387 
4388 
4389 
4390 
4391 bool KKStr::StrInStr (const char* target,
4392  const char* searchStr
4393  )
4394 {
4395  if ((target == NULL) || (searchStr == NULL))
4396  return false;
4397 
4398 # ifdef USE_SECURE_FUNCS
4399  char* t = _strdup (target);
4400  char* s = _strdup (searchStr);
4401 # else
4402  char* t = strdup (target);
4403  char* s = strdup (searchStr);
4404 #endif
4405 
4406 
4407  StrCapitalize (t);
4408  StrCapitalize (s);
4409 
4410  bool f = (strstr (t, s) != NULL);
4411 
4412  free(t);
4413  free(s);
4414  return f;
4415 }
4416 
4417 
4418 
4419 
4420 void KKStr::WriteXML (const KKStr& varName,
4421  ostream& o
4422  ) const
4423 {
4424  XmlTag startTag ("KKStr", XmlTag::TagTypes::tagStart);
4425  if (!varName.Empty ())
4426  startTag.AddAtribute ("VarName", varName);
4427  startTag.AddAtribute ("Len", len);
4428  startTag.WriteXML (o);
4430  XmlTag endTag ("KKStr", XmlTag::TagTypes::tagEnd);
4431  endTag.WriteXML (o);
4432  o << endl;
4433 } /* WriteXML */
4434 
4435 
4436 
4437 
4439  XmlTagConstPtr tag,
4440  VolConstBool& cancelFlag,
4441  RunLog& log
4442  )
4443 {
4444  kkuint16 expectedLen = tag->AttributeValueInt32 ("Len");
4445  delete val;
4446  val = NULL;
4447  allocatedSize = 0;
4448  if (expectedLen > 0)
4449  AllocateStrSpace (expectedLen);
4450 
4451  delete val;
4452  val = NULL;
4453  allocatedSize = 0;
4454  AllocateStrSpace (expectedLen);
4455 
4456  XmlTokenPtr t = s.GetNextToken (cancelFlag, log);
4457  while (t && (!cancelFlag))
4458  {
4460  {
4461  XmlContentPtr c = dynamic_cast<XmlContentPtr> (t);
4462  Append (*(c->Content ()));
4463  }
4464  delete t;
4465  if (cancelFlag)
4466  t = NULL;
4467  else
4468  t = s.GetNextToken (cancelFlag, log);
4469  }
4470  delete t;
4471  t = NULL;
4472 
4473  TrimRight (" \r\n");
4474 } /* ReadXML */
4475 
4476 
4477 
4479  KKQueue<KKStr> (false),
4480  sorted (false)
4481 {
4482 }
4483 
4484 
4485 KKStrList::KKStrList (bool owner):
4486  KKQueue<KKStr> (owner),
4487  sorted (false)
4488 {
4489 }
4490 
4491 
4492 
4493 KKStrList::KKStrList (const char* s[]):
4494  KKQueue<KKStr> (true),
4495  sorted (false)
4496 {
4497  if (s == NULL)
4498  return;
4499 
4500  int x = 0;
4501  while (s[x] != NULL)
4502  {
4503  PushOnBack (new KKStr (s[x]));
4504  ++x;
4505  }
4506 }
4507 
4508 
4509 
4510 
4512 {
4513  kkint32 memoryConsumedEstimated = sizeof (KKStrList);
4514  KKStrList::const_iterator idx;
4515  for (idx = this->begin (); idx != this->end (); ++idx)
4516  memoryConsumedEstimated += (*idx)->MemoryConsumedEstimated ();
4517  return memoryConsumedEstimated;
4518 }
4519 
4520 
4521 
4523 {
4524  bool found = false;
4525  kkint32 idx;
4526  kkint32 qSize = QueueSize ();
4527 
4528  for (idx = 0; ((idx < qSize) && (!found)); idx++)
4529  found = (str == (*IdxToPtr (idx)));
4530 
4531  return found;
4532 }
4533 
4534 
4535 
4536 
4538  XmlTagConstPtr tag,
4539  VolConstBool& cancelFlag,
4540  RunLog& log
4541  )
4542 {
4543  kkuint32 count = (kkuint32)tag->AttributeValueInt32 ("Count");
4544 
4545  DeleteContents ();
4546 
4547  XmlTokenPtr t = s.GetNextToken (cancelFlag, log);
4548  while (t && (!cancelFlag))
4549  {
4551  {
4552  XmlContentPtr c = dynamic_cast<XmlContentPtr>(t);
4553  if ((c != NULL) && (c->Content () != NULL))
4554  {
4555  KKStrParser parser (*(c->Content ()));
4556  parser.TrimWhiteSpace (" ");
4557  while (parser.MoreTokens ())
4558  {
4559  KKStr field = parser.GetNextToken ("\t");
4560  PushOnBack (new KKStr (field));
4561  }
4562  }
4563  }
4564  delete t;
4565  if (cancelFlag)
4566  t = NULL;
4567  else
4568  t = s.GetNextToken (cancelFlag, log);
4569  }
4570  delete t;
4571  t = NULL;
4572 } /* ReadXML */
4573 
4574 
4575 
4576 
4577 void KKStrList::WriteXML (const KKStr& varName,
4578  ostream& o
4579  ) const
4580 {
4581  XmlTag startTag ("KKStrList", XmlTag::TagTypes::tagStart);
4582  if (!varName.Empty ())
4583  startTag.AddAtribute ("VarName", varName);
4584  startTag.AddAtribute ("Count", (kkint32)size ());
4585  startTag.WriteXML (o);
4586 
4587  const_iterator idx;
4588  kkuint32 x = 0;
4589  for (idx = begin (); idx != end (); ++idx, ++x)
4590  {
4591  KKStrPtr sp = *idx;
4592  if (x > 0) o << "\t";
4594  }
4595  XmlTag endTag ("KKStrList", XmlTag::TagTypes::tagEnd);
4596  endTag.WriteXML (o);
4597  o << endl;
4598 } /* WriteXML */
4599 
4600 
4601 
4602 
4603 
4604 
4605 
4606 
4607 KKStrPtr KKStrList::BinarySearch (const KKStr& searchStr)
4608 {
4609  if (!sorted)
4610  {
4611  KKStr errMsg = "KKStrList::BinarySearch **** ERROR **** KKStr List is Not Sorted";
4612  cerr << endl << errMsg << endl << endl;
4613  throw KKException (errMsg);
4614  }
4615 
4616  kkint32 low = 0;
4617  kkint32 high = QueueSize () - 1;
4618  kkint32 mid;
4619 
4620  KKStrPtr str = NULL;
4621 
4622  while (low <= high)
4623  {
4624  mid = (low + high) / 2;
4625 
4626  str = IdxToPtr (mid);
4627 
4628  if (*str < searchStr)
4629  {
4630  low = mid + 1;
4631  }
4632 
4633  else if (*str > searchStr)
4634  {
4635  high = mid - 1;
4636  }
4637 
4638  else
4639  {
4640  return str;
4641  }
4642  }
4643 
4644  return NULL;
4645 } /* BinarySearch */
4646 
4647 
4648 
4649 
4650 
4651 void KKStrList::AddString (KKStrPtr str)
4652 {
4653  PushOnBack (str);
4654  sorted = false;
4655 }
4656 
4657 
4658 
4659 KKStrListPtr KKStrList::ParseDelimitedString (const KKStr& str,
4660  const char* delChars
4661  )
4662 {
4663  KKStrListPtr parms = new KKStrList (true);
4664 
4665 # ifdef USE_SECURE_FUNCS
4666  char* workStr = _strdup (str.Str ());
4667 # else
4668  char* workStr = strdup (str.Str ());
4669 # endif
4670 
4671  char* nextChar = workStr;
4672 
4673  while (*nextChar)
4674  {
4675  // Skip Past Leading Blanks
4676  while ((*nextChar) && (*nextChar == ' '))
4677  {
4678  nextChar++;
4679  }
4680 
4681  if (*nextChar == 0)
4682  break;
4683 
4684  const char* startOfToken = nextChar;
4685 
4686  while ((*nextChar) && (strchr (delChars, *nextChar) == NULL))
4687  {
4688  nextChar++;
4689  }
4690 
4691  if (*nextChar != 0)
4692  {
4693  *nextChar = 0;
4694  nextChar++;
4695  }
4696 
4697  KKStrPtr token = new KKStr (startOfToken);
4698  token->TrimRight ();
4699 
4700  parms->PushOnBack (token);
4701  }
4702 
4703  delete [] workStr;
4704 
4705  return parms;
4706 } /* ParseDelimitedString */
4707 
4708 
4709 
4710 
4711 /**
4712  @brief Compares to Strings and returns -1, 0, or 1, indicating if less than, equal, or greater.
4713  */
4715  const KKStr& s2
4716  )
4717 {
4718  if (s1.val == NULL)
4719  {
4720  if (s2.val == NULL)
4721  return 0;
4722  else
4723  return -1;
4724  }
4725 
4726  else if (s2.val == NULL)
4727  {
4728  return 1;
4729  }
4730 
4731  else
4732  {
4733  return strcmp (s1.val, s2.val);
4734  }
4735 } /* CompareStrings */
4736 
4737 
4738 
4739 
4741 {
4742 public:
4743  StringComparison (bool _reversedOrder)
4744  {
4745  reversedOrder = _reversedOrder;
4746  }
4747 
4748 
4749  bool operator() (KKStrPtr p1,
4750  KKStrPtr p2
4751  )
4752  {
4753  if (reversedOrder)
4754  {
4755  return (KKStr::CompareStrings (*p2, *p1) > 0);
4756  }
4757  else
4758  {
4759  return (KKStr::CompareStrings (*p1, *p2) < 0);
4760  }
4761  }
4762 
4763 private:
4764  bool reversedOrder;
4765 }; /* StringComparison */
4766 
4767 
4768 
4769 
4770 void KKStrList::Sort (bool _reversedOrder)
4771 {
4772  StringComparison stringComparison (_reversedOrder);
4773  sort (begin (), end (), stringComparison);
4774  if (!_reversedOrder)
4775  sorted = true;
4776 }
4777 
4778 
4779 KKStrListPtr KKStrList::DuplicateListAndContents () const
4780 {
4781  KKStrListPtr newList = new KKStrList (true);
4782  KKStrList::const_iterator idx;
4783  for (idx = begin (); idx != end (); idx++)
4784  newList->PushOnBack (new KKStr (*(*idx)));
4785 
4786  return newList;
4787 } /* DuplicateListAndContents */
4788 
4789 
4790 
4792  char ch
4793  )
4794 {
4795  if (!str)
4796  return -1;
4797 
4798  bool found = false;
4799  size_t len = strlen (str);
4800  size_t idx = len - 1;
4801 
4802  while ((idx >= 0) && (!found))
4803  {
4804  if (str[idx] == ch)
4805  found = true;
4806  else
4807  idx--;
4808  }
4809 
4810  if (found)
4811  return (kkint32)idx;
4812  else
4813  return -1;
4814 
4815 } /* LocateLastOccurrence */
4816 
4817 
4818 
4820  const char* mask
4821  )
4822 {
4823  // Get number of decimal Places
4824 
4825  char buff[512];
4826  char* bp = buff + 511;
4827  *bp = 0;
4828 
4829  bool negativePrinted = true;
4830 
4831  if (val < 0)
4832  {
4833  negativePrinted = false;
4834  val = fabs (val);
4835  }
4836 
4837  bool printDecimalPoint = false;
4838 
4839  kkint32 numOfDecimalPlaces = 0;
4840 
4841  kkint32 maskLen = (kkint32)strlen (mask);
4842 
4843  kkint32 decimalPosition = LocateLastOccurrence (mask, '.');
4844 
4845  const char* maskPtr = mask + maskLen - 1;
4846 
4847  long intPart = (long)floor (val);
4848 
4849  kkint32 nextDigit = 0;
4850 
4851  kkint32 x;
4852 
4853  if (decimalPosition >= 0)
4854  {
4855  numOfDecimalPlaces = maskLen - decimalPosition - 1;
4856  printDecimalPoint = true;
4857  maskPtr = mask + decimalPosition - 1;
4858  maskLen = decimalPosition;
4859  }
4860 
4861  if (printDecimalPoint)
4862  {
4863  double power = pow ((double)10, (double)numOfDecimalPlaces);
4864 
4865  double frac = val - floor (val);
4866 
4867  kkint32 fracInt = (kkint32)(frac * power + 0.5);
4868 
4869  for (x = 0; x < numOfDecimalPlaces; x++)
4870  {
4871  nextDigit = fracInt % 10;
4872  fracInt = fracInt / 10;
4873  bp--;
4874  *bp = (char)('0' + nextDigit);
4875  }
4876 
4877  if (fracInt != 0)
4878  {
4879  // This can occur,
4880  // ex: mask = "#0.000", val = 1.9997
4881  // fracInt will end up equaling 1.000. because of rounding.
4882  intPart = intPart + fracInt;
4883  }
4884 
4885  bp--;
4886  *bp = '.';
4887  }
4888 
4889  char formatChar = ' ';
4890  char lastFormatChar = ' ';
4891 
4892  while (maskLen > 0)
4893  {
4894  formatChar = (char)toupper (*maskPtr);
4895 
4896  switch (formatChar)
4897  {
4898  case '0':
4899  case '@':
4900  nextDigit = intPart % 10;
4901  intPart = intPart / 10;
4902  bp--;
4903  *bp = '0' + (uchar)nextDigit;
4904  break;
4905 
4906 
4907  case '#':
4908  case '9':
4909  if (intPart > 0)
4910  {
4911  nextDigit = intPart % 10;
4912  intPart = intPart / 10;
4913  bp--;
4914  *bp = '0' + (uchar)nextDigit;
4915  }
4916  else
4917  {
4918  bp--;
4919  *bp = ' ';
4920  }
4921  break;
4922 
4923 
4924  case 'Z':
4925  if (intPart > 0)
4926  {
4927  nextDigit = intPart % 10;
4928  intPart = intPart / 10;
4929  bp--;
4930  *bp = '0' + (uchar)nextDigit;
4931  }
4932  break;
4933 
4934 
4935  case '-':
4936  if (intPart > 0)
4937  {
4938  nextDigit = intPart % 10;
4939  intPart = intPart / 10;
4940  bp--;
4941  *bp = '0' + (uchar)nextDigit;
4942  }
4943  else
4944  {
4945  if (!negativePrinted)
4946  {
4947  negativePrinted = true;
4948  bp--;
4949  *bp = '-';
4950  }
4951  }
4952  break;
4953 
4954 
4955  case ',':
4956  if (intPart > 0)
4957  {
4958  bp--;
4959  *bp = ',';
4960  }
4961 
4962  else if (lastFormatChar != 'Z')
4963  {
4964  bp--;
4965  *bp = ' ';
4966  }
4967  break;
4968 
4969 
4970  default:
4971  bp--;
4972  *bp = formatChar;
4973  break;
4974  } /* end of Switch (*maskPtr) */
4975 
4976 
4977  lastFormatChar = formatChar;
4978 
4979  maskPtr--;
4980  maskLen--;
4981  }
4982 
4983  // If the mask was not large enough to include all digits then lets do it now.
4984  while (intPart > 0)
4985  {
4986  nextDigit = intPart % 10;
4987  intPart = intPart / 10;
4988  bp--;
4989  *bp = '0' + (uchar)nextDigit;
4990  }
4991 
4992  if (!negativePrinted)
4993  {
4994  bp--;
4995  *bp = '-';
4996  }
4997 
4998  return KKStr (bp);
4999 } /* StrFormatDouble */
5000 
5001 
5002 
5003 
5005  const char* mask
5006  )
5007 {
5008  return KKB::StrFormatDouble ((double)val, mask);
5009 }
5010 
5011 
5012 
5014  const char* mask
5015  )
5016 {
5017  // Get number of decimal Places
5018 
5019  char buff[128];
5020  char* bp = buff + 127;
5021  *bp = 0;
5022 
5023  bool negativePrinted = true;
5024 
5025  if (val < 0)
5026  {
5027  negativePrinted = false;
5028  val = 0 - val;
5029  }
5030 
5031  kkint32 maskLen = (kkint32)strlen (mask);
5032  const char* maskPtr = mask + maskLen - 1;
5033 
5034  kkint64 intPart = val;
5035 
5036  kkint32 nextDigit = 0;
5037 
5038  char formatChar = ' ';
5039  char lastFormatChar = ' ';
5040 
5041  while (maskLen > 0)
5042  {
5043  formatChar = (uchar)toupper (*maskPtr);
5044 
5045  switch (formatChar)
5046  {
5047  case '0':
5048  case '@':
5049  nextDigit = intPart % 10;
5050  intPart = intPart / 10;
5051  bp--;
5052  *bp = '0' + (uchar)nextDigit;
5053  break;
5054 
5055 
5056  case '#':
5057  case '9':
5058  if (intPart > 0)
5059  {
5060  nextDigit = intPart % 10;
5061  intPart = intPart / 10;
5062  bp--;
5063  *bp = '0' + (uchar)nextDigit;
5064  }
5065  else
5066  {
5067  bp--;
5068  *bp = ' ';
5069  }
5070  break;
5071 
5072 
5073  case 'Z':
5074  if (intPart > 0)
5075  {
5076  nextDigit = intPart % 10;
5077  intPart = intPart / 10;
5078  bp--;
5079  *bp = '0' + (uchar)nextDigit;
5080  }
5081  break;
5082 
5083 
5084  case '-':
5085  if (intPart > 0)
5086  {
5087  nextDigit = intPart % 10;
5088  intPart = intPart / 10;
5089  bp--;
5090  *bp = '0' + (uchar)nextDigit;
5091  }
5092  else
5093  {
5094  if (!negativePrinted)
5095  {
5096  negativePrinted = true;
5097  bp--;
5098  *bp = '-';
5099  }
5100  }
5101  break;
5102 
5103 
5104  case ',':
5105  if (intPart > 0)
5106  {
5107  bp--;
5108  *bp = ',';
5109  }
5110 
5111  else if (lastFormatChar != 'Z')
5112  {
5113  bp--;
5114  *bp = ' ';
5115  }
5116  break;
5117 
5118 
5119  default:
5120  bp--;
5121  *bp = formatChar;
5122  break;
5123  } /* end of Switch (*maskPtr) */
5124 
5125 
5126  lastFormatChar = formatChar;
5127 
5128  maskPtr--;
5129  maskLen--;
5130  }
5131 
5132  // If the mask was not large enough to include all digits then lets do it now.
5133  while (intPart > 0)
5134  {
5135  nextDigit = intPart % 10;
5136  intPart = intPart / 10;
5137  bp--;
5138  *bp = '0' + (uchar)nextDigit;
5139  }
5140 
5141  if (!negativePrinted)
5142  {
5143  bp--;
5144  *bp = '-';
5145  }
5146 
5147  return KKStr (bp);
5148 } /* StrFormatInt */
5149 
5150 
5151 
5153 {
5154  char buff[50];
5155 
5156  SPRINTF (buff, sizeof (buff), "%d", i);
5157  KKStr s (buff);
5158  return s;
5159 } /* StrFromInt16 */
5160 
5161 
5162 
5163 
5165 {
5166  char buff[50];
5167 
5168  SPRINTF (buff, sizeof (buff), "%u", ui);
5169  KKStr s (buff);
5170  return s;
5171 } /* StrFromUint16 */
5172 
5173 
5174 
5176 {
5177  char buff[50];
5178 
5179  SPRINTF (buff, sizeof (buff), "%ld", i);
5180  KKStr s (buff);
5181  return s;
5182 } /* StrFromInt32 */
5183 
5184 
5185 
5186 
5188 {
5189  char buff[50];
5190 
5191  SPRINTF (buff, sizeof (buff), "%lu", ui);
5192  KKStr s (buff);
5193  return s;
5194 } /* StrFromUint32 */
5195 
5196 
5197 
5199 {
5200  char buff[50];
5201 
5202  SPRINTF (buff, sizeof (buff), "%lld", i64);
5203  KKStr s (buff);
5204  return s;
5205 } /* StrFromInt64 */
5206 
5207 
5208 
5210 {
5211  char buff[50];
5212  SPRINTF (buff, sizeof (buff), "%llu", ul);
5213  KKStr s (buff);
5214  return s;
5215 } /* StrFromUint64 */
5216 
5217 
5218 
5220 {
5221  char buff[50];
5222  SPRINTF (buff, sizeof (buff), "%f", f);
5223  KKStr s (buff);
5224  return s;
5225 } /* StrFromFloat */
5226 
5227 
5228 
5230 {
5231  char buff[50];
5232  SPRINTF (buff, sizeof (buff), "%g", d);
5233  KKStr s (buff);
5234  return s;
5235 } /* StrFromFloat */
5236 
5237 
5238 
5239 
5240 
5241 
5242 
5243 
5244 KKStr& KKStr::operator<< (std::ostream& (* mf)(std::ostream &))
5245 {
5246  ostringstream o;
5247  mf (o);
5248  Append (o.str ().c_str ());
5249  return *this;
5250 }
5251 
5252 
5253 
5254 
5255 const kkuint32 KKB::KKStr::KKStrIntMax = USHRT_MAX;
5256 
5257 
5258 
5259 
5260 
5261 
5262 
5263 
5265  vector<KKStr> ()
5266 {
5267 }
5268 
5269 
5271  vector<KKStr> (v)
5272 {
5273 }
5274 
5275 
5276 
5278  XmlTagConstPtr tag,
5279  VolConstBool& cancelFlag,
5280  RunLog& log
5281  )
5282 {
5283  kkuint32 count = (kkuint32)tag->AttributeValueInt32 ("Count");
5284 
5285  clear ();
5286 
5287  XmlTokenPtr t = s.GetNextToken (cancelFlag, log);
5288 
5289  while (t && (!cancelFlag))
5290  {
5292  {
5293  XmlContentPtr c = dynamic_cast<XmlContentPtr>(t);
5294  if ((c != NULL) && (c->Content () != NULL))
5295  {
5296  KKStrParser parser (*(c->Content ()));
5297  parser.TrimWhiteSpace (" ");
5298  while (parser.MoreTokens ())
5299  {
5300  KKStr field = parser.GetNextToken ("\t");
5301  push_back (field);
5302  }
5303  }
5304  }
5305 
5306  delete t;
5307  if (cancelFlag)
5308  t = NULL;
5309  else
5310  t = s.GetNextToken (cancelFlag, log);
5311  }
5312  delete t;
5313  t = NULL;
5314 } /* ReadXML */
5315 
5316 
5317 
5318 
5319 void VectorKKStr::WriteXML (const KKStr& varName,
5320  ostream& o
5321  ) const
5322 {
5323  XmlTag startTag ("VectorKKStr", XmlTag::TagTypes::tagStart);
5324  if (!varName.Empty ())
5325  startTag.AddAtribute ("VarName", varName);
5326  startTag.AddAtribute ("Count", (kkint32)size ());
5327  startTag.WriteXML (o);
5328 
5329  const_iterator idx;
5330  kkuint32 x = 0;
5331  for (idx = begin (); idx != end (); ++idx, ++x)
5332  {
5333  if (x > 0) o << "\t";
5334  XmlContent::WriteXml (idx->QuotedStr (), o);
5335  }
5336  XmlTag endTag ("VectorKKStr", XmlTag::TagTypes::tagEnd);
5337  endTag.WriteXML (o);
5338  o << endl;
5339 }
5340 
5341 
5342 
5343 
5344 
5345 KKStrListIndexed::KKStrPtrComp::KKStrPtrComp (bool _caseSensitive):
5346  caseSensitive (_caseSensitive)
5347 {}
5348 
5349 
5350 KKStrListIndexed::KKStrPtrComp::KKStrPtrComp (const KKStrPtrComp& comparator):
5351  caseSensitive (comparator.caseSensitive)
5352 {}
5353 
5354 
5355 
5356 bool KKStrListIndexed::KKStrPtrComp::operator() (const KKStrConstPtr& lhs, const KKStrConstPtr& rhs) const
5357 {
5358  if (caseSensitive)
5359  return ((*lhs) < (*rhs));
5360  else
5361  return (lhs->Compare (*rhs) < 0);
5362 }
5363 
5364 
5365 
5367  comparator (true),
5368  indexIndex (),
5369  memoryConsumedEstimated (0),
5370  nextIndex (0),
5371  owner (true),
5372  strIndex (NULL)
5373 {
5374  strIndex = new StrIndex (comparator);
5375  memoryConsumedEstimated = sizeof (*this);
5376 }
5377 
5378 
5379 
5380 
5382  bool _caseSensitive
5383  ):
5384  comparator (_caseSensitive),
5385  indexIndex (),
5386  memoryConsumedEstimated (0),
5387  nextIndex (0),
5388  owner (_owner),
5389  strIndex (NULL)
5390 {
5391  strIndex = new StrIndex (comparator);
5392  memoryConsumedEstimated = sizeof (*this);
5393 }
5394 
5395 
5396 
5398  comparator (list.comparator),
5399  indexIndex (),
5400  memoryConsumedEstimated (0),
5401  nextIndex (0),
5402  owner (list.owner),
5403  strIndex (NULL)
5404 {
5405  strIndex = new StrIndex (comparator);
5406  memoryConsumedEstimated = sizeof (*this);
5407  IndexIndex::const_iterator idx;
5408  for (idx = list.indexIndex.begin (); idx != list.indexIndex.end (); ++idx)
5409  {
5410  if (owner)
5411  Add (new KKStr (*(idx->second)));
5412  else
5413  Add (idx->second);
5414  }
5415 }
5416 
5417 
5418 
5419 
5421 {
5423  indexIndex.clear ();
5424  strIndex->clear ();
5425 }
5426 
5427 
5428 
5430 {
5431  if (owner)
5432  {
5433  StrIndex::iterator idx;
5434  for (idx = strIndex->begin (); idx != strIndex->end (); ++idx)
5435  {
5436  KKStrPtr s = idx->first;
5437  delete s;
5438  }
5439  }
5440 
5441  delete strIndex;
5442  strIndex = NULL;
5443 }
5444 
5445 
5446 
5448 {
5449  return indexIndex.size ();
5450 }
5451 
5452 
5453 
5455 {
5456  return memoryConsumedEstimated;
5457 } /* MemoryConsumedEstimated */
5458 
5459 
5460 
5461 
5463 {
5464  if (indexIndex.size () != right.indexIndex.size ())
5465  return false;
5466 
5467  bool caseSensativeComparison = caseSensative || right.caseSensative;
5468 
5469  IndexIndex::const_iterator idxLeft = indexIndex.begin ();
5470  IndexIndex::const_iterator idxRight = right.indexIndex.begin ();
5471 
5472  while ((idxLeft != indexIndex.end ()) && (idxRight != right.indexIndex.end ()))
5473  {
5474  if (idxLeft->first != idxRight->first)
5475  return false;
5476 
5477  if (caseSensativeComparison)
5478  {
5479  if (idxLeft->second->Compare (*(idxRight->second)) != 0)
5480  return false;
5481  }
5482  else
5483  {
5484  if (idxLeft->second->CompareIgnoreCase (*(idxRight->second)) != 0)
5485  return false;
5486  }
5487 
5488  if ((*(idxLeft->second)) != (*(idxRight->second)))
5489 
5490  ++idxLeft;
5491  ++idxRight;
5492  }
5493 
5494  return true;
5495 } /* operator== */
5496 
5497 
5498 
5500 {
5501  return !((*this) == right);
5502 } /* operator!= */
5503 
5504 
5505 
5507 {
5508  StrIndex::iterator idx;
5509  idx = strIndex->find (s);
5510  if (idx != strIndex->end ())
5511  return -1;
5512 
5513  kkint32 index = nextIndex;
5514  ++nextIndex;
5515 
5516  strIndex->insert (StrIndexPair (s, index));
5517  indexIndex.insert (IndexIndexPair (index, s));
5518 
5519  if (owner)
5520  memoryConsumedEstimated += s->MemoryConsumedEstimated ();
5521  memoryConsumedEstimated += 8;
5522  return index;
5523 } /* Add */
5524 
5525 
5526 
5527 
5528 
5530 {
5531  StrIndex::iterator idx;
5532  idx = strIndex->find (&s);
5533  if (idx == strIndex->end ())
5534  return -1;
5535 
5536  KKStrPtr strIndexStr = idx->first;
5537 
5538  kkint32 index = idx->second;
5539  strIndex->erase (idx);
5540 
5541  IndexIndex::iterator idx2;
5542  idx2 = indexIndex.find (index);
5543  if (idx2 != indexIndex.end ())
5544  indexIndex.erase (idx2);
5545 
5546  if (owner)
5547  {
5548  memoryConsumedEstimated -= strIndexStr->MemoryConsumedEstimated ();
5549  delete strIndexStr;
5550  strIndexStr = NULL;
5551  }
5552  memoryConsumedEstimated -= 8;
5553  return index;
5554 } /* Delete */
5555 
5556 
5557 
5559 {
5560  StrIndex::const_iterator idx;
5561 
5562  KKStr sNotConst (s);
5563 
5564  idx = strIndex->find (&sNotConst);
5565  if (idx == strIndex->end ())
5566  return -1;
5567  else
5568  return idx->second;
5569 }
5570 
5571 
5572 kkint32 KKStrListIndexed::LookUp (KKStrPtr s) const
5573 {
5574  StrIndex::iterator idx;
5575  idx = strIndex->find (s);
5576  if (idx == strIndex->end ())
5577  return -1;
5578  else
5579  return idx->second;
5580 }
5581 
5582 
5583 
5584 KKStrConstPtr KKStrListIndexed::LookUp (kkuint32 x) const
5585 {
5586  IndexIndex::const_iterator idx;
5587  idx = indexIndex.find (x);
5588  if (idx == indexIndex.end ())
5589  return NULL;
5590  else
5591  return idx->second;
5592 }
5593 
5594 
5596  XmlTagConstPtr tag,
5597  VolConstBool& cancelFlag,
5598  RunLog& log
5599  )
5600 {
5602  bool caseSensative = tag->AttributeValueByName ("CaseSensative")->ToBool ();
5603  comparator.caseSensitive = caseSensative;
5604 
5605  XmlTokenPtr t = s.GetNextToken (cancelFlag, log);
5606  while (t && (!cancelFlag))
5607  {
5609  {
5610  XmlContentPtr c = dynamic_cast<XmlContentPtr> (t);
5612 
5613  while (p.MoreTokens ())
5614  {
5615  KKStr s = p.GetNextToken (",\t\n\r");
5616  Add (new KKStr (s));
5617  }
5618  }
5619  delete t;
5620  if (cancelFlag)
5621  t = NULL;
5622  else
5623  t = s.GetNextToken (cancelFlag, log);
5624  }
5625  delete t;
5626  t = NULL;
5627 } /* ReadXML */
5628 
5629 
5630 ///<summary> Strings will be separated by tab(\t) characters and in order of index. </summary>
5632 {
5633  KKStr s (indexIndex.size () * 20);
5634  IndexIndex::const_iterator idx;
5635  for (idx = indexIndex.begin (); idx != indexIndex.end (); ++idx)
5636  {
5637  if (!s.Empty ())
5638  s << "\t";
5639  s << *(idx->second);
5640  }
5641  return s;
5642 }
5643 
5644 
5645 void KKStrListIndexed::WriteXML (const KKStr& varName, ostream& o) const
5646 {
5647  XmlTag startTag ("KKStrListIndexed", XmlTag::TagTypes::tagStart);
5648 
5649  if (!varName.Empty ())
5650  startTag.AddAtribute ("VarName", varName);
5651  startTag.AddAtribute ("CaseSensative", caseSensative);
5652  startTag.WriteXML (o);
5653 
5654  kkuint32 n = size ();
5655  for (kkuint32 x = 0; x < n; ++x)
5656  {
5657  KKStrConstPtr s = LookUp ((kkint32)x);
5658  if (x > 0) o << "\t";
5660  }
5661 
5662  XmlTag endTag ("KKStrListIndexed", XmlTag::TagTypes::tagEnd);
5663  endTag.WriteXML (o);
5664  o << endl;
5665 }
__int16 kkint16
16 bit signed integer.
Definition: KKBaseTypes.h:85
kkint32 Add(KKStrPtr s)
Definition: KKStr.cpp:5506
KKStr(kkint32 size)
Creates a KKStr object that pre-allocates space for &#39;size&#39; characters.
Definition: KKStr.cpp:655
XmlTag(const KKStr &_name, TagTypes _tagType)
Definition: XmlStream.cpp:586
KKStr StrFromFloat(float f)
Definition: KKStr.cpp:5219
KKStr Wide(kkint32 width, char dir= 'R') const
Pads the string with spaces so that it is exactly &#39;width&#39; characters long. Can pad either left...
Definition: KKStr.cpp:2203
VectorKKStr Split(const char *delStr="\n\r\t, ") const
Breaks up the contents of the string into tokens where the characters in &#39;delStr&#39; acts as separates e...
Definition: KKStr.cpp:3480
void AppendInt32(kkint32 i)
Definition: KKStr.cpp:1901
kkint32 SPRINTF(char *buff, kkint32 buffSize, const char *formatSpec, kkuint16 right)
Definition: KKStr.cpp:177
char * STRDUP(const char *src)
Definition: KKStr.cpp:62
char operator[](kkint16 i) const
Definition: KKStr.cpp:3379
KKStr & Trim(const char *whiteSpaceChars="\n\r\t ")
Definition: KKStr.cpp:1686
KKStr(KKStr &&str)
Definition: KKStr.cpp:599
KKStr(const std::string &s)
Definition: KKStr.cpp:677
bool EqualIgnoreCase(const char *s2) const
Definition: KKStr.cpp:1257
void AddAtribute(const KKStr &attributeName, bool attributeValue)
Definition: XmlStream.cpp:611
KKStr StrFormatInt64(kkint64 val, const char *mask)
Definition: KKStr.cpp:5013
void Append(const char *buff, kkuint32 buffLen)
Definition: KKStr.cpp:1821
kkint32 CompareIgnoreCase(const KKStr &s2) const
Compares with another KKStr, ignoring case.
Definition: KKStr.cpp:919
static bool StrEqualNoCase(const char *s1, const char *s2)
Definition: KKStr.cpp:408
kkint32 MemoryConsumedEstimated() const
Definition: KKStr.cpp:766
__int32 kkint32
Definition: KKBaseTypes.h:88
KKStr GetNextToken2(const char *delStr="\n\t\r ") const
Retrieves the first token in the string without removing any characters.
Definition: KKStr.cpp:3089
kkint32 Find(char c, kkint32 pos=0) const
Definition: KKStr.cpp:3952
kkint32 MemCompare(const char *s1, const char *s2, kkint32 s1Idx, kkint32 s2Idx, kkint32 len)
Definition: KKStr.cpp:2063
void TrimWhiteSpace(const char *_whiteSpace=" ")
After this call all leading and trailing whitespace will be trimmed from tokens.
Definition: KKStrParser.cpp:95
wchar_t * ToWchar_t() const
Definition: KKStr.cpp:3703
KKStr operator+(kkuint16 right) const
Definition: KKStr.cpp:4022
kkint32 CountInstancesOf(char ch) const
Definition: KKStr.cpp:1122
KKStr StrFromInt64(kkint64 i)
Definition: KKStr.cpp:5198
void ReadXML(XmlStream &s, XmlTagConstPtr tag, VolConstBool &cancelFlag, RunLog &log)
Definition: KKStr.cpp:4438
bool CharInStr(char ch)
Definition: KKStr.cpp:2712
kkuint32 ExtractTokenUint(const char *delStr)
Definition: KKStr.cpp:3141
KKStr & TrimRight(const char *whiteSpaceChars="\n\r\t ")
Definition: KKStr.cpp:1695
VectorKKStr Parse(const char *delStr="\n\r\t, ") const
Will break up the contents of the string into tokens where one of the characters in &#39;delStr&#39; separate...
Definition: KKStr.cpp:3461
kkuint32 ToUint32() const
Definition: KKStr.cpp:3652
static bool StrEqual(const char *s1, const char *s2)
Definition: KKStr.cpp:373
KKStr ExtractToken2(const char *delStr="\n\t\r ")
Extract first Token from the string.
Definition: KKStr.cpp:3026
bool operator>=(const KKStr &right) const
Definition: KKStr.cpp:1627
const KKStr * KKStrConstPtr
Definition: KKStr.h:84
KKStr GetNextToken(const char *delStr="\n\t\r ")
Extract next Token from string, tokens will be separated by delimiter characters. ...
void LeftPad(kkint32 width, uchar ch= ' ')
pads the string with enough &#39;ch&#39; characters on the left side until the string is as long as &#39;width&#39; c...
Definition: KKStr.cpp:2303
void Lower()
Make all characters in the String into lower case.
Definition: KKStr.cpp:2482
StringComparison(bool _reversedOrder)
Definition: KKStr.cpp:4743
KKStrConstPtr LookUp(kkuint32 x) const
Definition: KKStr.cpp:5584
bool StringInList(KKStr &str)
Definition: KKStr.cpp:4522
void ChopLastChar()
Definition: KKStr.cpp:1668
KKStr ExtractToken(const char *delStr="\n\t\r ")
Definition: KKStr.cpp:2969
KKStr DecodeQuotedStr() const
Trees this KKSr instance as a QuotedStr; decodes escape sequences such as &#39;\&#39;, &#39;&#39;, &#39; &#39;, &#39;&#39;, and &#39;\0&#39; into original characters.
Definition: KKStr.cpp:3243
KKStr operator+(kkint32 right) const
Definition: KKStr.cpp:4036
kkint32 InstancesOfChar(char ch) const
Definition: KKStr.cpp:2041
char ExtractLastChar()
Removes the last character from the string and returns it to the caller.
Definition: KKStr.cpp:3226
kkint32 LocateStr(const KKStr &searchStr) const
Returns index of 1st occurrence of &#39;searchStr&#39; otherwise -1.
Definition: KKStr.cpp:2091
kkint32 SPRINTF(char *buff, kkint32 buffSize, const char *formatSpec, kkint32 right)
Definition: KKStr.cpp:193
bool operator==(const std::string right) const
Definition: KKStr.cpp:1603
void TrimRightChar()
Definition: KKStr.cpp:1723
KKStr ToTabDelString() const
Strings will be separated by tab() characters and in order of index.
Definition: KKStr.cpp:5631
bool operator>(const KKStr &right) const
Definition: KKStr.cpp:1619
unsigned __int16 kkuint16
16 bit unsigned integer.
Definition: KKBaseTypes.h:86
KKStr operator+(float right) const
Definition: KKStr.cpp:4092
KKStr & operator=(const char *src)
Definition: KKStr.cpp:1442
kkint32 LocateLastOccurrence(const char *str, char ch)
Definition: KKStr.cpp:4791
bool EndsWith(const KKStr &value, bool ignoreCase)
Definition: KKStr.cpp:1204
kkint32 SPRINTF(char *buff, kkint32 buffSize, char const *formatSpec, double d)
Definition: KKStr.cpp:271
kkint32 SPRINTF(char *buff, kkint32 buffSize, const char *formatSpec, kkuint32 right)
Definition: KKStr.cpp:208
XmlContent * XmlContentPtr
Definition: XmlStream.h:24
kkint32 ToInt() const
Definition: KKStr.cpp:3565
kkint32 LocateLastOccurrence(const KKStr &s) const
Returns index of last occurrence of &#39;s&#39; otherwise -1.
Definition: KKStr.cpp:2151
bool operator==(const char *rtStr) const
Definition: KKStr.cpp:1588
char FirstChar() const
Definition: KKStr.cpp:1970
static void StrCapitalize(char *str)
Definition: KKStr.cpp:4375
KKStr StrFromUint32(kkuint32 ui)
Definition: KKStr.cpp:5187
KKStr ToUpper() const
Definition: KKStr.cpp:2517
static KKStr Concat(const VectorKKStr &values)
Definition: KKStr.cpp:1057
kkuint32 MaxLenSupported() const
Definition: KKStr.cpp:2510
bool operator==(const KKStrListIndexed &right)
Definition: KKStr.cpp:5462
char * STRCOPY(char *dest, kkuint16 destSize, const char *src)
Definition: KKStr.cpp:31
kkint32 SPRINTF(char *buff, kkint32 buffSize, const char *formatSpec, kkint32 precision, double d)
Definition: KKStr.cpp:255
kkint32 STRICMP(const char *left, const char *right)
Definition: KKStr.cpp:92
kkint64 ToInt64() const
Definition: KKStr.cpp:3598
static const char * Str(const char *s)
Definition: KKStr.cpp:286
std::istream &__cdecl operator>>(std::istream &is, KKStr &str)
Definition: KKStr.cpp:4287
KKStr operator+(const char *right) const
Definition: KKStr.cpp:3986
bool EqualIgnoreCase(const KKStr &s2) const
Definition: KKStr.cpp:1250
XmlToken * XmlTokenPtr
Definition: XmlStream.h:18
kkint32 CompareIgnoreCase(const std::string &s2) const
Definition: KKStr.cpp:998
KKStr operator+(kkuint64 right) const
Definition: KKStr.cpp:4078
unsigned __int32 kkuint32
Definition: KKBaseTypes.h:89
bool EndsWith(const char *value, bool ignoreCase)
Definition: KKStr.cpp:1223
KKStrPtr ToKKStrPtr() const
Definition: KKStr.cpp:2541
kkint16 ToInt16() const
Definition: KKStr.cpp:3576
bool ValidNum(double &value) const
Definition: KKStr.cpp:2653
kkint32 MemoryConsumedEstimated() const
Definition: KKStr.cpp:5454
char * STRCAT(char *dest, kkint32 destSize, const char *src)
Definition: KKStr.cpp:74
__int64 kkint64
Definition: KKBaseTypes.h:90
char operator[](kkuint32 i) const
Definition: KKStr.cpp:3430
kkint32 SearchStr(const char *src, kkint32 srcLen, kkint32 startPos, const char *srchStr, kkint32 srchStrLen)
Definition: KKStr.cpp:3907
KKStrList(const char *s[])
Definition: KKStr.cpp:4493
bool MoreTokens() const
Definition: KKStrParser.h:74
bool operator()(const KKStr &s1, const KKStr &s2)
Definition: KKStr.cpp:501
bool Contains(const char *value)
Definition: KKStr.cpp:1112
KKStr & operator=(KKStr &&src)
Definition: KKStr.cpp:1369
kkint32 Delete(KKStr &s)
Definition: KKStr.cpp:5529
bool operator!=(const char *rtStr) const
Definition: KKStr.cpp:1596
bool operator<=(const KKStr &right) const
Definition: KKStr.cpp:1642
static KKStr Concat(const char **values)
Definition: KKStr.cpp:1031
char LastChar() const
Definition: KKStr.cpp:2007
kkuint32 Len() const
Returns the number of characters in the string.
Definition: KKStr.h:366
KKStrConstPtr AttributeValueByName(const KKStr &name) const
Definition: XmlStream.cpp:658
KKStr StrFromUint16(kkuint16 ui)
Definition: KKStr.cpp:5164
static void MemSet(void *dest, kkuint8 byte, kkuint32 size)
Definition: KKStr.cpp:4362
void AddAtribute(const KKStr &attributeName, kkint32 attributeValue)
Definition: XmlStream.cpp:620
void StrReplace(char **dest, const char *src)
Replaces the contents of *dest with *src.
Definition: KKStr.cpp:456
KKStr(double d, kkint32 precision)
summary>Constructs a KKStr instance form a stl::string instance.
Definition: KKStr.cpp:617
KKTHread * KKTHreadPtr
KKStrPtr BinarySearch(const KKStr &searchStr)
Definition: KKStr.cpp:4607
KKStrListIndexed(bool _owner, bool _caseSensitive)
Definition: KKStr.cpp:5381
void Append(char ch)
Definition: KKStr.cpp:1863
char * STRCOPY(char *dest, kkint32 destSize, const char *src)
Definition: KKStr.cpp:46
KKStrParser(const KKStr &_str)
Definition: KKStrParser.cpp:42
KKStr operator+(const char *left, const KKStr &right)
Definition: KKStr.cpp:3976
kkuint32 ToUint() const
Definition: KKStr.cpp:3636
static void StrDelete(char **str)
Definition: KKStr.cpp:296
KKStr operator+(kkuint32 right) const
Definition: KKStr.cpp:4050
kkint32 AttributeValueInt32(const KKStr &attributeName) const
Definition: XmlStream.cpp:676
kkint32 SPRINTF(char *buff, kkint32 buffSize, const char *formatSpec, kkuint64 right)
Definition: KKStr.cpp:239
double ExtractTokenDouble(const char *delStr)
Definition: KKStr.cpp:3180
void Append(const char *buff)
Definition: KKStr.cpp:1783
bool ExtractTokenBool(const char *delStr)
Extract the next token from the string assuming that it is a logical True/False value.
Definition: KKStr.cpp:3165
void AppendUInt32(kkuint32 i)
Definition: KKStr.cpp:1940
KKStr(const KKStr &str)
Copy Constructor.
Definition: KKStr.cpp:561
kkint32 Compare(const std::string &s2) const
Compares with STL string.
Definition: KKStr.cpp:881
unsigned __int8 kkuint8
Definition: KKBaseTypes.h:84
void AddAtribute(const KKStr &attributeName, const KKStr &attributeValue)
Definition: XmlStream.cpp:602
char EnterStr()
Definition: KKStr.cpp:2394
KKStr Tail(kkint32 tailLen) const
Returns a string consisting of the &#39;tailLen&#39; characters from the end of the string.
Definition: KKStr.cpp:2847
KKStrList * KKStrListPtr
Definition: KKStr.h:773
void TrimLeft(const char *whiteSpaceChars="\n\r\t ")
Definition: KKStr.cpp:1745
double ToLongitude() const
Processes string as if a standard longitude; ex: "95:32.2E" = 95.53833.
Definition: KKStr.cpp:3819
bool Empty() const
Definition: KKStr.h:241
bool EqualIgnoreCase(const KKStrConstPtr s2) const
Definition: KKStr.cpp:1244
kkint32 SPRINTF(char *buff, kkint32 buffSize, const char *formatSpec, kkint16 right)
Definition: KKStr.cpp:162
XmlTag const * XmlTagConstPtr
Definition: KKStr.h:45
Manages the reading and writing of objects in a simple XML format. For a class to be supported by Xml...
Definition: XmlStream.h:46
kkint32 Find(const char *s, kkint32 pos=0) const
Definition: KKStr.cpp:3945
KKStr SubStrPart(kkint32 firstChar, kkint32 lastChar) const
returns a SubString consisting of all characters starting at index &#39;firstChar&#39; and ending at &#39;lastInd...
Definition: KKStr.cpp:2802
static KKStr Spaces(kkint32 c)
Returns a string of spaces &#39;c&#39; characters long.
Definition: KKStr.cpp:4329
static kkint32 CompareStrings(const KKStr &s1, const KKStr &s2)
Compares to Strings and returns -1, 0, or 1, indicating if less than, equal, or greater.
Definition: KKStr.cpp:4714
bool operator()(KKStrPtr p1, KKStrPtr p2)
Definition: KKStr.cpp:4749
kkint32 ToInt32() const
Definition: KKStr.cpp:3587
unsigned char uchar
Unsigned character.
Definition: KKBaseTypes.h:77
KKStr StrFromDouble(double d)
Definition: KKStr.cpp:5229
bool StrInStr(const KKStr &searchField) const
Searches for the occurrence of &#39;searchField&#39; and where in the string. If found will return &#39;true&#39; oth...
Definition: KKStr.cpp:2731
bool EndsWith(const char *value)
Definition: KKStr.cpp:1197
#define EnterChar
Definition: KKStr.h:30
kkint32 MemoryConsumedEstimated() const
Definition: KKStr.cpp:4511
static KKStr Concat(const std::vector< std::string > &values)
Concatenates the list of &#39;std::string&#39; strings.
Definition: KKStr.cpp:1082
bool Contains(const KKStr &value)
Definition: KKStr.cpp:1103
void Upper()
Converts all characters in string to their Upper case equivalents via &#39;toupper&#39;.
Definition: KKStr.cpp:2461
kkint32 LocateLastOccurrence(char ch) const
Returns index of last occurrence of &#39;ch&#39; otherwise -1.
Definition: KKStr.cpp:2118
static kkint32 StrCompareIgnoreCase(const char *s1, const char *s2)
Definition: KKStr.cpp:318
std::vector< kkint32 > VectorInt32
Vector of signed 32 bit integers.
Definition: KKBaseTypes.h:144
void ReadXML(XmlStream &s, XmlTagConstPtr tag, VolConstBool &cancelFlag, RunLog &log)
Definition: KKStr.cpp:5595
static bool StrEqualN(const char *s1, const char *s2, kkuint32 len)
Definition: KKStr.cpp:388
KKStr(const char *src, kkuint32 startPos, kkuint32 endPos)
Constructs a KKStr instance from a sub-string of &#39;src&#39;.
Definition: KKStr.cpp:693
kkint32 LocateCharacter(char ch) const
Returns index of 1st occurrence of &#39;ch&#39; otherwise -1.
Definition: KKStr.cpp:2021
static const KKStr & EmptyStr()
Static method that returns an Empty String.
Definition: KKStr.cpp:3453
kkint32 STRNICMP(const char *left, const char *right, kkint32 len)
Definition: KKStr.cpp:126
unsigned long ulong
Unsigned long.
Definition: KKBaseTypes.h:80
kkint32 LookUp(KKStrPtr s) const
Definition: KKStr.cpp:5572
void ReadXML(XmlStream &s, XmlTagConstPtr tag, VolConstBool &cancelFlag, RunLog &log)
Definition: KKStr.cpp:4537
bool StartsWith(const char *value) const
Definition: KKStr.cpp:1144
KKStr ExtractQuotedStr(const char *delChars, bool decodeEscapeCharacters)
Definition: KKStr.cpp:3282
void Test2(ostream &x1, const char *x2)
Definition: KKStr.cpp:4268
bool operator!=(const KKStr &right) const
Definition: KKStr.cpp:1558
long ToLong() const
Definition: KKStr.cpp:3611
char ExtractChar()
Removes the first character from the string and returns it to the caller.
Definition: KKStr.cpp:3197
void Sort(bool _reversedOrder)
Definition: KKStr.cpp:4770
void WriteXML(const KKStr &varName, std::ostream &o) const
Definition: KKStr.cpp:5319
bool EndsWith(const KKStr &value)
Definition: KKStr.cpp:1190
bool operator==(const KKStr &right) const
Definition: KKStr.cpp:1550
unsigned __int64 kkuint64
Definition: KKBaseTypes.h:91
void AddString(KKStrPtr str)
Definition: KKStr.cpp:4651
kkint32 Find(const char *s, kkint32 pos, kkint32 n) const
Definition: KKStr.cpp:3938
bool StartsWith(const char *value, bool ignoreCase) const
Definition: KKStr.cpp:1169
KKStr StrFormatInt(kkint32 val, const char *mask)
Definition: KKStr.cpp:5004
KKStr(const char *str)
Definition: KKStr.cpp:537
void WriteXML(const KKStr &varName, std::ostream &o) const
Definition: KKStr.cpp:4420
double ToDouble() const
Definition: KKStr.cpp:3541
std::ostream &__cdecl operator<<(std::ostream &os, const KKStr &str)
kkint32 ExtractTokenInt(const char *delStr)
Definition: KKStr.cpp:3129
KKStr operator+(const KKStr &right) const
Definition: KKStr.cpp:3998
kkuint64 ExtractTokenUint64(const char *delStr)
Definition: KKStr.cpp:3153
bool StartsWith(const KKStr &value, bool ignoreCase) const
Definition: KKStr.cpp:1150
kkint32 Find(const KKStr &str, kkint32 pos=0) const
Will return the position where the 1st instance of &#39;str&#39; after &#39;pos&#39; occurs or -1 if not found...
Definition: KKStr.cpp:3931
#define EscapeChar
Definition: KKStr.h:31
wchar_t * StrWide() const
Definition: KKStr.cpp:1264
KKStr operator+(kkint16 right) const
Definition: KKStr.cpp:4010
static bool StrEqualNoCaseN(const char *s1, const char *s2, kkuint32 len)
Definition: KKStr.cpp:436
const char * Str() const
Returns a pointer to a ascii string.
Definition: KKStr.h:422
KKStr MaxLen(kkuint32 maxLen) const
Definition: KKStr.cpp:2499
void Append(const std::string &str)
Definition: KKStr.cpp:1894
KKStr StrFormatDouble(double val, const char *mask)
Definition: KKStr.cpp:4819
void RightPad(kkint32 width, char ch= ' ')
Pads string on the right side with specified character so that the string will be of specified length...
Definition: KKStr.cpp:2239
kkint32 LocateNthOccurrence(char ch, kkint32 x) const
Definition: KKStr.cpp:2179
void ChopFirstChar()
Definition: KKStr.cpp:1649
KKStr & operator=(kkint32 right)
Definition: KKStr.cpp:1478
bool operator!=(const std::string right) const
Definition: KKStr.cpp:1611
KKStr ToXmlStr() const
Definition: KKStr.cpp:2929
double ToLatitude() const
Processes string as if a standard latitude; ex: "15:32.2S" = -15.53833.
Definition: KKStr.cpp:3725
ulong ToUlong() const
Definition: KKStr.cpp:3644
KKStr operator+(kkint64 right) const
Definition: KKStr.cpp:4064
static void WriteXml(const KKStr &s, std::ostream &o)
Definition: XmlStream.cpp:853
KKStrList(bool owner)
Definition: KKStr.cpp:4485
static const char * StrChr(const char *str, int ch)
Definition: KKStr.cpp:308
void Append(const KKStr &str)
Definition: KKStr.cpp:1887
KKException(const char *_exceptionStr)
Definition: KKException.cpp:38
char operator[](kkint32 i) const
Definition: KKStr.cpp:3413
void WriteXML(std::ostream &o)
Definition: XmlStream.cpp:723
static void MemCpy(void *dest, void *src, kkuint32 size)
Definition: KKStr.cpp:4338
KKStr operator+(double right) const
Definition: KKStr.cpp:4107
KKStr & operator=(const KKStr &src)
Definition: KKStr.cpp:1390
bool operator==(KKStrConstPtr right) const
Definition: KKStr.cpp:1566
KKStrPtr const Content() const
Definition: XmlStream.h:338
Used for logging messages.
Definition: RunLog.h:49
kkint32 LookUp(const KKStr &s) const
Definition: KKStr.cpp:5558
bool operator<(const KKStr &right) const
Definition: KKStr.cpp:1635
bool StartsWith(const KKStr &value) const
Definition: KKStr.cpp:1137
KKStr StrFromInt16(kkint16 i)
Definition: KKStr.cpp:5152
float ToPercentage() const
Definition: KKStr.cpp:3623
KKStrListIndexed(const KKStrListIndexed &list)
Definition: KKStr.cpp:5397
virtual TokenTypes TokenType()=0
Class that manages the extraction of tokens from a String without being destructive to the original s...
Definition: KKStrParser.h:18
void FreeUpUnUsedSpace()
Definition: KKStr.cpp:1980
kkint32 Compare(const KKStr &s2) const
Definition: KKStr.cpp:844
void WriteXML(const KKStr &varName, std::ostream &o) const
Definition: KKStr.cpp:4577
static KKStrListPtr ParseDelimitedString(const KKStr &str, const char *delChars=",\t\n\r")
Definition: KKStr.cpp:4659
float ToFloat() const
Definition: KKStr.cpp:3553
virtual XmlTokenPtr GetNextToken(VolConstBool &cancelFlag, RunLog &log)
Definition: XmlStream.cpp:116
void ReadXML(XmlStream &s, XmlTagConstPtr tag, VolConstBool &cancelFlag, RunLog &log)
Definition: KKStr.cpp:5277
bool operator!=(const KKStrListIndexed &right)
Definition: KKStr.cpp:5499
kkint32 SPRINTF(char *buff, kkint32 buffSize, const char *formatSpec, kkint64 right)
Definition: KKStr.cpp:223
VectorKKStr Split(char del) const
Splits the string up into tokens using &#39;del&#39; as the separator returning them in a vector...
Definition: KKStr.cpp:3500
KKException(const KKStr &_exceptionStr)
Definition: KKException.cpp:45
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
void LopOff(kkint32 lastCharPos)
Trims off all characters after the &#39;lastCharPos&#39; index; to make an empty string you would have to spe...
Definition: KKStr.cpp:2866
bool ValidInt(kkint32 &value)
Definition: KKStr.cpp:2548
VectorInt32 * ToVectorInt32() const
Definition: KKStr.cpp:3671
kkuint32 size() const
Definition: KKStr.cpp:5447
void WriteXML(const KKStr &varName, std::ostream &o) const
Definition: KKStr.cpp:5645
kkuint64 ToUint64() const
Definition: KKStr.cpp:3660
KKStr StrFromUint64(kkuint64 ui)
Definition: KKStr.cpp:5209
KKStr SubStrPart(kkint32 firstChar) const
returns a SubString consisting of all characters starting at index &#39;firstChar&#39; until the end of the s...
Definition: KKStr.cpp:2780
kkint32 CompareIgnoreCase(const char *s2) const
summary>Compares to Strings and returns -1, 0, or 1, indicating if less than, equal, or greater.
Definition: KKStr.cpp:955
char operator[](kkuint16 i) const
Definition: KKStr.cpp:3396
KKStrParser(const char *_str)
Definition: KKStrParser.cpp:54
bool ValidMoney(float &value) const
Definition: KKStr.cpp:2594
bool operator!=(KKStrConstPtr right) const
Definition: KKStr.cpp:1577
KKStr QuotedStr() const
Returns a quoted version of string where special characters Line-Feed, Carriage Return, and Tab, are encoded as escape sequences.
Definition: KKStr.cpp:2890
VectorKKStr(const VectorKKStr &v)
Definition: KKStr.cpp:5270
KKStr ToLower() const
Definition: KKStr.cpp:2529
KKStr StrFromInt32(kkint32 i)
Definition: KKStr.cpp:5175
KKStr operator+(const char left, const KKStr &right)
Definition: KKStr.cpp:3964
volatile const bool VolConstBool
Definition: KKBaseTypes.h:163
static bool StrInStr(const char *target, const char *searchStr)
Definition: KKStr.cpp:4391
KKStrListPtr DuplicateListAndContents() const
Definition: KKStr.cpp:4779