00001 #if !defined(IT_Bus_FWSTRINGHELP_INCLUDED_)
00002 #define IT_Bus_FWSTRINGHELP_INCLUDED_
00003
00004 #include <stdio.h>
00005
00006 #include <it_bus/api_defines.h>
00007
00008 #include <it_dsa/string.h>
00009
00010
00011 #if defined(_WIN32)
00012 #define strncasecmp _strnicmp
00013 #define strcasecmp _stricmp
00014 #define wcsncasecmp _wcsnicmp
00015 #define snprintf _snprintf
00016 #define vsnprintf _vsnprintf
00017 #endif
00018
00019
00020 inline bool IsBlank(const char* strValue)
00021 {
00022 if (strValue == NULL)
00023 return true;
00024
00025 long lStringLen = strlen(strValue);
00026
00027 if (lStringLen == 0)
00028 return true;
00029
00030 for(long lIndex = 0; lIndex < lStringLen; lIndex++)
00031 {
00032 if (strValue[lIndex] != ' ')
00033 return false;
00034 }
00035
00036 return true;
00037 }
00038
00039 class IT_AFC_API CCountedString
00040 {
00041 protected:
00042 long* m_plRefCount;
00043 char* m_szData;
00044
00045 public:
00046 CCountedString()
00047 {
00048 m_plRefCount = new long(1);
00049 m_szData = NULL;
00050 }
00051
00052 CCountedString(const CCountedString& cs)
00053 {
00054 m_plRefCount = cs.m_plRefCount;
00055 m_szData = cs.m_szData;
00056 (*m_plRefCount)++;
00057 }
00058
00059 CCountedString(const char* sz)
00060 {
00061 m_plRefCount = new long(1);
00062 m_szData = NULL;
00063 Alloc(strlen(sz));
00064 strcpy(m_szData,sz);
00065 }
00066
00067 bool operator==(const char* val)
00068 {
00069 if ( (m_szData == NULL) || (val == NULL) )
00070 return (val == m_szData);
00071
00072 return (0 == strcmp(val, m_szData));
00073 }
00074
00075 bool operator!=(const char* val)
00076 {
00077 if ( (m_szData == NULL) || (val == NULL) )
00078 return (val != m_szData);
00079
00080 return (0 != strcmp(val, m_szData));
00081 }
00082
00083
00084 bool operator==(const size_t p)
00085 {
00086 return ((char*)p == m_szData);
00087 }
00088
00089 bool operator!=(const size_t p)
00090 {
00091 return ((char*)p != m_szData);
00092 }
00093
00094 operator bool()
00095 {
00096 return (m_szData != NULL);
00097 }
00098
00099 CCountedString& operator = (const CCountedString& cs)
00100 {
00101 if ( (*m_plRefCount) > 1)
00102 {
00103 throw;
00104 }
00105
00106 if (m_szData != NULL)
00107 delete [] m_szData;
00108
00109 delete m_plRefCount;
00110
00111 m_plRefCount = cs.m_plRefCount;
00112 m_szData = cs.m_szData;
00113 (*m_plRefCount)++;
00114
00115 return *this;
00116 }
00117
00118 const char* operator = (const char* sz)
00119 {
00120 Alloc(strlen(sz));
00121 strcpy(m_szData,sz);
00122 return m_szData;
00123 }
00124
00125
00126 ~CCountedString()
00127 {
00128 if (m_plRefCount == NULL)
00129 return;
00130
00131 (*m_plRefCount)--;
00132 if (0 == (*m_plRefCount))
00133 {
00134 if (m_szData != NULL)
00135 delete [] m_szData;
00136
00137 delete m_plRefCount;
00138 }
00139 }
00140
00141 void Alloc(unsigned long lSize)
00142 {
00143 if (m_szData != NULL)
00144 {
00145 if ( (*m_plRefCount) > 1)
00146 throw;
00147
00148 delete [] m_szData;
00149 }
00150
00151 m_szData = new char[lSize + 1];
00152 }
00153
00154 operator char*()
00155 {
00156 return m_szData;
00157 }
00158
00159 operator const char*() const
00160 {
00161 return m_szData;
00162 }
00163
00164 char* At(long dwPosition)
00165 {
00166 if (m_szData != NULL)
00167 return &m_szData[dwPosition];
00168
00169 return NULL;
00170 }
00171
00172 void Realloc(unsigned long lSize)
00173 {
00174 if (m_szData == NULL)
00175 Alloc(lSize);
00176 else
00177 {
00178 if ( (*m_plRefCount) > 1)
00179 throw;
00180
00181 char* szLocalData = new char[lSize + 1];
00182 strcpy(szLocalData, m_szData);
00183
00184 delete [] m_szData;
00185 m_szData = szLocalData;
00186 }
00187 }
00188
00189 long GetSize()
00190 {
00191 if (m_szData == NULL)
00192 return 0;
00193 else
00194 return strlen(m_szData);
00195 }
00196 };
00197
00198
00199
00200 typedef enum {
00201 url_XAlphas = (1<<0)
00202 , url_XPAlphas = (1<<1)
00203 , url_Path = (1<<2)
00204 } nsEscapeMask;
00205
00206 const int netCharType[256] =
00207
00208
00209
00210
00211
00212
00213 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00214 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00215 0,0,0,0,0,0,0,0,0,0,7,0,0,7,7,4,
00216 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,
00217 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00218
00219
00220 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7,
00221 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00222 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,
00223 0,
00224 };
00225
00226
00227
00228 #define UNHEX(C) \
00229 ((C >= '0' && C <= '9') ? C - '0' : \
00230 ((C >= 'A' && C <= 'F') ? C - 'A' + 10 : \
00231 ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)))
00232
00233 #define IS_OK(C) (netCharType[((unsigned int) (C))] & (mask))
00234
00235 #define HEX_ESCAPE '%'
00236
00237
00238 inline bool URLEscapeCount(const char * str, long len, nsEscapeMask mask, long* out_len, char* result)
00239
00240 {
00241 if (!str)
00242 return false;
00243
00244 bool bCalcSize = ((NULL != out_len) && (*out_len == 0));
00245
00246 int i;
00247 register const unsigned char* src = (const unsigned char *) str;
00248 const char* hexChars = "0123456789ABCDEF";
00249
00250 if (bCalcSize)
00251 {
00252 int extra = 0;
00253
00254 for (i = 0; i < len; i++)
00255 {
00256 if (!IS_OK(*src))
00257 {
00258 if (!( (mask > url_XAlphas) && (*src == ' ') ))
00259 extra += 2;
00260 }
00261 src++;
00262 }
00263
00264 *out_len = len + extra;
00265 }
00266
00267 if (NULL == result)
00268 return true;
00269
00270 register unsigned char* dst = (unsigned char *) result;
00271 src = (const unsigned char *) str;
00272 if (mask > url_XAlphas)
00273 {
00274 for (i = 0; i < len; i++)
00275 {
00276 unsigned char c = *src++;
00277 if (IS_OK(c))
00278 *dst++ = c;
00279 else if (c == ' ')
00280 *dst++ = '+';
00281 else
00282 {
00283 *dst++ = HEX_ESCAPE;
00284 *dst++ = hexChars[c >> 4];
00285 *dst++ = hexChars[c & 0x0f];
00286 }
00287 }
00288 }
00289 else
00290 {
00291 for (i = 0; i < len; i++)
00292 {
00293 unsigned char c = *src++;
00294 if (IS_OK(c))
00295 *dst++ = c;
00296 else
00297 {
00298 *dst++ = HEX_ESCAPE;
00299 *dst++ = hexChars[c >> 4];
00300 *dst++ = hexChars[c & 0x0f];
00301 }
00302 }
00303 }
00304
00305 return true;
00306 }
00307
00308
00309 inline void URLEscape(const char * str, nsEscapeMask mask, long* out_len, char* result)
00310
00311 {
00312 if(!str)
00313 return;
00314
00315 URLEscapeCount(str, (long)strlen(str), mask, out_len, result);
00316 }
00317
00318
00319
00320
00321
00322 inline bool URLUnescapeCount(char * str, long len, nsEscapeMask mask, long* out_len, char* result)
00323
00324 {
00325 if (!str)
00326 return false;
00327
00328 bool bCalcSize = ((NULL != out_len) && (*out_len == 0));
00329
00330 register char* src = str;
00331 register char* dst = result;
00332
00333 if (bCalcSize)
00334 {
00335 int i = 0;
00336 *out_len = len;
00337
00338 while(i < len)
00339 {
00340 if ( (src[i] == HEX_ESCAPE) && (i + 2 < len) )
00341 {
00342 *out_len -= 2;
00343 i+=3;
00344 }
00345 else
00346 i++;
00347 }
00348 }
00349
00350 if (NULL == result)
00351 return true;
00352
00353 char* end = src + len;
00354 while (src < end)
00355 if ( (*src == '+') && (mask > url_XAlphas) )
00356 {
00357 *dst = ' ';
00358 dst++;
00359 src++;
00360 }
00361 else if (*src != HEX_ESCAPE)
00362 *dst++ = *src++;
00363 else
00364 {
00365 src++;
00366 if (*src)
00367 {
00368 *dst = UNHEX(*src) << 4;
00369 src++;
00370 }
00371
00372 if (*src)
00373 {
00374 *dst = (*dst + UNHEX(*src));
00375 src++;
00376 }
00377 dst++;
00378 }
00379
00380 *out_len = (dst - result);
00381
00382 return true;
00383 }
00384
00385
00386 inline bool URLUnescape(char * str, nsEscapeMask mask, long* out_len, char* result)
00387
00388 {
00389 return URLUnescapeCount(str, strlen(str), mask, out_len, result);
00390 }
00391
00392
00393 inline bool URLUnescapeInPlace(char * str, nsEscapeMask mask, long* out_len, char* )
00394
00395 {
00396 return URLUnescape(str, mask, out_len, str);
00397 }
00398
00399
00400
00401 inline long FindAnyLineBreak(const char* szData, long lIndex, long lSize)
00402 {
00403 const char* p = szData;
00404
00405 if (lIndex > lSize)
00406 return -1;
00407
00408 long lLastPos = lSize - 2;
00409
00410 for(long lPos = lIndex; lPos <= lLastPos; lPos++)
00411 {
00412 if ( (p[lPos] == '\r') && (p[lPos + 1] == '\n') )
00413 return lPos;
00414
00415 if ( (p[lPos] == '\n') && (p[lPos + 1] == '\r') )
00416 return lPos;
00417
00418 if ( (p[lPos] == '\r') && (p[lPos + 1] == '\r') )
00419 return lPos;
00420
00421 if ( (p[lPos] == '\n') && (p[lPos + 1] == '\n') )
00422 return lPos;
00423 }
00424
00425 return -1;
00426 }
00427
00428
00429
00430 inline IT_String Left(const char* szSource, long dwLength)
00431 {
00432 if (dwLength == 0)
00433 return "";
00434
00435 long lLength = strlen(szSource);
00436
00437 if ( dwLength >= lLength )
00438 return szSource;
00439
00440 return IT_String(szSource, dwLength);
00441 }
00442
00443 inline IT_String Right(const char* szSource, long dwLength)
00444 {
00445 if (dwLength == 0)
00446 return "";
00447
00448 long lLength = strlen(szSource);
00449
00450 if ( dwLength >= lLength )
00451 return szSource;
00452
00453 const char* szStart = szSource;
00454
00455 long dwIndex = lLength - dwLength;
00456
00457 szStart+=dwIndex;
00458
00459 return IT_String(szStart, dwLength);
00460 }
00461
00462 inline IT_String Mid(const char* szSource, long dwIndex, long dwLength = -1)
00463 {
00464 if (dwLength == 0)
00465 return "";
00466
00467 long lLength = strlen(szSource);
00468
00469 if ( (dwLength == -1) || (dwLength > lLength - dwIndex) )
00470 dwLength = lLength - dwIndex;
00471
00472 const char* szStart = szSource + dwIndex;
00473
00474 return IT_String(szStart, dwLength);
00475 }
00476
00477 inline IT_String Hex(long dwValue)
00478 {
00479 char szHex[16];
00480 sprintf(szHex, "%lx", dwValue);
00481
00482 return IT_String(szHex);
00483 }
00484
00485
00486 inline IT_String Trim(const char* sz)
00487 {
00488 if (sz == NULL)
00489 return "";
00490
00491 long lLength = strlen(sz);
00492 const char* szBegin = sz;
00493 const char* szEnd = &szBegin[lLength - 1];
00494
00495 if ((*szBegin != ' ') && (*szEnd != ' ') )
00496 return sz;
00497
00498 long dwStrip = 0;
00499
00500 while (*szBegin == ' ')
00501 {
00502 szBegin++;
00503 dwStrip++;
00504 }
00505
00506 while ( (szEnd > szBegin) && (*szEnd == ' ') )
00507 {
00508 szEnd--;
00509 dwStrip++;
00510 }
00511
00512 return IT_String(szBegin, lLength - dwStrip);
00513 }
00514
00515
00516 inline IT_String LTrim(const char* sz)
00517 {
00518 if (sz == NULL)
00519 return "";
00520
00521 long lLength = strlen(sz);
00522
00523 const char* szBegin = sz;
00524
00525 if (*szBegin != ' ')
00526 return sz;
00527
00528 long dwStrip = 0;
00529 while (*szBegin == ' ')
00530 {
00531 szBegin++;
00532 dwStrip++;
00533 }
00534
00535 return IT_String(szBegin, lLength - dwStrip);
00536 }
00537
00538 inline char FirstChar(const char* szSource, bool bSkipBlanks = true)
00539 {
00540 if ( IsBlank(szSource) )
00541 return 0;
00542
00543 if (bSkipBlanks)
00544 {
00545 IT_String strSource = LTrim(strSource.c_str());
00546
00547 if ( strSource.empty() )
00548 return 0;
00549
00550 return ((strSource.c_str())[0]);
00551 }
00552 else
00553 return (szSource[0]);
00554 }
00555
00556
00557 inline IT_String EscapeSequence(const char* szInput, char wc, const char* szEscapeSequence)
00558 {
00559 if (IsBlank(szInput))
00560 return "";
00561
00562 long dwInputLen = strlen(szInput);
00563 long dwInputIdx = 0;
00564
00565 char sz[2];
00566 sz[0] = 0;
00567 sz[1] = 0;
00568
00569 IT_String strEscaped = "";
00570
00571 while ( ( dwInputIdx < dwInputLen ) )
00572 {
00573 if (szInput[dwInputIdx] == wc)
00574 {
00575 strEscaped = strEscaped + szEscapeSequence;
00576 }
00577 else
00578 {
00579 sz[0] = szInput[dwInputIdx];
00580 strEscaped = strEscaped + sz;
00581 }
00582 dwInputIdx++;
00583 }
00584
00585 return strEscaped;
00586 }
00587
00588
00589
00590
00591 inline bool IsFuzzyEqual(const char* str1, const char* str2)
00592 {
00593
00594
00595 if (str1 == str2)
00596 return true;
00597
00598 const char* szLocal1 = 0;
00599 unsigned long iSize1 = 0;
00600 if (str1 != NULL)
00601 {
00602 szLocal1 = str1;
00603
00604
00605 while(*szLocal1 == ' ')
00606 szLocal1++;
00607
00608
00609 if (*szLocal1 != 0)
00610 {
00611 const char* szLocal1End = szLocal1 + strlen(szLocal1) - 1;
00612
00613 while ( *szLocal1End == ' ')
00614 --szLocal1End;
00615
00616 ++szLocal1End;
00617
00618 iSize1 = (szLocal1End - szLocal1);
00619 }
00620 }
00621
00622 const char* szLocal2 = 0;
00623 unsigned long iSize2 = 0;
00624 if (str2 != NULL)
00625 {
00626 szLocal2 = str2;
00627
00628 while(*szLocal2 == ' ')
00629 ++szLocal2;
00630
00631 if (*szLocal2 != 0)
00632 {
00633 const char* szLocal2End = szLocal2 + strlen(szLocal2) - 1;
00634
00635 while ( *szLocal2End == ' ')
00636 --szLocal2End;
00637
00638 ++szLocal2End;
00639
00640 iSize2 = (szLocal2End - szLocal2);
00641 }
00642 }
00643
00644 if (iSize1 != iSize2)
00645 return false;
00646
00647 if ((szLocal1==0) || (iSize1==0))
00648 return ((szLocal2==0) || (iSize2==0));
00649
00650 if ((szLocal2==0) || (iSize2==0))
00651 return ((szLocal1==0) || (iSize1==0));
00652
00653 return (strncasecmp(szLocal1,szLocal2,iSize1) == 0);
00654 }
00655
00656
00657 #endif