Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
StrT.h
Go to the documentation of this file.
1 //
4 //
5 
6 #ifndef _INC_StrT_H
7 #define _INC_StrT_H
8 #ifndef NO_PRAGMA_ONCE
9 #pragma once
10 #endif
11 
12 #include "StrChar.h"
13 #include "StrConst.h"
14 #include "StrNum.h"
15 #include "StrU.h"
16 #include "StrFormat.h"
17 #include "cValT.h"
18 #include "cHeap.h"
19 #include "cUnitTestDecl.h"
20 #include "cDebugAssert.h" // ASSERT
21 
22 namespace Gray
23 {
24  class cLogProcessor;
25 
27  {
31 
33 
34  // Symmetric
36  // DO %X% percent pairs. ala DOS batch scripts for environment variables.
37 
38  // Asymmetric
42 
43  // DO <?X?> XML/HTML type blocks ? use StrT::ReplaceX()
45  };
46  typedef UINT32 STR_BLOCKS_t;
47 
49  {
54  STRP_SPACE_SEP = 0x02,
55  STRP_END_WHITE = 0x04,
57  STRP_DEF = 0x0F,
58 
59  STRP_MERGE_CRNL = 0x10,
60  STRP_EMPTY_SKIP = 0x20,
61  STRP_EMPTY_STOP = 0x40,
62  STRP_ALL = 0x7F,
63  };
64  typedef UINT32 STRP_MASK_t;
65 
66  //*****************************************************************************
67 
68  struct GRAYCORE_LINK StrT // static //!< namespace for string templates for UTF8 and UNICODE
69  {
74 
75  static const StrLen_t k_LEN_MAX = 15000;
76  static const StrLen_t k_LEN_MAX_KEY = 128;
77 
78 #define STR_NL "\n"
79 #define STR_CRLF "\r\n"
80 
81  static const char k_szBlockStart[STR_BLOCK_QTY + 1];
82  static const char k_szBlockEnd[STR_BLOCK_QTY + 1];
83 
84  static const char k_szEscEncode[12];
85  static const char k_szEscDecode[12];
86 
87  // NON modifying methods first.
88 
89  template< typename TYPE >
90  static StrLen_t Len(const TYPE* pszStr) NOEXCEPT;
91 
92  template< typename TYPE >
93  static inline const TYPE* Cast(const TYPE* pszStr)
94  {
98  return pszStr;
99  }
100 
101  template< typename TYPE >
102  static inline bool IsNullOrEmpty(const TYPE* pszStr) NOEXCEPT
103  {
105  if (pszStr == nullptr)
106  return true;
107  if (pszStr[0] == '\0')
108  return true;
109  return false;
110  }
111 
112  template< typename TYPE >
113  static inline const TYPE* CheckEmpty(const TYPE* pszStr) NOEXCEPT
114  {
116  if (pszStr == nullptr)
117  return nullptr;
118  if (pszStr[0] == '\0')
119  return nullptr;
120  return pszStr;
121  }
122 
123  template< typename TYPE >
124  static StrLen_t Len(const TYPE* pszStr, StrLen_t iLenMax) NOEXCEPT
125  {
128  if (pszStr == nullptr)
129  return 0;
130  StrLen_t i = 0;
131  for (; i < iLenMax && pszStr[i] != '\0'; i++)
132  {
133  }
134  return i;
135  }
136 
137  template< typename TYPE >
138  static StrLen_t inline Diff(const TYPE* pszEnd, const TYPE* pszStart)
139  {
141  ASSERT(pszEnd != nullptr);
142  ASSERT(pszStart != nullptr);
143  INT_PTR i = (pszEnd - pszStart); // ptrdiff_t
144  ASSERT(i > -(INT_PTR)(cHeap::k_ALLOC_MAX) && i < (INT_PTR)(cHeap::k_ALLOC_MAX)); // k_ALLOC_MAX
145  return (StrLen_t)i;
146  }
147 
148  template< typename TYPE >
149  GRAYCORE_LINK static COMPARE_t GRAYCALL Cmp(const TYPE* pszStr1, const TYPE* pszStr2);
150  template< typename TYPE >
151  GRAYCORE_LINK static COMPARE_t GRAYCALL CmpN(const TYPE* pszStr1, const TYPE* pszStr2, StrLen_t iLenMaxChars) NOEXCEPT;
152  template< typename TYPE >
153  GRAYCORE_LINK static COMPARE_t GRAYCALL CmpI(const TYPE* pszStr1, const TYPE* pszStr2);
154  template< typename TYPE >
155  GRAYCORE_LINK static COMPARE_t GRAYCALL CmpIN(const TYPE* pszStr1, const TYPE* pszStr2, StrLen_t iLenMaxChars) NOEXCEPT;
156  template< typename TYPE >
157  GRAYCORE_LINK static COMPARE_t GRAYCALL CmpHeadI(const TYPE* pszFind, const TYPE* pszTableElem);
158  template< typename TYPE >
159  GRAYCORE_LINK static bool GRAYCALL StartsWithI(const TYPE* pszStr2, const TYPE* pszPrefix);
160  template< typename TYPE >
161  GRAYCORE_LINK static bool GRAYCALL EndsWithI(const TYPE* pszStr2, const TYPE* pszPostfix, StrLen_t nLenStr = k_StrLen_UNK);
162 
163  template< typename TYPE >
165  template< typename TYPE >
167  template< typename TYPE >
169  template< typename TYPE >
170  static bool HasChar(const TYPE* pszStr, TYPE ch) NOEXCEPT
171  {
172  return FindCharN(pszStr, ch) >= 0;
173  }
174  template< typename TYPE >
175  GRAYCORE_LINK static TYPE* GRAYCALL FindCharRev(const TYPE* pszStr, TYPE ch, StrLen_t iLen = k_StrLen_UNK);
176  template< typename TYPE >
177  GRAYCORE_LINK static TYPE* GRAYCALL FindTokens(const TYPE* pszStr, const TYPE* pszTokens, StrLen_t iLenMax = StrT::k_LEN_MAX);
178 
179  template< typename TYPE >
180  GRAYCORE_LINK static TYPE* GRAYCALL FindStr(const TYPE* pszStr, const TYPE* pszFind, StrLen_t iLenMax = StrT::k_LEN_MAX);
181  template< typename TYPE >
182  GRAYCORE_LINK static TYPE* GRAYCALL FindStrI(const TYPE* pszStr, const TYPE* pszFind, StrLen_t iLenMax = StrT::k_LEN_MAX);
183  template< typename TYPE >
184  GRAYCORE_LINK static StrLen_t GRAYCALL FindWord(const TYPE* pTextSearch, const TYPE* pszKeyWord, StrLen_t iLenMax = StrT::k_LEN_MAX);
185 
186  template< typename TYPE>
188  {
190  if (pStr == nullptr)
191  return 0;
192  StrLen_t i = 0;
193  while (i < iLenMax && StrChar::IsSpace(pStr[i]))
194  i++;
195  return i;
196  }
197  template< typename TYPE>
198  static const TYPE* GetNonWhitespace(const TYPE* pStr, StrLen_t iLenMax = StrT::k_LEN_MAX) NOEXCEPT
199  {
200  // never return nullptr unless pStr = nullptr
201  return(pStr + GetNonWhitespaceI(pStr, iLenMax));
202  }
203  template< typename TYPE>
205  {
206  return(pStr + GetNonWhitespaceI(pStr, iLenMax));
207  }
208  template< typename TYPE >
210  template< typename TYPE >
211  GRAYCORE_LINK static bool GRAYCALL IsWhitespace(const TYPE* pStr, StrLen_t iLenChars = StrT::k_LEN_MAX);
212 
213  template< typename TYPE >
214  GRAYCORE_LINK static bool GRAYCALL IsPrintable(const TYPE* pStr, StrLen_t iLenChars = StrT::k_LEN_MAX);
215 
216  // String searching. const
217  template< typename TYPE >
218  GRAYCORE_LINK static ITERATE_t GRAYCALL TableFind(const TYPE* pszFindThis, const void* ppszTableInit, size_t nElemSize = sizeof(const TYPE*));
219  template< typename TYPE >
220  GRAYCORE_LINK static ITERATE_t GRAYCALL TableFindHead(const TYPE* pszFindHead, const void* ppszTableInit, size_t nElemSize = sizeof(const TYPE*));
221  template< typename TYPE >
222  GRAYCORE_LINK static ITERATE_t GRAYCALL TableFindSorted(const TYPE* pszFindThis, const void* ppszTableInit, ITERATE_t iCountMax, size_t nElemSize = sizeof(const TYPE*));
223  template< typename TYPE >
224  GRAYCORE_LINK static ITERATE_t GRAYCALL TableFindHeadSorted(const TYPE* pszFindHead, const void* ppszTableInit, ITERATE_t iCountMax, size_t nElemSize = sizeof(const TYPE*));
225 
226 #define STR_TABLEFIND_N(k,t) StrT::TableFind( k, t, sizeof(t[0]))
227 #define STR_TABLEFIND_NH(k,t) StrT::TableFindHead( k, t, sizeof(t[0]))
228 #define STR_TABLEFIND_S(k,t) StrT::TableFindSorted( k, t, _countof(t)-1, sizeof(t[0]))
229 #define STR_TABLEFIND_SH(k,t) StrT::TableFindHeadSorted( k, t, _countof(t)-1, sizeof(t[0]))
230 
231  // simple string regular expression pattern matching. i.e. *? Wildcards.
232  template< typename TYPE >
233  GRAYCORE_LINK static StrLen_t GRAYCALL MatchRegEx(const TYPE* pText, const TYPE* pRegExPattern, bool bIgnoreCase, StrLen_t nTextMax = k_StrLen_UNK);
234 
235  //**********************************************************************
236  // String modifying.
237 
238  template< typename TYPE >
239  GRAYCORE_LINK static StrLen_t GRAYCALL CopyLen(TYPE* pszDst, const TYPE* pSrc, StrLen_t iLenCharsMax) NOEXCEPT;
240 
241  template< typename TYPE >
242  static void MakeUpperCase(TYPE* pszDst, StrLen_t iLenCharsMax) NOEXCEPT
243  {
246  if (pszDst == nullptr)
247  return;
248  StrLen_t i = 0;
249  for (; pszDst[i] != '\0' && i < iLenCharsMax; i++)
250  {
251  pszDst[i] = (TYPE)StrChar::ToUpperA(pszDst[i]);
252  }
253  }
254  template< typename TYPE >
255  static void MakeLowerCase(TYPE* pszDst, StrLen_t iLenCharsMax) NOEXCEPT
256  {
259  if (pszDst == nullptr)
260  return;
261  StrLen_t i = 0;
262  for (; pszDst[i] != '\0' && i < iLenCharsMax; i++)
263  {
264  pszDst[i] = (TYPE)StrChar::ToLowerA(pszDst[i]);
265  }
266  }
267 
268  // like _vsntprintf
269  template< typename TYPE >
270  static StrLen_t vsprintfN(OUT TYPE* pszOut, StrLen_t iLenOutMax, const TYPE* pszFormat, va_list vlist);
271 
272  template< typename TYPE >
273  static StrLen_t _cdecl sprintfN(OUT TYPE* pszOut, StrLen_t iLenOutMax, const TYPE* pszFormat, ...)
274  {
280  va_list vargs;
281  va_start(vargs, pszFormat);
282  StrLen_t nLenRet = StrT::vsprintfN(pszOut, iLenOutMax, pszFormat, vargs);
283  va_end(vargs);
284  return nLenRet;
285  }
286 
287  template< typename TYPE >
288  GRAYCORE_LINK static TYPE* GRAYCALL FindBlockEnd(STR_BLOCK_TYPE eBlockType, const TYPE* pLine, StrLen_t iLenMax = StrT::k_LEN_MAX);
289  template< typename TYPE>
291 
292  template< typename TYPE >
293  GRAYCORE_LINK static StrLen_t GRAYCALL EscSeqRemove(TYPE* pStrOut, const TYPE* pStrIn, StrLen_t iLenOutMax = StrT::k_LEN_MAX, StrLen_t iLenInMax = StrT::k_LEN_MAX);
294  template< typename TYPE >
295  GRAYCORE_LINK static StrLen_t GRAYCALL EscSeqRemoveQ(TYPE* pStrOut, const TYPE* pStrIn, StrLen_t iLenOutMax = StrT::k_LEN_MAX, StrLen_t iLenInMax = StrT::k_LEN_MAX);
296 
297  template< typename TYPE >
298  GRAYCORE_LINK static StrLen_t GRAYCALL EscSeqAdd(TYPE* pStrOut, const TYPE* pStrIn, StrLen_t iLenOutMax = StrT::k_LEN_MAX);
299  template< typename TYPE >
300  GRAYCORE_LINK static StrLen_t GRAYCALL EscSeqAddQ(TYPE* pStrOut, const TYPE* pStrIn, StrLen_t iLenOutMax = StrT::k_LEN_MAX);
301 
302  template< typename TYPE >
304  template< typename TYPE >
306 
307  template< typename TYPE >
308  GRAYCORE_LINK static StrLen_t GRAYCALL ReplaceX(TYPE* pDst, StrLen_t iDstLenMax, StrLen_t nDstIdx, StrLen_t iDstSegLen, const TYPE* pSrc, StrLen_t iSrcLen = k_StrLen_UNK);
309 
310  template< typename TYPE >
311  GRAYCORE_LINK static ITERATE_t GRAYCALL ParseCmds(TYPE* pszCmdLine, StrLen_t nCmdLenMax, TYPE** ppCmds, ITERATE_t iQtyMax, const TYPE* pszSep = nullptr, STRP_MASK_t uFlags = STRP_DEF);
312  template< typename TYPE >
313  GRAYCORE_LINK static ITERATE_t GRAYCALL ParseCmdsTmp(TYPE* pszTmp, StrLen_t iTmpSizeMax, const TYPE* pszCmdLine, TYPE** ppCmds, ITERATE_t iCmdQtyMax, const TYPE* pszSep = nullptr, STRP_MASK_t uFlags = STRP_DEF);
314 
315  //**********************************************************************
316  // Numerics
317 
318  // string to numeric. similar to strtoul()
319  template< typename TYPE >
320  GRAYCORE_LINK static UINT64 GRAYCALL toUL(const TYPE* pszStr, const TYPE** ppszStrEnd = /*(const TYPE**)*/nullptr, RADIX_t nBaseRadix = 0);
321  template< typename TYPE >
322  GRAYCORE_LINK static INT64 GRAYCALL toIL(const TYPE* pszStr, const TYPE** ppszStrEnd = /*(const TYPE**)*/nullptr, RADIX_t nBaseRadix = 10);
323 
324  template< typename TYPE >
325  static UINT_PTR toUP(const TYPE* pszStr, const TYPE** ppszStrEnd = /*(const TYPE**)*/nullptr, RADIX_t nBaseRadix = 0)
326  {
327  // UINT_PTR
328  return (UINT_PTR)toUL(pszStr, ppszStrEnd, nBaseRadix);
329  }
330  template< typename TYPE >
331  static INT_PTR toIP(const TYPE* pszStr, const TYPE** ppszStrEnd = /*(const TYPE**)*/nullptr, RADIX_t nBaseRadix = 10)
332  {
333  // INT_PTR
334  return (INT_PTR)toIL(pszStr, ppszStrEnd, nBaseRadix);
335  }
336 
337  template< typename TYPE >
338  static UINT toU(const TYPE* pszStr, const TYPE** ppszStrEnd = /*(const TYPE**)*/nullptr, RADIX_t nBaseRadix = 0)
339  {
341  return (UINT)toUL(pszStr, ppszStrEnd, nBaseRadix);
342  }
343  template< typename TYPE >
344  static int toI(const TYPE* pszStr, const TYPE** ppszStrEnd = /*(const TYPE**)*/nullptr, RADIX_t nBaseRadix = 10)
345  {
348  return (int)toIL(pszStr, ppszStrEnd, nBaseRadix);
349  }
350 
351  // numeric to string
352  template< typename TYPE>
353  GRAYCORE_LINK static TYPE* GRAYCALL ULtoA2(UINT64 uVal, TYPE* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix = 10, char chRadixA = 'A');
354  template< typename TYPE >
355  GRAYCORE_LINK static StrLen_t GRAYCALL ULtoA(UINT64 nVal, TYPE* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix = 10);
356  template< typename TYPE >
357  GRAYCORE_LINK static StrLen_t GRAYCALL ILtoA(INT64 nVal, OUT TYPE* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix = 10);
358 
359  template< typename TYPE>
360  GRAYCORE_LINK static StrLen_t GRAYCALL ULtoAK(UINT64 uVal, OUT TYPE* pszStr, StrLen_t iStrMax, UINT nKUnit = 1024, bool bSpace = true);
361 
362  template< typename TYPE >
363  static StrLen_t UtoA(UINT32 nVal, OUT TYPE* pszOut, StrLen_t iStrMax, RADIX_t nBaseRadix = 10)
364  {
368  return ULtoA(nVal, pszOut, iStrMax, nBaseRadix); // convert 32 bit up to 64 bit.
369  }
370  template< typename TYPE >
371  static StrLen_t ItoA(INT32 nVal, OUT TYPE* pszOut, StrLen_t iStrMax, RADIX_t nBaseRadix = 10)
372  {
377  return ILtoA(nVal, pszOut, iStrMax, nBaseRadix); // convert 32 bit up to 64 bit.
378  }
379 
380  // Floats/Doubles
381  template< typename TYPE>
382  GRAYCORE_LINK static double GRAYCALL toDouble(const TYPE* pszStr, const TYPE** ppszStrEnd = /*(const TYPE**)*/ nullptr);
383  template< typename TYPE >
384  GRAYCORE_LINK static StrLen_t GRAYCALL DtoA(double nVal, OUT TYPE* pszOut, StrLen_t iStrMax, int iDecPlaces = -1, char chE = -'e');
385 
387  };
388 
389  template< typename TYPE = char >
390  struct GRAYCORE_LINK StrX : public StrT // static
391  {
395 
396  static const TYPE* GRAYCALL GetBoolStr(bool bVal) NOEXCEPT;
397 
398  // String searching. const
399  static inline const TYPE* GetTableElemU(const void* ppszTableInit, ITERATE_t i, size_t nSizeElem)
400  {
403  ASSERT(ppszTableInit != nullptr);
404  return *((const TYPE* const*)(((const BYTE*)ppszTableInit) + (i * nSizeElem)));
405  }
406 
407  static const TYPE* GRAYCALL GetTableElem(ITERATE_t iEnumVal, const void* ppszTableInit, ITERATE_t iCountMax, size_t nElemSize = sizeof(const TYPE*));
408 
409  static ITERATE_t GRAYCALL GetTableCount(const void* ppszTableInit, size_t nElemSize);
410  static ITERATE_t GRAYCALL GetTableCountSorted(const void* ppszTableInit, size_t nElemSize);
411  };
412 
413  // Override implementations
414 
415  template<> StrLen_t inline StrT::Len<char>(const char* pszStr) NOEXCEPT // count of chars NOT same as bytes (size_t)
416  {
420 #if USE_CRT
421  if (pszStr == nullptr)
422  return 0;
423  return (StrLen_t) ::strlen(pszStr);
424 #else
425  return Len(pszStr, k_LEN_MAX);
426 #endif
427  }
428  template<> StrLen_t inline StrT::Len<wchar_t>(const wchar_t* pszStr) NOEXCEPT
429  {
433 #if USE_CRT
434  if (pszStr == nullptr)
435  return 0;
436  return (StrLen_t) ::wcslen(pszStr);
437 #else
438  return Len(pszStr, k_LEN_MAX);
439 #endif
440  }
441 
442  template<> inline UINT64 StrT::toUL<char>(const char* pszStr, const char** ppszStrEnd, RADIX_t nBaseRadix)
443  {
444  return StrNum::toUL(pszStr, ppszStrEnd, nBaseRadix);
445  }
446  template<> inline UINT64 StrT::toUL<wchar_t>(const wchar_t* pszStr, const wchar_t** ppszStrEnd, RADIX_t nBaseRadix)
447  {
448  char szTmp[StrNum::k_LEN_MAX_DIGITS_INT + 4];
450  const char* ppszStrEndA = nullptr;
451  const UINT64 nVal = StrNum::toUL(szTmp, &ppszStrEndA, nBaseRadix);
452  if (ppszStrEnd != nullptr)
453  {
454  *ppszStrEnd = pszStr + StrT::Diff(ppszStrEndA, szTmp);
455  }
456  return nVal;
457  }
458 
459  template<> inline INT64 StrT::toIL<char>(const char* pszStr, const char** ppszStrEnd, RADIX_t nBaseRadix)
460  {
461  return StrNum::toIL(pszStr, ppszStrEnd, nBaseRadix);
462  }
463  template<> inline INT64 StrT::toIL<wchar_t>(const wchar_t* pszStr, const wchar_t** ppszStrEnd, RADIX_t nBaseRadix)
464  {
465  char szTmp[StrNum::k_LEN_MAX_DIGITS_INT + 4];
467  const char* ppszStrEndA;
468  INT64 nVal = StrNum::toIL(szTmp, &ppszStrEndA, nBaseRadix);
469  if (ppszStrEnd != nullptr)
470  {
471  *ppszStrEnd = pszStr + StrT::Diff(ppszStrEndA, szTmp);
472  }
473  return nVal;
474  }
475 
476  template<> inline double StrT::toDouble<char>(const char* pszStr, const char** ppszStrEnd) // static
477  {
478 #if 1
479  if (pszStr == nullptr)
480  return 0;
481  return ::strtod(pszStr, (char**)ppszStrEnd); // const_cast
482 #else
483  return StrNum::toDouble(pszStr, ppszStrEnd);
484 #endif
485  }
486  template<> inline double StrT::toDouble<wchar_t>(const wchar_t* pszStr, const wchar_t** ppszStrEnd) // static
487  {
488 #if 1
489  if (pszStr == nullptr)
490  return 0;
491  return ::wcstod(pszStr, (wchar_t**)ppszStrEnd); // const_cast
492 #else
493  // Convert to char string first.
494  char szTmp[StrNum::k_LEN_MAX_DIGITS + 4];
496  const char* ppszStrEndA;
497  double nVal = StrNum::toDouble(szTmp, &ppszStrEndA);
498  if (ppszStrEnd != nullptr)
499  {
500  *ppszStrEnd = pszStr + StrT::Diff(ppszStrEndA, szTmp);
501  }
502  return nVal;
503 #endif
504  }
505 
506  template<> inline char* StrT::ULtoA2<char>(UINT64 uVal, char* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix, char chRadixA) // static
507  {
508  return StrNum::ULtoA2(uVal, pszOut, iOutMax, nBaseRadix, chRadixA);
509  }
510  template<> inline wchar_t* StrT::ULtoA2<wchar_t>(UINT64 uVal, wchar_t* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix, char chRadixA) // static
511  {
512  char szTmp[StrNum::k_LEN_MAX_DIGITS_INT];
513  char* pszRetA = StrNum::ULtoA2(uVal, szTmp, STRMAX(szTmp), nBaseRadix, chRadixA);
514  StrLen_t iLenInc = StrT::Diff(szTmp + STRMAX(szTmp), pszRetA);
515  if (iLenInc > iOutMax)
516  iLenInc = iOutMax;
517  pszOut += (iOutMax - iLenInc);
518  StrU::UTF8toUNICODE(pszOut, iLenInc, pszRetA, iLenInc);
519  return pszOut;
520  }
521 
522  template<> inline StrLen_t StrT::ULtoA<char>(UINT64 uVal, char* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix) // static
523  {
524  return StrNum::ULtoA(uVal, pszOut, iOutMax, nBaseRadix);
525  }
526  template<> inline StrLen_t StrT::ULtoA<wchar_t>(UINT64 uVal, wchar_t* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix) // static
527  {
528  char szTmp[StrNum::k_LEN_MAX_DIGITS_INT];
529  StrLen_t iStrLen = StrNum::ULtoA(uVal, szTmp, _countof(szTmp), nBaseRadix);
530  return StrU::UTF8toUNICODE(pszOut, iOutMax, szTmp, iStrLen);
531  }
532  template<> inline StrLen_t StrT::ILtoA<char>(INT64 uVal, char* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix) // static
533  {
534  return StrNum::ILtoA(uVal, pszOut, iOutMax, nBaseRadix);
535  }
536  template<> inline StrLen_t StrT::ILtoA<wchar_t>(INT64 uVal, wchar_t* pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix) // static
537  {
538  char szTmp[StrNum::k_LEN_MAX_DIGITS_INT];
539  StrLen_t iStrLen = StrNum::ILtoA(uVal, szTmp, _countof(szTmp), nBaseRadix);
540  return StrU::UTF8toUNICODE(pszOut, iOutMax, szTmp, iStrLen);
541  }
542 
543  template<> inline StrLen_t StrT::DtoA<char>(double nVal, OUT char* pszOut, StrLen_t iStrMax, int iDecPlaces, char chE) // static
544  {
545 #if 0
546  return StrNum::DToATestLegacy(nVal, pszOut, iStrMax, iDecPlaces);
547 #else
548  return StrNum::DtoAG(nVal, pszOut, iStrMax, iDecPlaces, chE);
549 #endif
550  }
551 
552  template<> inline StrLen_t StrT::DtoA<wchar_t>(double nVal, OUT wchar_t* pszOut, StrLen_t iOutMax, int iDecPlaces, char chE) // static
553  {
554  char szTmp[StrNum::k_LEN_MAX_DIGITS + 4];
555 #if 0
556  StrLen_t iStrLen = StrNum::DToATestLegacy(nVal, szTmp, _countof(szTmp), iDecPlaces);
557 #else
558  StrLen_t iStrLen = StrNum::DtoAG2(nVal, szTmp, iDecPlaces, chE);
559 #endif
560  return StrU::UTF8toUNICODE(pszOut, iOutMax, szTmp, iStrLen);
561  }
562 
563 
564  template<> inline StrLen_t StrT::ULtoAK<char>(UINT64 uVal, OUT char* pszOut, StrLen_t iStrMax, UINT nKUnit, bool bSpace) // static
565  {
566  return StrNum::ULtoAK(uVal, pszOut, iStrMax, nKUnit, bSpace);
567  }
568 
569  template<> inline StrLen_t StrT::ULtoAK<wchar_t>(UINT64 uVal, OUT wchar_t* pszOut, StrLen_t iStrMax, UINT nKUnit, bool bSpace) // static
570  {
571  char szTmp[StrNum::k_LEN_MAX_DIGITS + 4];
572  StrLen_t iStrLen = StrNum::ULtoAK(uVal, szTmp, _countof(szTmp), nKUnit, bSpace);
573  return StrU::UTF8toUNICODE(pszOut, iStrMax, szTmp, iStrLen);
574  }
575 
576 #if 1 // use the C lib. else StrFormat
577  template<> StrLen_t inline StrT::vsprintfN<char>(OUT char* pszOut, StrLen_t iLenOutMax, const char* pszFormat, va_list vlist)
578  {
592 #if defined(__linux__)
593  return ::vsnprintf(pszOut, iLenOutMax, pszFormat, vlist); // C99
594 #elif USE_CRT && (_MSC_VER >= 1400) && ! defined(UNDER_CE)
595  // CRT version. act as _TRUNCATE
596  return ::_vsnprintf_s(pszOut, (size_t)(iLenOutMax), (size_t)(iLenOutMax - 1), pszFormat, vlist); // to shut up the deprecated warnings.
597 #elif USE_CRT
598  // OLD CRT version.
599  return ::_vsnprintf(pszOut, iLenOutMax, pszFormat, vlist);
600 #else // _WIN32
601  // dont use _WIN32 System version (No floats). return ::FormatMessageA(0, pszFormat, 0, 0, pszOut, iLenOutMax, &vlist);
602  return StrFormat<char>::FormatV(pszOut, iLenOutMax, pszFormat, vlist);
603 #endif
604  }
605 
606  template<> StrLen_t inline StrT::vsprintfN<wchar_t>(OUT wchar_t* pszOut, StrLen_t iLenOutMax, const wchar_t* pszFormat, va_list vlist)
607  {
615 #if defined(__linux__)
616  return ::vswprintf(pszOut, iLenOutMax, pszFormat, vlist); // C99
617 #elif USE_CRT && (_MSC_VER >= 1400) && ! defined(UNDER_CE)
618  // CRT version. act as _TRUNCATE
619  return ::_vsnwprintf_s(pszOut, (size_t)(iLenOutMax), (size_t)(iLenOutMax - 1), pszFormat, vlist); // to shut up the deprecated warnings.
620 #elif USE_CRT
621  // OLD CRT version.
622  return ::_vsnwprintf(pszOut, iLenOutMax, pszFormat, vlist);
623 #else // _WIN32
624  // @note dont use _WIN32 System version (No floats) return ::FormatMessageW(0, pszFormat, 0, 0, pszOut, iLenOutMax, &vlist);
625  return StrFormat<wchar_t>::FormatV(pszOut, iLenOutMax, pszFormat, vlist);
626 #endif
627  }
628 #endif
629 
630  // Override implementations
631 
632  template<> inline const char* StrX<char>::GetBoolStr(bool bVal) NOEXCEPT // static
633  {
634  // Simpler than using "true" : "false"
635  return bVal ? "1" : "0";
636  }
637  template<> inline const wchar_t* StrX<wchar_t>::GetBoolStr(bool bVal) NOEXCEPT // static
638  {
639  return bVal ? L"1" : L"0";
640  }
641 
642  // #include "StrT.inl"
643  // Force instantiation of stuff for char and wchar_t for linking.
644 }
645 #endif // _INC_StrT_H
#define NOEXCEPT
Definition: GrayCore.h:73
#define GRAYCORE_LINK
Definition: GrayCore.h:47
#define GRAYCALL
declare calling convention for static functions so everyone knows the arg passing scheme....
Definition: GrayCore.h:36
#define STRMAX(x)
Get Max size of static string space. minus the '\0' terminator character.
Definition: StrConst.h:33
#define TYPE
Definition: StrT.cpp:38
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define _countof(a)
Definition: cKernel.h:35
#define UNITTEST_FRIEND(n)
Define this in the class body to be unit tested. Allow the unit test to access private/protected stuf...
Definition: cUnitTestDecl.h:17
static StrLen_t __stdcall FormatV(TYPE *pszOut, StrLen_t nLenOutMax, const TYPE *pszFormat, va_list vlist)
Definition: StrFormat.cpp:384
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
int COMPARE_t
result of compare. 0=same, 1=a>b, -1=a<b
Definition: cValT.h:17
const StrLen_t k_StrLen_UNK
use the default/current length of the string argument.
Definition: StrConst.h:34
int StrLen_t
the length of a string in chars (bytes for UTF8, wchar_t for UNICODE). or offset in characters....
Definition: StrConst.h:32
UINT32 STRP_MASK_t
bit mask of STRP_TYPE_
Definition: StrT.h:64
const HASHCODE_t k_HASHCODE_CLEAR
not a valid index.
Definition: GrayCore.h:118
STRP_TYPE_
Definition: StrT.h:49
@ STRP_EMPTY_SKIP
merge/skip empty tokens
Definition: StrT.h:60
@ STRP_END_WHITE
trim end whitespace off token.
Definition: StrT.h:55
@ STRP_MERGE_CRNL
merge "\r\n" (may also be separators.) (newline = linefeed)
Definition: StrT.h:59
@ STRP_0
Definition: StrT.h:52
@ STRP_EMPTY_STOP
Stop when we hit an empty token.
Definition: StrT.h:61
@ STRP_SPACE_SEP
allow space separator only if non space not already used.
Definition: StrT.h:54
@ STRP_DEF
default parsing for a line with , separators.
Definition: StrT.h:57
@ STRP_CHECK_BLOCKS
check for special nested block sequences. "{[("
Definition: StrT.h:56
@ STRP_ALL
all parsing options on.
Definition: StrT.h:62
@ STRP_START_WHITE
remove start whitespace from each token
Definition: StrT.h:53
int ITERATE_t
like size_t but signed
Definition: Index.h:28
WORD RADIX_t
Base for convert of numbers to strings. e.g. 10 base vs 16 base hex numbers.
Definition: StrChar.h:27
STR_BLOCK_TYPE
< quotes/brackets and parenthesis must be matched.
Definition: StrT.h:27
@ STR_BLOCK_CURLY
{X} curly braces
Definition: StrT.h:39
@ STR_BLOCK_SQUARE
[X] brackets
Definition: StrT.h:40
@ STR_BLOCK_PAREN
(X) parenthesis
Definition: StrT.h:41
@ STR_BLOCK_QTY
Definition: StrT.h:44
@ STR_BLOCK_NONE
Definition: StrT.h:32
@ STR_BLOCK_QUOTE
"X" double quotes
Definition: StrT.h:35
UINT32 HASHCODE32_t
always 32 bits.
Definition: GrayCore.h:117
UINT32 STR_BLOCKS_t
bit mask of STR_BLOCK_TYPE
Definition: StrT.h:46
static wchar_t ToUpperA(wchar_t ch) noexcept
Definition: StrChar.h:207
static bool IsSpace(wchar_t ch) noexcept
Definition: StrChar.h:89
static wchar_t ToLowerA(wchar_t ch) noexcept
Definition: StrChar.h:231
static const StrLen_t k_LEN_MAX_DIGITS
Largest number we can represent in double format + some extra places for post decimal....
Definition: StrNum.h:26
static StrLen_t __stdcall ILtoA(INT64 nVal, OUT char *pszOut, StrLen_t iStrMax, RADIX_t nBaseRadix=10)
Definition: StrNum.cpp:239
static const StrLen_t k_LEN_MAX_DIGITS_INT
Largest 64 bits base 2 not including sign or '\0' is only 64 digits.
Definition: StrNum.h:27
static INT64 __stdcall toIL(const char *pszInp, const char **ppszInpEnd=(const char **) nullptr, RADIX_t nBaseRadix=10)
Definition: StrNum.cpp:129
static StrLen_t __stdcall GetNumberString(OUT char *pszOut, const wchar_t *pszInp, StrLen_t iStrMax=k_LEN_MAX_DIGITS)
Definition: StrNum.cpp:27
static StrLen_t __stdcall DtoAG(double dVal, OUT char *pszOut, StrLen_t iStrMax, int iDecPlacesWanted=-1, char chE=- 'e')
Definition: StrNum.cpp:345
static double __stdcall toDouble(const char *pszInp, const char **ppszInpEnd=(const char **) nullptr)
Definition: StrNum.cpp:356
static StrLen_t __stdcall ULtoA(UINT64 nVal, OUT char *pszOut, StrLen_t iStrMax, RADIX_t nBaseRadix=10)
Definition: StrNum.cpp:215
static StrLen_t __stdcall DtoAG2(double dVal, OUT char *pszOut, int iDecPlacesWanted=-1, char chE=- 'e')
Definition: StrNum.cpp:261
static StrLen_t __stdcall ULtoAK(UINT64 uVal, OUT char *pszOut, StrLen_t iStrMax, UINT nKUnit, bool bSpace)
Definition: StrNum.cpp:145
static char *__stdcall ULtoA2(UINT64 uVal, OUT char *pszOut, StrLen_t iStrMax, RADIX_t nBaseRadix=10, char chRadixA='A')
Definition: StrNum.cpp:187
static UINT64 __stdcall toUL(const char *pszInp, const char **ppszInpEnd=(const char **) nullptr, RADIX_t nBaseRadix=0)
Definition: StrNum.cpp:54
Definition: StrT.h:69
static int toI(const TYPE *pszStr, const TYPE **ppszStrEnd=nullptr, RADIX_t nBaseRadix=10)
Definition: StrT.h:344
static __DECL_IMPORT TYPE *__stdcall FindChar(const TYPE *pszStr, TYPE ch, StrLen_t iLen=StrT::k_LEN_MAX) noexcept
static const StrLen_t k_LEN_MAX
arbitrary max size for Format() etc. NOTE: _MSC_VER says stack frame should be at least 16384
Definition: StrT.h:75
static __DECL_IMPORT bool __stdcall IsPrintable(const TYPE *pStr, StrLen_t iLenChars=StrT::k_LEN_MAX)
static StrLen_t vsprintfN(OUT TYPE *pszOut, StrLen_t iLenOutMax, const TYPE *pszFormat, va_list vlist)
static __DECL_IMPORT bool __stdcall StartsWithI(const TYPE *pszStr2, const TYPE *pszPrefix)
static __DECL_IMPORT StrLen_t __stdcall TrimWhitespaceEnd(TYPE *pStr, StrLen_t iLenChars=k_StrLen_UNK)
static __DECL_IMPORT StrLen_t __stdcall GetWhitespaceEnd(const TYPE *pStr, StrLen_t iLenChars=k_StrLen_UNK)
static bool HasChar(const TYPE *pszStr, TYPE ch) noexcept
Definition: StrT.h:170
static __DECL_IMPORT COMPARE_t __stdcall CmpIN(const TYPE *pszStr1, const TYPE *pszStr2, StrLen_t iLenMaxChars) noexcept
static __DECL_IMPORT COMPARE_t __stdcall Cmp(const TYPE *pszStr1, const TYPE *pszStr2)
static __DECL_IMPORT bool __stdcall IsWhitespace(const TYPE *pStr, StrLen_t iLenChars=StrT::k_LEN_MAX)
static __DECL_IMPORT StrLen_t __stdcall MatchRegEx(const TYPE *pText, const TYPE *pRegExPattern, bool bIgnoreCase, StrLen_t nTextMax=k_StrLen_UNK)
static __DECL_IMPORT StrLen_t __stdcall FindWord(const TYPE *pTextSearch, const TYPE *pszKeyWord, StrLen_t iLenMax=StrT::k_LEN_MAX)
static const TYPE * Cast(const TYPE *pszStr)
Definition: StrT.h:93
static __DECL_IMPORT TYPE *__stdcall FindCharRev(const TYPE *pszStr, TYPE ch, StrLen_t iLen=k_StrLen_UNK)
static __DECL_IMPORT StrLen_t __stdcall FindCharN(const TYPE *pszStr, TYPE ch) noexcept
static __DECL_IMPORT ITERATE_t __stdcall TableFindSorted(const TYPE *pszFindThis, const void *ppszTableInit, ITERATE_t iCountMax, size_t nElemSize=sizeof(const TYPE *))
static StrLen_t UtoA(UINT32 nVal, OUT TYPE *pszOut, StrLen_t iStrMax, RADIX_t nBaseRadix=10)
Definition: StrT.h:363
static __DECL_IMPORT ITERATE_t __stdcall TableFindHeadSorted(const TYPE *pszFindHead, const void *ppszTableInit, ITERATE_t iCountMax, size_t nElemSize=sizeof(const TYPE *))
static TYPE * GetNonWhitespace(TYPE *pStr, StrLen_t iLenMax=StrT::k_LEN_MAX) noexcept
Definition: StrT.h:204
static bool IsNullOrEmpty(const TYPE *pszStr) noexcept
Definition: StrT.h:102
static StrLen_t Len(const TYPE *pszStr, StrLen_t iLenMax) noexcept
Definition: StrT.h:124
static __DECL_IMPORT TYPE *__stdcall FindStr(const TYPE *pszStr, const TYPE *pszFind, StrLen_t iLenMax=StrT::k_LEN_MAX)
static __DECL_IMPORT ITERATE_t __stdcall ParseCmds(TYPE *pszCmdLine, StrLen_t nCmdLenMax, TYPE **ppCmds, ITERATE_t iQtyMax, const TYPE *pszSep=nullptr, STRP_MASK_t uFlags=STRP_DEF)
static __DECL_IMPORT UINT64 __stdcall toUL(const TYPE *pszStr, const TYPE **ppszStrEnd=nullptr, RADIX_t nBaseRadix=0)
static __DECL_IMPORT ITERATE_t __stdcall ParseCmdsTmp(TYPE *pszTmp, StrLen_t iTmpSizeMax, const TYPE *pszCmdLine, TYPE **ppCmds, ITERATE_t iCmdQtyMax, const TYPE *pszSep=nullptr, STRP_MASK_t uFlags=STRP_DEF)
static __DECL_IMPORT COMPARE_t __stdcall CmpHeadI(const TYPE *pszFind, const TYPE *pszTableElem)
static __DECL_IMPORT TYPE *__stdcall FindStrI(const TYPE *pszStr, const TYPE *pszFind, StrLen_t iLenMax=StrT::k_LEN_MAX)
static __DECL_IMPORT HASHCODE32_t __stdcall GetHashCode32(const TYPE *pszStr, StrLen_t nLen=k_StrLen_UNK, HASHCODE32_t nHash=k_HASHCODE_CLEAR) noexcept
static __DECL_IMPORT StrLen_t __stdcall EscSeqAddQ(TYPE *pStrOut, const TYPE *pStrIn, StrLen_t iLenOutMax=StrT::k_LEN_MAX)
static void MakeLowerCase(TYPE *pszDst, StrLen_t iLenCharsMax) noexcept
Definition: StrT.h:255
static __DECL_IMPORT double __stdcall toDouble(const TYPE *pszStr, const TYPE **ppszStrEnd=nullptr)
static __DECL_IMPORT ITERATE_t __stdcall TableFind(const TYPE *pszFindThis, const void *ppszTableInit, size_t nElemSize=sizeof(const TYPE *))
static __DECL_IMPORT bool __stdcall EndsWithI(const TYPE *pszStr2, const TYPE *pszPostfix, StrLen_t nLenStr=k_StrLen_UNK)
static __DECL_IMPORT TYPE *__stdcall StripBlock(TYPE *pszText)
static const TYPE * CheckEmpty(const TYPE *pszStr) noexcept
Definition: StrT.h:113
static __DECL_IMPORT COMPARE_t __stdcall CmpN(const TYPE *pszStr1, const TYPE *pszStr2, StrLen_t iLenMaxChars) noexcept
static __DECL_IMPORT StrLen_t __stdcall EscSeqRemove(TYPE *pStrOut, const TYPE *pStrIn, StrLen_t iLenOutMax=StrT::k_LEN_MAX, StrLen_t iLenInMax=StrT::k_LEN_MAX)
static const TYPE * GetNonWhitespace(const TYPE *pStr, StrLen_t iLenMax=StrT::k_LEN_MAX) noexcept
Definition: StrT.h:198
static StrLen_t _cdecl sprintfN(OUT TYPE *pszOut, StrLen_t iLenOutMax, const TYPE *pszFormat,...)
Definition: StrT.h:273
static INT_PTR toIP(const TYPE *pszStr, const TYPE **ppszStrEnd=nullptr, RADIX_t nBaseRadix=10)
Definition: StrT.h:331
static void MakeUpperCase(TYPE *pszDst, StrLen_t iLenCharsMax) noexcept
Definition: StrT.h:242
static StrLen_t GetNonWhitespaceI(const TYPE *pStr, StrLen_t iLenMax=StrT::k_LEN_MAX) noexcept
Definition: StrT.h:187
static StrLen_t Len(const TYPE *pszStr) noexcept
static __DECL_IMPORT StrLen_t __stdcall EscSeqRemoveQ(TYPE *pStrOut, const TYPE *pStrIn, StrLen_t iLenOutMax=StrT::k_LEN_MAX, StrLen_t iLenInMax=StrT::k_LEN_MAX)
static StrLen_t ItoA(INT32 nVal, OUT TYPE *pszOut, StrLen_t iStrMax, RADIX_t nBaseRadix=10)
Definition: StrT.h:371
static StrLen_t Diff(const TYPE *pszEnd, const TYPE *pszStart)
Definition: StrT.h:138
static __DECL_IMPORT StrLen_t __stdcall DtoA(double nVal, OUT TYPE *pszOut, StrLen_t iStrMax, int iDecPlaces=-1, char chE=- 'e')
static UINT_PTR toUP(const TYPE *pszStr, const TYPE **ppszStrEnd=nullptr, RADIX_t nBaseRadix=0)
Definition: StrT.h:325
static __DECL_IMPORT INT64 __stdcall toIL(const TYPE *pszStr, const TYPE **ppszStrEnd=nullptr, RADIX_t nBaseRadix=10)
static __DECL_IMPORT TYPE *__stdcall FindBlockEnd(STR_BLOCK_TYPE eBlockType, const TYPE *pLine, StrLen_t iLenMax=StrT::k_LEN_MAX)
static __DECL_IMPORT StrLen_t __stdcall ReplaceX(TYPE *pDst, StrLen_t iDstLenMax, StrLen_t nDstIdx, StrLen_t iDstSegLen, const TYPE *pSrc, StrLen_t iSrcLen=k_StrLen_UNK)
static __DECL_IMPORT StrLen_t __stdcall ILtoA(INT64 nVal, OUT TYPE *pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix=10)
static UINT toU(const TYPE *pszStr, const TYPE **ppszStrEnd=nullptr, RADIX_t nBaseRadix=0)
Definition: StrT.h:338
static __DECL_IMPORT StrLen_t __stdcall ULtoA(UINT64 nVal, TYPE *pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix=10)
static __DECL_IMPORT ITERATE_t __stdcall TableFindHead(const TYPE *pszFindHead, const void *ppszTableInit, size_t nElemSize=sizeof(const TYPE *))
static __DECL_IMPORT StrLen_t __stdcall EscSeqAdd(TYPE *pStrOut, const TYPE *pStrIn, StrLen_t iLenOutMax=StrT::k_LEN_MAX)
static __DECL_IMPORT TYPE *__stdcall FindTokens(const TYPE *pszStr, const TYPE *pszTokens, StrLen_t iLenMax=StrT::k_LEN_MAX)
static __DECL_IMPORT StrLen_t __stdcall ULtoAK(UINT64 uVal, OUT TYPE *pszStr, StrLen_t iStrMax, UINT nKUnit=1024, bool bSpace=true)
static __DECL_IMPORT StrLen_t __stdcall CopyLen(TYPE *pszDst, const TYPE *pSrc, StrLen_t iLenCharsMax) noexcept
static __DECL_IMPORT TYPE *__stdcall TrimWhitespace(TYPE *pStr, StrLen_t iLenMax=StrT::k_LEN_MAX)
static __DECL_IMPORT TYPE *__stdcall ULtoA2(UINT64 uVal, TYPE *pszOut, StrLen_t iOutMax, RADIX_t nBaseRadix=10, char chRadixA='A')
static __DECL_IMPORT COMPARE_t __stdcall CmpI(const TYPE *pszStr1, const TYPE *pszStr2)
static StrLen_t __stdcall UTF8toUNICODE(wchar_t &wChar, const char *pInp, StrLen_t iSizeInpBytes)
Definition: StrU.cpp:133
Definition: StrT.h:391
static const TYPE *__stdcall GetBoolStr(bool bVal) noexcept
static const TYPE * GetTableElemU(const void *ppszTableInit, ITERATE_t i, size_t nSizeElem)
Definition: StrT.h:399
static const size_t k_ALLOC_MAX
256 * 64K = (arbitrary) largest reasonable single malloc.
Definition: cHeap.h:45