Back to index

nux  3.0.0
TextString.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "NuxCore.h"
00024 
00025 namespace nux
00026 {
00027 //
00028 // Copy a string with length checking.
00029 //warning: Behavior differs from strncpy; last character is zeroed.
00030 //
00031   TCHAR *Strncpy (TCHAR *Dest, size_t Size, const TCHAR *Src, size_t MaxLen)
00032   {
00033     nuxAssert (MaxLen >= 0);
00034     STRNCPY_S (Dest, Size, Src, MaxLen);
00035     Dest[MaxLen] = 0;
00036     return Dest;
00037   }
00038 
00039 //
00040 // Concatenate a string with length checking
00041 //
00042   TCHAR *Strncat (TCHAR *Dest, size_t Size, const TCHAR *Src, size_t MaxLen)
00043   {
00044     size_t Len = StringLength (Dest);
00045     nuxAssert (Size >= Len);
00046     TCHAR *NewDest = Dest + Len;
00047 
00048     if ( (MaxLen -= Len) > 0)
00049     {
00050       Strncpy (NewDest, Size - Len, Src, MaxLen);
00051       NewDest[MaxLen-1] = 0;
00052     }
00053 
00054     return Dest;
00055   }
00056 
00057 
00058 // Search a string inside a string. Return a pointer to the beginning of the searched string if it is found. Else, return NULL;
00059 // The shearched string must be preceded by a non alpha numeric character in Str.
00060 
00061   const TCHAR *Strfind (const TCHAR *Str, const TCHAR *Find)
00062   {
00063     nuxAssert (Find != NULL);
00064     nuxAssert (Str != NULL);
00065 
00066     if (Find == NULL || Str == NULL)
00067     {
00068       return NULL;
00069     }
00070 
00071     bool AlphaNum = 0;
00072     TCHAR First = ( (*Find < TEXT ('a') ) || (*Find > TEXT ('z') ) ) ? (*Find) : (*Find + TEXT ('A') - TEXT ('a') );
00073     size_t Len = StringLength (Find++) - 1;
00074     TCHAR chr = *Str++;
00075 
00076     while (chr)
00077     {
00078       if ( (chr >= TEXT ('a') ) && (chr <= TEXT ('z') ) )
00079       {
00080         chr += TEXT ('A') - TEXT ('a');
00081       }
00082 
00083       if (!AlphaNum && (chr == First) && !TCharStringNICompare (Str, Find, Len) )
00084       {
00085         return Str - 1;
00086       }
00087 
00088       AlphaNum = ( (chr >= TEXT ('A') ) && (chr <= TEXT ('Z') ) ) || ( (chr >= TEXT ('0') ) && (chr <= TEXT ('9') ) );
00089       chr = *Str++;
00090     }
00091 
00092     return NULL;
00093   }
00094 
00095   bool IsLastChar (const TCHAR *CharString, const TCHAR Chr)
00096   {
00097     nuxAssert (CharString != 0);
00098 
00099     if (CharString == 0)
00100       return false;
00101 
00102     size_t Size = StringLength (CharString);
00103 
00104     if (Size == 0)
00105       return false;
00106 
00107     if (CharString[Size-1] == Chr)
00108       return true;
00109 
00110     return false;
00111   }
00112 
00113   NString Itoa (int InNum)
00114   {
00115     SQWORD    Num                                = InNum; // This avoids having to deal with negating -MaxS32 - 1
00116     NString NumberString;
00117     const TCHAR      *NumberChar[10]             = { TEXT ("0"), TEXT ("1"), TEXT ("2"), TEXT ("3"), TEXT ("4"), TEXT ("5"), TEXT ("6"), TEXT ("7"), TEXT ("8"), TEXT ("9") };
00118     bool      bIsNumberNegative    = false;
00119 
00120     // Correctly handle negative numbers and convert to positive integer.
00121     if (Num < 0)
00122     {
00123       bIsNumberNegative = true;
00124       Num = -Num;
00125     }
00126 
00127     // Convert to string assuming base ten and a positive integer.
00128     do
00129     {
00130       NumberString += NumberChar[Num % 10];
00131       Num /= 10;
00132     }
00133     while (Num);
00134 
00135     // Append sign as we're going to reverse string afterwards.
00136     if (bIsNumberNegative)
00137     {
00138       NumberString += TEXT ("-");
00139     }
00140 
00141     NumberString.Reverse();
00142     return NumberString;
00143   }
00144 
00146   TCHAR *Strdup (const TCHAR *str)
00147   {
00148     if (str == 0)
00149       return 0;
00150 
00151     size_t len = StringLength (str);
00152 
00153     if (len >= 0)
00154     {
00155       TCHAR *res = new TCHAR[len+1];
00156       Strncpy (res, len + 1, str, len);
00157       return res;
00158     }
00159 
00160     return 0;
00161   }
00162 
00164   ANSICHAR *StrdupA ( const ANSICHAR *str)
00165   {
00166     if (str == 0)
00167       return 0;
00168 
00169     int len = (int) strlen (str);
00170 
00171     if (len >= 0)
00172     {
00173       ANSICHAR *res = new ANSICHAR[len+1];
00174       STRNCPY_S ( (char *) res, len + 1, (const char *) str, len);
00175       return res;
00176     }
00177 
00178     return 0;
00179   }
00180 
00182   UNICHAR *StrdupU ( const UNICHAR *str)
00183   {
00184     if (str == 0)
00185       return 0;
00186 
00187     int len = (int) wcslen ( (const wchar_t *) str);
00188 
00189     if (len >= 0)
00190     {
00191       UNICHAR *res = new UNICHAR[len+1];
00192       WCSNCPY_S ( (wchar_t *) res, len + 1, (const wchar_t *) str, len);
00193       return res;
00194     }
00195 
00196     return 0;
00197   }
00198 // /*
00199 // * Standard string formatted print.
00200 // */
00201 // VARARG_BODY(int, inlSprintf, const TCHAR*, VARARG_EXTRA(TCHAR* Dest))
00202 // {
00203 //     int    Result = -1;
00204 //     va_list ap;
00205 //     va_start(ap, Fmt);
00206 //     //@warning: make sure code using inlSprintf allocates enough memory if the below 1024 is ever changed.
00207 //     GET_VARARGS_RESULT(Dest,1024/*!!*/,Fmt,Result);
00208 //     return Result;
00209 // }
00210 
00211 
00212   size_t ValueToLiteralString (char *buffer, unsigned int len, unsigned short     value)
00213   {
00214     return ToCharString (buffer, len, "%hu",     value);
00215   }
00216   size_t ValueToLiteralString (char *buffer, unsigned int len, short     value)
00217   {
00218     return ToCharString (buffer, len, "%hi",     value);
00219   }
00220   size_t ValueToLiteralString (char *buffer, unsigned int len, unsigned int     value)
00221   {
00222     return ToCharString (buffer, len, "%lu",     value);
00223   }
00224   size_t ValueToLiteralString (char *buffer, unsigned int len, int     value)
00225   {
00226     return ToCharString (buffer, len, "%li",     value);
00227   }
00228   size_t ValueToLiteralString (char *buffer, unsigned int len, unsigned long   value)
00229   {
00230     return ToCharString (buffer, len, "%lu",     value);
00231   }
00232   size_t ValueToLiteralString (char *buffer, unsigned int len, long    value)
00233   {
00234     return ToCharString (buffer, len, "%li",     value);
00235   }
00236   size_t ValueToLiteralString (char *buffer, unsigned int len, unsigned long long     value)
00237   {
00238     return ToCharString (buffer, len, "%I64u",   value);
00239   }
00240   size_t ValueToLiteralString (char *buffer, unsigned int len, long long     value)
00241   {
00242     return ToCharString (buffer, len, "%I64i",   value);
00243   }
00244   size_t ValueToLiteralString (char *buffer, unsigned int len, float   value)
00245   {
00246     return ToCharString (buffer, len, "%.10g",   value);
00247   }
00248   size_t ValueToLiteralString (char *buffer, unsigned int len, double  value)
00249   {
00250     return ToCharString (buffer, len, "%.20lg",  value);
00251   }
00252   size_t ValueToLiteralString (char *buffer, unsigned int len, unsigned char      value)
00253   {
00254     return ValueToLiteralString (buffer, len,    (unsigned int) value);
00255   }
00256   size_t ValueToLiteralString (char *buffer, unsigned int len, char    value)
00257   {
00258     return ValueToLiteralString (buffer, len,    (int) value);
00259   }
00260 
00261   bool ValueFromLiteralString (const char *buffer, unsigned int len, unsigned short    &value)
00262   {
00263     return FromCharString (buffer, len, "%hu", value );
00264   }
00265   bool ValueFromLiteralString (const char *buffer, unsigned int len, short    &value)
00266   {
00267     return FromCharString (buffer, len, "%hi", value );
00268   }
00269   bool ValueFromLiteralString (const char *buffer, unsigned int len, unsigned int    &value)
00270   {
00271     return FromCharString (buffer, len, "%lu", value );
00272   }
00273   bool ValueFromLiteralString (const char *buffer, unsigned int len, int    &value)
00274   {
00275     return FromCharString (buffer, len, "%li", value );
00276   }
00277   bool ValueFromLiteralString (const char *buffer, unsigned int len, unsigned long  &value)
00278   {
00279     return FromCharString (buffer, len, "%lu", value );
00280   }
00281   bool ValueFromLiteralString (const char *buffer, unsigned int len, long   &value)
00282   {
00283     return FromCharString (buffer, len, "%li", value );
00284   }
00285   bool ValueFromLiteralString (const char *buffer, unsigned int len, unsigned long long    &value)
00286   {
00287     return FromCharString (buffer, len, "%I64u", value );
00288   }
00289   bool ValueFromLiteralString (const char *buffer, unsigned int len, long long    &value)
00290   {
00291     return FromCharString (buffer, len, "%I64i", value );
00292   }
00293   bool ValueFromLiteralString (const char *buffer, unsigned int len, float  &value)
00294   {
00295     return FromCharString (buffer, len, "%g", value );
00296   }
00297   bool ValueFromLiteralString (const char *buffer, unsigned int len, double &value)
00298   {
00299     return FromCharString (buffer, len, "%lg", value );
00300   }
00301   bool ValueFromLiteralString (const char *buffer, unsigned int len, unsigned char     &value)
00302   {
00303     unsigned int tmp = 0;
00304     bool result;
00305     result = ValueFromLiteralString (buffer, len, tmp);
00306     value = (unsigned char) tmp;
00307     return result;
00308   }
00309 
00310   bool ValueFromLiteralString (const char *buffer, unsigned int len, char &value)
00311   {
00312     int tmp = 0;
00313     bool result;
00314     result = ValueFromLiteralString (buffer, len, tmp);
00315     value = (char) tmp;
00316     return result;
00317   }
00318 
00319   VARARG_BODY (int, Snprintf, const TCHAR *, VARARG_EXTRA (TCHAR *Dest) VARARG_EXTRA (int Size) VARARG_EXTRA (int Count) )
00320   {
00321     int Result = -1;
00322     GET_VARARGS_RESULT (Dest, Size, Count, Fmt, Result);
00323     return Result;
00324   }
00325 
00326   NString::NString()
00327   {
00328     m_string = TEXT("");
00329   }
00330 
00331   NString::NString (const NString &s)
00332   {
00333     m_string = s.m_string;
00334   }
00335 
00336   NString &NString::operator= (const NString &s)
00337   {
00338     m_string = s.m_string;
00339     return *this;
00340   }
00341 
00342   NString::NString (const tstring &s)
00343   {
00344     m_string = s;
00345   }
00346 
00347   NString::NString (const TCHAR &s)
00348   {
00349     m_string = s;
00350   }
00351 
00352   NString::NString (const ANSICHAR *s)
00353   {
00354 #ifdef UNICODE
00355 
00356     if (s == 0)
00357       m_string = TEXT ("");
00358     else
00359       m_string = ANSICHAR_TO_UNICHAR (s);
00360 
00361 #else
00362 
00363     if (s == 0)
00364       m_string = TEXT ("");
00365     else
00366       m_string = s;
00367 
00368 #endif
00369   }
00370 
00371   NString::NString (const UNICHAR *s)
00372   {
00373 #ifdef UNICODE
00374 
00375     if (s == 0)
00376       m_string = TEXT ("");
00377     else
00378       m_string = s;
00379 
00380 #else
00381 
00382     if (s == 0)
00383       m_string = TEXT ("");
00384     else
00385       m_string = UNICHAR_TO_ANSICHAR (s);
00386 
00387 #endif
00388   }
00389 
00390 
00391   NString::~NString()
00392   {
00393   }
00394 
00395   const tstring &NString::GetTStringRef() const
00396   {
00397     return m_string;
00398   }
00399 
00400 //const TCHAR* NString::GetTChar() const
00401 //{
00402 //    return m_string.c_str();
00403 //}
00404 
00405   const TCHAR *NString::GetTCharPtr() const
00406   {
00407     return m_string.c_str();
00408   }
00409 
00410   size_t NString::Length() const
00411   {
00412     return m_string.length();
00413   }
00414 
00415   size_t NString::Size() const
00416   {
00417     return m_string.size();
00418   }
00419 
00420   void NString::Clear()
00421   {
00422     m_string.clear();
00423   }
00424 
00425   bool NString::IsEmpty() const
00426   {
00427     return m_string.empty();
00428   }
00429 
00430   void NString::Erase (size_t Pos, size_t Count)
00431   {
00432     m_string.erase (Pos, Count);
00433   }
00434 
00435   NString &NString::Insert (size_t Pos, const TCHAR *Ptr)
00436   {
00437     m_string.insert (Pos, Ptr);
00438     return *this;
00439   }
00440 
00441   NString &NString::Insert (size_t Pos, const TCHAR *Ptr, size_t Count)
00442   {
00443     m_string.insert (Pos, Ptr, Count);
00444     return *this;
00445   }
00446 
00447   NString &NString::Insert (size_t Pos, const tstring &Str)
00448   {
00449     m_string.insert (Pos, Str);
00450     return *this;
00451   }
00452 
00453   NString &NString::Insert (size_t Pos, const tstring &Str, size_t Offset, size_t Count)
00454   {
00455     m_string.insert (Pos, Str, Offset, Count);
00456     return *this;
00457   }
00458 
00459   NString &NString::Insert (size_t Pos, const NString &Str)
00460   {
00461     m_string.insert (Pos, Str.m_string);
00462     return *this;
00463   }
00464 
00465   NString &NString::Insert (size_t Pos, const NString &Str, size_t Offset, size_t Count)
00466   {
00467     m_string.insert (Pos, Str.m_string, Offset, Count);
00468     return *this;
00469   }
00470 
00471   NString &NString::Insert (size_t Pos, int Count, const TCHAR &Ch)
00472   {
00473     m_string.insert (Pos, Count, Ch);
00474     return *this;
00475   }
00476 
00477   const TCHAR &NString::operator[] (size_t ChPos) const
00478   {
00479     return m_string[ChPos];
00480   }
00481 
00482   TCHAR &NString::operator[] (size_t ChPos)
00483   {
00484     return m_string[ChPos];
00485   }
00486 
00487   NString &NString::Replace (size_t Pos1, size_t Num1, const TCHAR *Ptr)
00488   {
00489     m_string.replace (Pos1, Num1, Ptr);
00490     return *this;
00491   }
00492 
00493   NString &NString::Replace (size_t Pos1, size_t Num1, const TCHAR *Ptr, size_t Num2)
00494   {
00495     m_string.replace (Pos1, Num1, Ptr, Num2);
00496     return *this;
00497   }
00498 
00499   NString &NString::Replace (size_t Pos1, size_t Num1, const tstring &Str)
00500   {
00501     m_string.replace (Pos1, Num1, Str);
00502     return *this;
00503   }
00504 
00505   NString &NString::Replace (size_t Pos1, size_t Num1, const tstring &Str, size_t Pos2, size_t Num2)
00506   {
00507     m_string.replace (Pos1, Num1, Str, Pos2, Num2);
00508     return *this;
00509   }
00510 
00511   NString &NString::Replace (size_t Pos1, size_t Num1, const NString &Str)
00512   {
00513     m_string.replace (Pos1, Num1, Str.m_string);
00514     return *this;
00515   }
00516 
00517   NString &NString::Replace (size_t Pos1, size_t Num1, const NString &Str, size_t Pos2, size_t Num2)
00518   {
00519     m_string.replace (Pos1, Num1, Str.m_string, Pos2, Num2);
00520     return *this;
00521   }
00522 
00523   NString &NString::Replace (size_t Pos1, size_t Num1, size_t Count, TCHAR Ch)
00524   {
00525     m_string.replace (Pos1, Num1, Count, Ch);
00526     return *this;
00527   }
00528 
00529   void NString::Reverse()
00530   {
00531     NString rev;
00532     size_t l = Length();
00533 
00534     for (size_t i = l - 1; i >= 0; i--)
00535     {
00536       rev += m_string[i];
00537     }
00538 
00539     (*this) = rev;
00540   }
00541 
00542   NString &NString::SearchAndReplace (TCHAR ChOut, TCHAR ChIn)
00543   {
00544     for (size_t i = 0; i < Length(); i++)
00545       if (m_string[i] == ChOut)
00546         m_string[i] = ChIn;
00547 
00548     return *this;
00549   }
00550 
00552   size_t NString::FindLastOccurence (const TCHAR &suffix) const
00553   {
00554     size_t start = 0;
00555     size_t pos = 0;
00556 
00557     do
00558     {
00559       pos = m_string.find (suffix, start);
00560 
00561       if (pos != tstring::npos)
00562         start = pos + 1;
00563     }
00564     while (pos != tstring::npos);
00565 
00566     return start - 1;
00567   }
00568 
00570   size_t NString::FindLastOccurence (const TCHAR *suffix) const
00571   {
00572     size_t start = 0;
00573     size_t pos = 0;
00574 
00575     do
00576     {
00577       pos = m_string.find (suffix, start);
00578 
00579       if (pos != tstring::npos)
00580         start = pos + 1;
00581     }
00582     while (pos != tstring::npos);
00583 
00584     return start - 1;
00585   }
00586 
00588   size_t NString::FindLastOccurence (const tstring &suffix) const
00589   {
00590     size_t start = 0;
00591     size_t pos = 0;
00592 
00593     do
00594     {
00595       pos = m_string.find (suffix, start);
00596 
00597       if (pos != tstring::npos)
00598         start = pos + 1;
00599     }
00600     while (pos != tstring::npos);
00601 
00602     return start - 1;
00603   }
00604 
00606   size_t NString::FindLastOccurence (const NString &suffix) const
00607   {
00608     size_t start = 0;
00609     size_t pos = 0;
00610 
00611     do
00612     {
00613       pos = m_string.find (suffix.m_string, start);
00614 
00615       if (pos != tstring::npos)
00616         start = pos + 1;
00617     }
00618     while (pos != tstring::npos);
00619 
00620     return start - 1;
00621   }
00622 
00623 
00625   size_t NString::FindFirstOccurence (const TCHAR &suffix)  const
00626   {
00627     size_t pos = 0;
00628     pos = m_string.find (suffix, pos);
00629     return (pos != tstring::npos) ? pos : -1;
00630   }
00631 
00633   size_t NString::FindFirstOccurence (const TCHAR *suffix)  const
00634   {
00635     size_t pos = 0;
00636     pos = m_string.find (suffix, pos);
00637     return (pos != tstring::npos) ? pos : -1;
00638   }
00639 
00641   size_t NString::FindFirstOccurence (const tstring &suffix)  const
00642   {
00643     size_t pos = 0;
00644     pos = m_string.find (suffix, pos);
00645     return (pos != tstring::npos) ? pos : -1;
00646   }
00647 
00649   size_t NString::FindFirstOccurence (const NString &suffix) const
00650   {
00651     size_t pos = 0;
00652     pos = m_string.find (suffix.m_string, pos);
00653     return (pos != tstring::npos) ? pos : -1;
00654   }
00655 
00657   size_t NString::FindNextOccurence (const TCHAR &suffix, size_t start) const
00658   {
00659     size_t pos = 0;
00660     pos = m_string.find (suffix, start);
00661     return (pos != tstring::npos) ? pos : -1;
00662   }
00663 
00665   size_t NString::FindNextOccurence (const TCHAR *suffix, size_t start) const
00666   {
00667     size_t pos = 0;
00668     pos = m_string.find (suffix, start);
00669     return (pos != tstring::npos) ? pos : -1;
00670   }
00671 
00673   size_t NString::FindNextOccurence (const tstring &suffix, size_t start) const
00674   {
00675     size_t pos = 0;
00676     pos = m_string.find (suffix, start);
00677     return (pos != tstring::npos) ? pos : -1;
00678   }
00679 
00681   size_t NString::FindNextOccurence (const NString &suffix, size_t start) const
00682   {
00683     size_t pos = 0;
00684     pos = m_string.find (suffix.m_string, start);
00685     return (pos != tstring::npos) ? pos : -1;
00686   }
00687 
00689   size_t NString::FindFirstOccurenceOf (const TCHAR &str) const
00690   {
00691     size_t pos = 0;
00692     pos = m_string.find_first_of (str, pos);
00693     return (pos != tstring::npos) ? pos : -1;
00694   }
00696   size_t NString::FindFirstOccurenceOf (const TCHAR *str) const
00697   {
00698     size_t pos = 0;
00699     pos = m_string.find_first_of (str, pos);
00700     return (pos != tstring::npos) ? pos : -1;
00701   }
00703   size_t NString::FindFirstOccurenceOf (const tstring &str) const
00704   {
00705     size_t pos = 0;
00706     pos = m_string.find_first_of (str, pos);
00707     return (pos != tstring::npos) ? pos : -1;
00708   }
00710   size_t NString::FindFirstOccurenceOf (const NString &str) const
00711   {
00712     size_t pos = 0;
00713     pos = m_string.find_first_of (str.m_string, pos);
00714     return (pos != tstring::npos) ? pos : -1;
00715   }
00716 
00718   size_t NString::FindLastOccurenceOf (const TCHAR &str) const
00719   {
00720     size_t pos = 0;
00721     pos = m_string.find_last_of (str, pos);
00722     return (pos != tstring::npos) ? pos : -1;
00723   }
00725   size_t NString::FindLastOccurenceOf (const TCHAR *str) const
00726   {
00727     size_t pos = 0;
00728     pos = m_string.find_last_of (str, pos);
00729     return (pos != tstring::npos) ? pos : -1;
00730   }
00732   size_t NString::FindLastOccurenceOf (const tstring &str) const
00733   {
00734     size_t pos = 0;
00735     pos = m_string.find_last_of (str, pos);
00736     return (pos != tstring::npos) ? pos : -1;
00737   }
00739   size_t NString::FindLastOccurenceOf (const NString &str) const
00740   {
00741     size_t pos = 0;
00742     pos = m_string.find_last_of (str.m_string, pos);
00743     return (pos != tstring::npos) ? pos : -1;
00744   }
00745 
00746   size_t NString::Find (NString str, int start)
00747   {
00748     size_t pos = m_string.find (str.m_string, start);
00749     return (pos != tstring::npos) ? pos : -1;
00750   }
00751 
00752   size_t NString::Find (TCHAR c, int start)
00753   {
00754     size_t pos = m_string.find (c, start);
00755     return (pos != tstring::npos) ? pos : -1;
00756   }
00757 
00758   bool NString::IsSuffix (const TCHAR &suffix)
00759   {
00760     size_t l = m_string.length() - 1;
00761 
00762     if (l < 0)
00763       return false;
00764 
00765     size_t pos = FindLastOccurence (suffix);
00766 
00767     if (pos == tstring::npos)
00768       return false;
00769 
00770     return (pos == l);
00771   }
00772 
00773   bool NString::IsSuffix (const TCHAR *suffix)
00774   {
00775     size_t sl = StringLength (suffix);
00776 
00777     if (sl == 0)
00778       return false;
00779 
00780     size_t l = m_string.length() - sl;
00781 
00782     if (l < 0)
00783       return false;
00784 
00785     size_t pos = FindLastOccurence (suffix);
00786 
00787     if (pos == tstring::npos)
00788       return false;
00789 
00790     return (pos == l);
00791   }
00792 
00794   bool NString::IsSuffix (const tstring &suffix)
00795   {
00796     size_t sl = suffix.length();
00797 
00798     if (sl == 0)
00799       return false;
00800 
00801     size_t l = m_string.length() - sl;
00802 
00803     if (l < 0)
00804       return false;
00805 
00806     size_t pos = FindLastOccurence (suffix);
00807 
00808     if (pos == tstring::npos)
00809       return false;
00810 
00811     return (pos == l);
00812   }
00813 
00815   bool NString::IsSuffix (const NString &suffix)
00816   {
00817     size_t sl = suffix.Length();
00818 
00819     if (sl == 0)
00820       return false;
00821 
00822     size_t l = m_string.length() - sl;
00823 
00824     if (l < 0)
00825       return false;
00826 
00827     size_t pos = FindLastOccurence (suffix);
00828 
00829     if (pos == tstring::npos)
00830       return false;
00831 
00832     return (pos == l);
00833   }
00834 
00836   bool NString::IsPrefix (const TCHAR &prefix)
00837   {
00838     size_t l = m_string.length() - 1;
00839 
00840     if (l < 0)
00841       return false;
00842 
00843     size_t pos = FindFirstOccurence (prefix);
00844 
00845     if (pos == tstring::npos)
00846       return false;
00847 
00848     return (pos == 0);
00849   }
00850 
00852   bool NString::IsPrefix (const TCHAR *prefix)
00853   {
00854     size_t sl = StringLength (prefix);
00855 
00856     if (sl == 0)
00857       return false;
00858 
00859     size_t pos = FindFirstOccurence (prefix);
00860 
00861     if (pos == tstring::npos)
00862       return false;
00863 
00864     return (pos == 0);
00865   }
00866 
00868   bool NString::IsPrefix (const tstring &prefix)
00869   {
00870     size_t sl = prefix.length();
00871 
00872     if (sl == 0)
00873       return false;
00874 
00875     size_t pos = FindFirstOccurence (prefix);
00876 
00877     if (pos == tstring::npos)
00878       return false;
00879 
00880     return (pos == 0);
00881   }
00883   bool NString::IsPrefix (const NString &prefix)
00884   {
00885     size_t sl = prefix.Length();
00886 
00887     if (sl == 0)
00888       return false;
00889 
00890     size_t pos = FindFirstOccurence (prefix);
00891 
00892     if (pos == tstring::npos)
00893       return false;
00894 
00895     return (pos == 0);
00896   }
00897 
00899   void NString::RemoveSuffix (const TCHAR &suffix)
00900   {
00901     if (IsSuffix (suffix) )
00902     {
00903       size_t pos = FindLastOccurence (suffix);
00904       *this = NString (m_string.substr (0, pos) );
00905     }
00906   }
00907 
00909   void NString::RemoveSuffix (const TCHAR *suffix)
00910   {
00911     if (IsSuffix (suffix) )
00912     {
00913       size_t pos = FindLastOccurence (suffix);
00914       *this = NString (m_string.substr (0, pos) );
00915     }
00916   }
00917 
00919   void NString::RemoveSuffix (const tstring &suffix)
00920   {
00921     if (IsSuffix (suffix) )
00922     {
00923       size_t pos = FindLastOccurence (suffix);
00924       *this = NString (m_string.substr (0, pos) );
00925     }
00926   }
00927 
00929   void NString::RemoveSuffix (const NString &suffix)
00930   {
00931     if (IsSuffix (suffix) )
00932     {
00933       size_t pos = FindLastOccurence (suffix);
00934       *this = NString (m_string.substr (0, pos) );
00935     }
00936   }
00937 
00939   void NString::RemovePrefix (const TCHAR &prefix)
00940   {
00941     if (IsPrefix (prefix) )
00942     {
00943       *this = NString (m_string.substr (1) );
00944     }
00945   }
00946 
00948   void NString::RemovePrefix (const TCHAR *prefix)
00949   {
00950     if (IsPrefix (prefix) )
00951     {
00952       size_t l = StringLength (prefix);
00953       *this = NString (m_string.substr (l) );
00954     }
00955   }
00956 
00958   void NString::RemovePrefix (const tstring &prefix)
00959   {
00960     if (IsPrefix (prefix) )
00961     {
00962       size_t l = prefix.length();
00963       *this = NString (m_string.substr (l) );
00964     }
00965   }
00966 
00968   void NString::RemovePrefix (const NString &prefix)
00969   {
00970     if (IsPrefix (prefix) )
00971     {
00972       size_t l = prefix.Length();
00973       *this = NString (m_string.substr (l) );
00974     }
00975   }
00976 
00977   NString NString::GetSubString (size_t count) const
00978   {
00979     nuxAssert (count >= 0);
00980     return NString (m_string.substr (0, count) );
00981   }
00982 
00983   NString NString::GetSubString (size_t start, size_t count) const
00984   {
00985     nuxAssert (start >= 0);
00986     nuxAssert (count >= 0);
00987     return NString (m_string.substr (start, count) );
00988   }
00989 
00990   NString NString::Mid (size_t count) const
00991   {
00992     return GetSubString (count);
00993   }
00994 
00995   NString NString::Mid (size_t start, size_t count) const
00996   {
00997     return GetSubString (start, count);
00998   }
00999 
01000   NString NString::Left (size_t N) const
01001   {
01002     if (N >= Length() )
01003       return *this;
01004 
01005     return GetSubString (0, N);
01006   }
01007 
01008   NString NString::Right (size_t N) const
01009   {
01010     if (N >= Length() )
01011       return *this;
01012 
01013     return GetSubString (Length() - N, N);
01014   }
01015 
01016   NString NString::Trim() const
01017   {
01018     return TrimLeft().TrimRight();
01019   }
01020 
01021   NString NString::TrimLeft() const
01022   {
01023     size_t n = 0;
01024     size_t L = Length() - 1;
01025 
01026     while (n <= L)
01027     {
01028       if (IsWhitespaceChar (m_string[n]) )
01029       {
01030         n++;
01031       }
01032       else
01033       {
01034         break;
01035       }
01036     }
01037 
01038     return GetSubString (n, Length() - n);
01039   }
01040 
01041   NString NString::TrimRight() const
01042   {
01043     size_t L = Length() - 1;
01044 
01045     while (0 <= L)
01046     {
01047       if (IsWhitespaceChar (m_string[L]) )
01048       {
01049         L--;
01050       }
01051       else
01052       {
01053         break;
01054       }
01055     }
01056 
01057     return GetSubString (0, Length() + 1);
01058   }
01059 
01060   NString NString::TrimLeft (NString str) const
01061   {
01062     size_t n = 0;
01063     size_t L = Length();
01064 
01065     if (L == 0)
01066       return *this;
01067 
01068     while (n < L)
01069     {
01070       bool trim = false;
01071       size_t sz = str.Length();
01072 
01073       for (size_t i = 0; i < sz; i++)
01074       {
01075         if (m_string[n] == str[i])
01076         {
01077           trim = true;
01078           break;
01079         }
01080       }
01081 
01082       if (trim)
01083       {
01084         n++;
01085       }
01086       else
01087       {
01088         break;
01089       }
01090     }
01091 
01092     return GetSubString (n, Length() - n);
01093   }
01094 
01095   NString NString::TrimRight (NString str) const
01096   {
01097     size_t L = Length();
01098 
01099     if (L == 0)
01100       return *this;
01101 
01102     L = L - 1;
01103 
01104     while (0 <= L)
01105     {
01106       bool trim = false;
01107       size_t sz = str.Length();
01108 
01109       for (size_t i = 0; i < sz; i++)
01110       {
01111         if (m_string[L] == str[i])
01112         {
01113           trim = true;
01114           break;
01115         }
01116       }
01117 
01118       if (trim)
01119       {
01120         L--;
01121       }
01122       else
01123       {
01124         break;
01125       }
01126     }
01127 
01128     return GetSubString (0, L + 1);
01129   }
01130 
01131   const TCHAR *NString::operator () () const
01132   {
01133     if (Size() == 0)
01134       return 0;
01135 
01136     return GetTCharPtr();
01137   }
01138 
01139   const TCHAR *NString::operator * () const
01140   {
01141     if (Size() == 0)
01142       return 0;
01143 
01144     return GetTCharPtr();
01145   }
01146 
01147 // NString::operator const TCHAR*() const
01148 // {
01149 //     return (const TCHAR*)GetTCharPtr();
01150 // }
01151 
01152   NString &NString::operator += (const TCHAR &sufix)
01153   {
01154     m_string += sufix;
01155     return *this;
01156   }
01157 
01158   NString &NString::operator += (const TCHAR *sufix)
01159   {
01160     m_string += sufix;
01161     return *this;
01162   }
01163 
01164   NString &NString::operator += (const tstring sufix)
01165   {
01166     m_string += sufix;
01167     return *this;
01168   }
01169 
01170   NString &NString::operator += (const NString sufix)
01171   {
01172     m_string += sufix.m_string;
01173     return *this;
01174   }
01175 
01176   void NString::SplitAtFirstOccurenceOf (const TCHAR *SplitString, NString &Left, NString &Right)
01177   {
01178     size_t start = FindFirstOccurence (SplitString);
01179 
01180     if (start != tstring::npos)
01181     {
01182       size_t size = StringLength (SplitString);
01183       Left = GetSubString (0, start);
01184       Right = GetSubString (start + size, Length() - (start + size) );
01185     }
01186     else
01187     {
01188       Left = *this;
01189       Right = "";
01190     }
01191   }
01192 
01193   void NString::SplitAtFirstOccurenceOf (const TCHAR &SplitChar, NString &Left, NString &Right)
01194   {
01195     SplitAtFirstOccurenceOf (NString (SplitChar), Left, Right);
01196   }
01197 
01198   void NString::SplitAtFirstOccurenceOf (const NString &SplitString, NString &Left, NString &Right)
01199   {
01200     SplitAtFirstOccurenceOf (SplitString.GetTCharPtr(), Left, Right);
01201   }
01202 
01203   void NString::SplitAtLastOccurenceOf (const TCHAR *SplitString, NString &Left, NString &Right)
01204   {
01205     size_t start = FindLastOccurence (SplitString);
01206 
01207     if (start != tstring::npos)
01208     {
01209       size_t size = StringLength (SplitString);
01210       Left = GetSubString (0, start);
01211       Right = GetSubString (start + size, Length() - (start + size) );
01212     }
01213     else
01214     {
01215       Left = *this;
01216       Right = "";
01217     }
01218   }
01219 
01220   void NString::SplitAtLastOccurenceOf (const TCHAR &SplitChar, NString &Left, NString &Right)
01221   {
01222     SplitAtLastOccurenceOf (NString (SplitChar), Left, Right);
01223   }
01224 
01225   void NString::SplitAtLastOccurenceOf (const NString &SplitString, NString &Left, NString &Right)
01226   {
01227     SplitAtLastOccurenceOf (SplitString.GetTCharPtr(), Left, Right);
01228   }
01229 
01230   void NString::ParseToArray (std::vector<NString>& StringArray, const NString &delimiter)
01231   {
01232     NString Left;
01233     NString Right;
01234     NString Temp;
01235     SplitAtFirstOccurenceOf (delimiter, Left, Temp);
01236 
01237     if (Left.Size() )
01238     {
01239       Left = Left.Trim();
01240       StringArray.push_back (Left);
01241     }
01242 
01243     Right = Temp;
01244 
01245     while (Right.Size() )
01246     {
01247       Right.SplitAtFirstOccurenceOf (delimiter, Left, Temp);
01248 
01249       if (Left.Size() )
01250       {
01251         Left = Left.Trim();
01252         StringArray.push_back (Left);
01253       }
01254 
01255       Right = Temp;
01256     }
01257   }
01258 
01259   TCHAR NString::GetFirstChar() const
01260   {
01261     if (IsEmpty() )
01262       return 0;
01263     return m_string[0];
01264   }
01265 
01266   TCHAR NString::GetLastChar() const
01267   {
01268     if (IsEmpty() )
01269       return 0;
01270     return m_string[Size()-1];
01271   }
01272 
01273   bool operator != (const NString &left, const NString &right)
01274   {
01275     return left.m_string != right.m_string;
01276   }
01277   bool operator == (const NString &left, const NString &right)
01278   {
01279     return left.m_string == right.m_string;
01280   }
01281   bool operator <  (const NString &left, const NString &right)
01282   {
01283     return left.m_string < right.m_string;
01284   }
01285   bool operator <= (const NString &left, const NString &right)
01286   {
01287     return left.m_string <= right.m_string;
01288   }
01289   bool operator >  (const NString &left, const NString &right)
01290   {
01291     return left.m_string > right.m_string;
01292   }
01293   bool operator >= (const NString &left, const NString &right)
01294   {
01295     return left.m_string >= right.m_string;
01296   }
01297 
01298   NString operator+ (const NString &left, const NString &right)
01299   {
01300     return NString (left.m_string + right.m_string);
01301   }
01302 
01303   NString operator+ (const NString &left, const TCHAR *right)
01304   {
01305     return NString (left.m_string + right);
01306   }
01307 
01308   NString operator+ (const NString &left, const TCHAR right)
01309   {
01310     return NString (left.m_string + right);
01311   }
01312 
01313   NString operator+ (const TCHAR *left, const NString &right)
01314   {
01315     return NString (left + right.m_string);
01316   }
01317 
01318   NString operator+ (const TCHAR left, const NString &right)
01319   {
01320     return NString (left + right.m_string);
01321   }
01322 
01323   tostream &operator << (tostream &o, const NString &s)
01324   {
01325     return o << s.m_string;
01326   }
01327 
01333   VARARG_BODY (NString, NString::Printf, const TCHAR *, VARARG_NONE)
01334   {
01335     unsigned int  BufferSize  = 1024;
01336     TCHAR *Buffer      = NULL;
01337     size_t Result      = tstring::npos;
01338 
01339     while (Result == tstring::npos)
01340     {
01341       Buffer = (TCHAR *) Realloc (Buffer, BufferSize * sizeof (TCHAR) );
01342       GET_VARARGS_RESULT (Buffer, BufferSize, BufferSize - 1, Fmt, Result);
01343       BufferSize *= 2;
01344     };
01345 
01346     Buffer[Result] = 0;
01347 
01348     NString ResultString (Buffer);
01349 
01350     free (Buffer);
01351 
01352     return ResultString;
01353   }
01354 
01355 }