home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ool.zip / OOL / source / Xstring.cpp < prev    next >
C/C++ Source or Header  |  1997-04-08  |  37KB  |  1,463 lines

  1. /****************************************************************************************
  2.  
  3. XString
  4.  
  5. (c) 1996 by Jens von Pilgrim
  6.  
  7. Details: See header file
  8.  
  9. History:
  10.  
  11. Note: in Strip: while-loops (correct for non-short-evaluation... (first<length)
  12.  
  13. *****************************************************************************************/
  14. // #define _BUILD_DLL_
  15.  
  16. // #include "stdio.h"      // only for testing...
  17.  
  18. // #include "stdafx.h"
  19.  
  20. //#include "XLib.h"
  21. #include "XString.h"
  22.  
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26.  
  27. /*@ XString::StrCmp(const XString &inThen)
  28. @group Comperasion
  29. @remarks Returns exactly the result from strcmp, usefull if other function needs this result.
  30. The Result is
  31.  
  32. == 0: this string == inThen
  33.  
  34.  < 0: this string < inThen
  35.  
  36.  > 0: this string > inThen
  37. */
  38. int XString::StrCmp(const XString &inThen) const
  39. { X_ASSERT(m_pszChar!=NULL);
  40.   X_ASSERT( inThen.m_pszChar!=NULL);
  41.   
  42.   return strcmp(m_pszChar, inThen.m_pszChar);
  43. }
  44.  
  45.  
  46.  
  47. /*@ XString::XString()
  48. @group Constructor/Destructor
  49. @remarks Constructs an empty string
  50. */
  51. XString::XString()
  52. {
  53.   m_pszChar = (char *) malloc(1);
  54.   X_ASSERT(m_pszChar != NULL);  
  55.   m_pszChar[0] = '\0';
  56.   m_Length = 0;
  57.   m_isNULL = TRUE;
  58.  
  59. }
  60.  
  61. /*@ XString::XString(const XString &aString)
  62. @group Constructor/Destructor
  63. @remarks Constructs a string as a copy of 'aString'
  64. */
  65. XString::XString(const XString &aString)
  66. {
  67.   X_ASSERT(&aString != NULL);
  68.   X_ASSERT(&aString.m_pszChar != NULL);
  69.    
  70.   m_Length = aString.m_Length;
  71.   m_isNULL = aString.m_isNULL;      
  72.  
  73.   m_pszChar = (char *) malloc(m_Length+1);
  74.   X_ASSERT(m_pszChar != NULL);
  75.    
  76.   memcpy(m_pszChar, aString.m_pszChar, m_Length+1);
  77.  
  78.   X_ASSERT(m_Length == strlen(m_pszChar));
  79. }
  80.  
  81. /*@ XString::XString(char *pszChar)
  82. @group Constructor/Destructor
  83. @remarks Constructs a string as a copy of pszChar, usefull as caster
  84. */
  85. XString::XString(char *pszChar)
  86. {
  87.     X_ASSERT(pszChar != NULL);
  88.     m_Length = strlen(pszChar);
  89.     m_pszChar = (char *) malloc(m_Length+1);
  90.     X_ASSERT(m_pszChar != NULL);
  91.    
  92.     memcpy(m_pszChar, pszChar, m_Length+1);
  93.  
  94.     X_ASSERT(GetLength() == strlen(m_pszChar));
  95.     m_isNULL = FALSE;
  96. }
  97.  
  98.  
  99.  
  100.  
  101. XString::XString(const char *pszChar)
  102. {
  103.     X_ASSERT(pszChar != NULL);
  104.     m_Length = strlen(pszChar);
  105.     m_pszChar = (char *) malloc(m_Length+1);
  106.     X_ASSERT(m_pszChar != NULL);
  107.    
  108.     memcpy(m_pszChar, pszChar, m_Length+1);
  109.  
  110.     X_ASSERT(GetLength() == strlen(m_pszChar));
  111.     m_isNULL = FALSE;
  112. }
  113.  
  114. XString::XString(char *pszChar, int duplicate)
  115. {
  116.     if (pszChar != NULL) m_Length = strlen(pszChar);
  117.     else m_Length = 0;
  118.     m_pszChar = pszChar;
  119.     m_isNULL = FALSE;
  120. }
  121.  
  122.  
  123. /*@  XString::XString(char aChar)
  124. @group Constructor/Destructor
  125. @remarks Constructs a string with first char == aChar
  126. */
  127. XString::XString(char aChar)
  128. {
  129.   m_Length = 1;
  130.   m_pszChar = (char *) malloc(m_Length+1);
  131.     X_ASSERT(m_pszChar != NULL);
  132.    
  133.   m_pszChar[0] = aChar;
  134.   m_pszChar[1] = '\0';
  135.  
  136.   X_ASSERT(m_Length == strlen(m_pszChar));
  137.   m_isNULL = FALSE;
  138. }
  139.  
  140. /*@  XString::XString(int aNumber, int Radix)
  141. @group Constructor/Destructor
  142. @remarks Constructs a string and casts an int, usefull as caster
  143. */
  144. XString::XString(int aNumber, int Radix)
  145. { m_pszChar = (char *) malloc(20);
  146.   _itoa(aNumber, m_pszChar, Radix);
  147.   m_Length = strlen(m_pszChar);
  148.   ReleaseBuffer();
  149.   m_isNULL = FALSE;
  150. }
  151.  
  152. /*@  XString::XString(long aNumber, int Radix)
  153. @group Constructor/Destructor
  154. @remarks Constructs a string and casts an int, usefull as caster
  155. */
  156. XString::XString(long aNumber, int Radix)
  157. { m_pszChar = (char *) malloc(40);
  158.   _ltoa(aNumber, m_pszChar, Radix);
  159.   m_Length = strlen(m_pszChar);
  160.   ReleaseBuffer();
  161.   FALSE;
  162. }
  163.  
  164. /*@  XString::~XString()
  165. @group Constructor/Destructor
  166. @remarks (Virtual) Destructor, removes string from memory
  167. */
  168. XString::~XString()
  169. {
  170.   X_ASSERT (m_pszChar != NULL);
  171.   free(m_pszChar);
  172. }
  173.  
  174.  
  175.  
  176. /*@ XString::operator =(const XString &aString)
  177. @group Set
  178. @returns Returns copy of aString
  179. @remarks The Sourcestring aString is copied (duplicated) to this-string
  180. */
  181. XString XString::operator =(const XString &aString)
  182. {
  183.   X_ASSERT(aString.m_pszChar != NULL);
  184.   X_ASSERT(aString.m_Length == strlen(aString.m_pszChar));
  185.  
  186.   free(m_pszChar);
  187.   m_Length = aString.m_Length;
  188.   m_pszChar = (char *) malloc(m_Length+1);
  189.   X_ASSERT(m_pszChar != NULL);
  190.   
  191.   memcpy(m_pszChar, aString.m_pszChar, m_Length+1);
  192.  
  193.   X_ASSERT(m_Length == strlen(m_pszChar));
  194.   m_isNULL = aString.m_isNULL;
  195.  
  196.   return *this;
  197. }
  198.  
  199.  
  200. /*@ XString::operator() (XSIZE_T inCount)
  201. @group Get
  202. @returns Returns a pointer to chars.
  203. @remarks Usefull in functions requiering char-pointer like
  204. printf (printf("Hallo %s", aString()); ). The method works like Left, so
  205. AString(5) returns the first 5 chars.
  206. */
  207. char* XString::operator() (XSIZE_T inCount)
  208. {
  209.   return Left(inCount)(0);
  210. }
  211.  
  212.  
  213. /*@ XString::operator() ()
  214. @group Get
  215. */
  216. /*
  217. const char *const XString::operator() () const
  218. { return m_pszChar;
  219. }
  220. */
  221.  
  222. /*@ XString::operator[] ()
  223. @group Get
  224. @remarks The same as function At. The first char has index 0!
  225. @returns Returns the char at position inZeroIndex.
  226. */
  227. char& XString::operator[](XSIZE_T inZeroIndex) const
  228. { X_ASSERT(inZeroIndex<m_Length);
  229.   return m_pszChar[inZeroIndex];
  230. }
  231.  
  232. char& XString::operator[] (int inZeroIndex) const
  233. { X_ASSERT(XSIZE_T(inZeroIndex)<m_Length);
  234.   return m_pszChar[inZeroIndex];
  235. }
  236.  
  237. /*@ XString::At ()
  238. @group Get
  239. @remarks The same as operator []. The first char has index 0!
  240. @returns Returns the char at position inZeroIndex.
  241. */
  242. char& XString::At(XSIZE_T inZeroIndex) const
  243. { X_ASSERT(inZeroIndex<m_Length);
  244.   return m_pszChar[inZeroIndex];
  245. }
  246.  
  247.  
  248.  
  249. /*@ XString::operator const int()
  250. @group Caster
  251. @returns String as a constant int, sometimes a const is required.
  252. Uses standard C-function atoi
  253. */
  254. XString::operator const int() const
  255. { X_ASSERT(m_pszChar != NULL);
  256.   return atoi(m_pszChar); 
  257. }
  258.  
  259. /*@ XString::operator const long()
  260. @group Caster
  261. @returns String as a constant long int, sometimes a const is required.
  262. REMARS Uses standard C-function atol
  263. */
  264. XString::operator const long() const
  265. { X_ASSERT(m_pszChar != NULL);
  266.   return atol(m_pszChar); 
  267. }
  268.  
  269. /*@ XString::operator const double()
  270. @group Caster
  271. @returns String as a constant float (double), sometimes a const is required.
  272. REMARS Uses standard C-function atof
  273. */
  274. XString::operator const double() const
  275. { X_ASSERT(m_pszChar != NULL);
  276.   return atof(m_pszChar); 
  277. }
  278.  
  279.  
  280. /*@ XString::operator +=(const XString &Str)
  281. @group Set
  282. @returns Returns thisString+Str
  283. REMARS Concats string with another string Str and saves the result in string.
  284. Like this:
  285.  
  286. XString a,b,c;
  287.  
  288. ...
  289.  
  290. a=(b+=c);
  291.  
  292. Result: (a==b) = TRUE
  293. */
  294. XString XString::operator +=(const XString &Str)
  295. {
  296.   m_isNULL = FALSE;
  297.  
  298.   X_ASSERT(Str.m_pszChar!=NULL);
  299.   X_ASSERT(m_pszChar!=NULL);
  300.   X_ASSERT(m_Length==strlen(m_pszChar));
  301.  
  302.   char *newChar = (char *) malloc(m_Length+Str.m_Length+1);
  303.  
  304.   X_ASSERT(newChar != NULL);
  305.  
  306.   memcpy(newChar, m_pszChar, m_Length);
  307.   memcpy(&newChar[m_Length], Str.m_pszChar, Str.m_Length + 1);
  308.  
  309.   free(m_pszChar);
  310.   m_pszChar = newChar;
  311.   m_Length += Str.m_Length;
  312.  
  313.   X_ASSERT(m_Length == strlen(m_pszChar));
  314.  
  315.   return *this;
  316. }
  317.  
  318.  
  319. /*@ XString::operator +=(const char *Str)
  320. @group Set
  321. @remarks Adds a string
  322. */
  323. XString XString::operator +=(const char *Str)
  324.   m_isNULL = FALSE;
  325.  
  326.   X_ASSERT(Str!=NULL);
  327.   X_ASSERT(m_pszChar!=NULL);
  328.   X_ASSERT(m_Length==strlen(m_pszChar));
  329.  
  330.   XSIZE_T length = strlen(Str);
  331.   char *newChar = (char *) malloc(m_Length+length+1);
  332.  
  333.   X_ASSERT(newChar != NULL);
  334.  
  335.   memcpy(newChar, m_pszChar, m_Length);
  336.   memcpy(&newChar[m_Length], Str, length + 1);
  337.  
  338.   free(m_pszChar);
  339.   m_pszChar = newChar;
  340.   m_Length += length;
  341.  
  342.  
  343.   X_ASSERT(m_Length == strlen(m_pszChar));
  344.  
  345.   return *this;
  346.  
  347.  
  348. }
  349.  
  350. /*@ XString::IsEmpty ()
  351. @group Comperasion
  352. @returns TRUE, if the String is empty
  353.  
  354. BOOL, else
  355. @remarks If the string is not allocated (f.e. a Stringpointer before calling new) is NOT empyt! If
  356. you call any String-Function before calling the Constructor, most functions fail and the program
  357. will exit by a failed assert!
  358. */
  359. BOOL XString::IsEmpty() const
  360. { return GetLength()==0; }
  361.  
  362.  
  363. void XString::MakeEmpty()
  364. {
  365.   m_pszChar = (char*) realloc(m_pszChar, 1);
  366.   X_ASSERT(m_pszChar != NULL);  
  367.   m_pszChar[0] = '\0';
  368.   m_Length = 0;
  369.   m_isNULL = FALSE;
  370. }
  371.  
  372.  
  373. BOOL XString::IsNULL() const
  374. {
  375.     return m_isNULL;
  376. }
  377.  
  378. void XString::MakeNULL()
  379. {
  380.     MakeEmpty();
  381.     m_isNULL = TRUE;
  382. }
  383.  
  384.  
  385. /*@ XString::Mid(XSIZE_T From, XSIZE_T Count)
  386. @group Get
  387. @returns Returns substring with Count-length from position From in string.
  388. @remarks If From>GetLength(), an empty string is returned; if From+Count>GetLength(),
  389. a string with a length of (GetLength()-From) is returned.
  390. */
  391. XString XString::Mid(XSIZE_T From, XSIZE_T Count) const
  392. {
  393.   X_ASSERT(m_pszChar != NULL);
  394.   X_ASSERT(m_Length == strlen(m_pszChar));
  395.  
  396.   if ((Count == 0) || (From>=m_Length)) return XString();
  397.   if (From+Count>m_Length) Count=m_Length-From;
  398.  
  399.   X_ASSERT (Count<=m_Length);
  400.  
  401.   XString Res(NULL, 1);
  402.   Res.m_pszChar = (char *) malloc(Count+1);
  403.  
  404.   X_ASSERT(Res.m_pszChar != NULL);
  405.  
  406.   memcpy(Res.m_pszChar, m_pszChar+From, Count);
  407.   Res.m_pszChar[Count]=0;
  408.   Res.m_Length = Count;
  409.  
  410.   X_ASSERT(Res.m_Length == strlen(Res.m_pszChar));
  411.  
  412.   return Res;
  413. }
  414.  
  415. /*@ XString::Left(XSIZE_T Count)
  416. @group Get
  417. @returns Returns the first Count chars as a XString from string. Thus, it's equal to Mid(0, nCount).
  418. @remarks If Count>GetLength(), a copy of the string is returned, if Count is 0, an empty string is returned.
  419. */
  420.  
  421. XString XString::Left(XSIZE_T Count) const
  422. {
  423.   X_ASSERT(m_pszChar != NULL);
  424.  
  425.   if (Count==0) return XString();
  426.  
  427.   if (Count>m_Length) Count=m_Length;
  428.  
  429.   XString Res(NULL, 1);
  430.   Res.m_Length = Count;
  431.   Res.m_pszChar = (char *) malloc(Count+1);
  432.  
  433.   X_ASSERT(Res.m_pszChar != NULL);
  434.  
  435.   memcpy(Res.m_pszChar, m_pszChar, Count);
  436.   Res.m_pszChar[Count]=0;
  437.  
  438.  X_ASSERT(Res.m_Length == strlen(Res.m_pszChar));
  439.  
  440.   return Res;
  441. }
  442.  
  443.  
  444. /*@ XString::Right(..)
  445. @group Get
  446. @remarks What do you think this methods is for? See Left() for details, rigth up!
  447. */
  448. XString XString::Right(XSIZE_T Count) const
  449. {
  450.   X_ASSERT(m_pszChar != NULL);
  451.  
  452.   if (Count==0) return XString();
  453.   if (Count>m_Length) Count=m_Length;
  454.  
  455.   XString Res(NULL, 1);
  456.   Res.m_Length = Count;
  457.   Res.m_pszChar = (char *) malloc(Count+1);
  458.  
  459.   X_ASSERT(Res.m_pszChar != NULL);
  460.  
  461.   memcpy(Res.m_pszChar, &m_pszChar[m_Length-Count], Count+1);
  462.   // abschließendes 0 wird mitkopiert
  463.  
  464.   X_ASSERT(Res.m_Length == strlen(Res.m_pszChar));
  465.  
  466.   return Res;
  467. }
  468.  
  469. /*@ XString::Find()
  470. @group Enhanced
  471. @returns TRUE, if substring is in string, outPos is the (zero-indexed) position of the substring in string (the first). BOOL, if the substring was not found
  472. @remarks Because some parameters have standard values, you can call this method also with Find(pos, "...").
  473. */
  474. BOOL XString::Find(XSIZE_T &outPos, const XString &SubString, XSIZE_T From, XSIZE_T inTo, BOOL inInCase) const
  475. { X_ASSERT (SubString.m_pszChar != NULL);
  476.  
  477.   if (inTo==0) inTo = GetLength();
  478.   if (inTo>GetLength()) inTo = GetLength();
  479.   if (inTo<From) return FALSE;
  480.  
  481.   X_ASSERT (m_pszChar!=NULL);
  482.  
  483.   if (SubString.m_Length==0) return FALSE;
  484.   if (SubString.m_Length>inTo-From) return FALSE;
  485.  
  486.   XSIZE_T StrI, SubI=0, 
  487.          SubLength=SubString.m_Length-1,
  488.          First;
  489.  
  490.   if (!inInCase)
  491.   {
  492.     for (StrI=From; StrI<inTo-SubLength; StrI++)
  493.     {
  494.         if (m_pszChar[StrI]==SubString.m_pszChar[SubI])
  495.         {    First = StrI;
  496.             do
  497.             {
  498.                 if (SubI == SubLength) { outPos = First; return TRUE; };
  499.                 SubI++;
  500.                 StrI++;
  501.             }   while (m_pszChar[StrI]==SubString.m_pszChar[SubI]);
  502.             SubI=0;
  503.             StrI = First; // !!, eg */ in ***/ nicht gefunden!
  504.         }
  505.     }
  506.   }
  507.   else  // Find InCase
  508.   {
  509.     for (StrI=From; StrI<inTo-SubLength; StrI++)
  510.     {
  511.         if (UpperChar(m_pszChar[StrI])==UpperChar(SubString.m_pszChar[SubI]))
  512.         {    First = StrI;
  513.             do
  514.             {
  515.                 if (SubI == SubLength) { outPos = First; return TRUE; };
  516.                 SubI++;
  517.                 StrI++;
  518.             }   while (UpperChar(m_pszChar[StrI])==UpperChar(SubString.m_pszChar[SubI]));
  519.             SubI=0;
  520.             StrI = First; // !!, eg */ in ***/ nicht gefunden!
  521.         }
  522.     }
  523.   }
  524.  
  525.      
  526.  
  527.   return FALSE;
  528. }
  529.  
  530.  
  531.  
  532.  
  533. /*@ XString::FindRev(XSIZE_T &outPos, const XString &SubString, XSIZE_T From = 0, XSIZE_T inTo = 0)
  534. @group Enhanced
  535. @returns TRUE, if substring is in string, outPos is the (zero-indexed) position of the substring in string (the first). BOOL, if the substring was not found
  536. @remarks Because some parameters have standard values, you can call this method also with Find(pos, "...").
  537. */
  538. BOOL XString::FindRev(XSIZE_T &outPos, const XString &SubString, XSIZE_T From, XSIZE_T inTo, BOOL inInCase) const
  539. { X_ASSERT (SubString.m_pszChar != NULL);
  540.   
  541.   if (inTo==0) inTo = GetLength();   
  542.   if (From>inTo) return FALSE;
  543.  
  544.   X_ASSERT (m_pszChar!=NULL);
  545.  
  546.   if (SubString.m_Length==0) return FALSE;
  547.   if (SubString.m_Length>inTo-From) return FALSE;
  548.  
  549.   XSIZE_T StrI, SubI=SubString.m_Length-1,
  550.          SubLength=SubString.m_Length-1,
  551.          First;
  552.  
  553.   if (!inInCase)
  554.   {      
  555.     for (StrI=inTo; StrI>From+SubLength; StrI--)
  556.     {
  557.         if (m_pszChar[StrI]==SubString.m_pszChar[SubI])
  558.         {    
  559.             First = StrI;
  560.             do
  561.             {
  562.                 if (SubI == 0) { outPos = First; return TRUE; };
  563.                 SubI--;
  564.                 StrI--;
  565.             }
  566.             while (m_pszChar[StrI]==SubString.m_pszChar[SubI]);
  567.             SubI=SubLength;
  568.             StrI = First; // !!, eg */ in ***/ nicht gefunden!
  569.         }
  570.     }
  571.   }
  572.   else    // FindRev InCase
  573.   {       
  574.     for (StrI=inTo; StrI>From+SubLength; StrI--)
  575.     {
  576.         if (UpperChar(m_pszChar[StrI])==UpperChar(SubString.m_pszChar[SubI]))
  577.         {    
  578.             First = StrI;
  579.             do
  580.             {
  581.                 if (SubI == 0) { outPos = First; return TRUE; };
  582.                 SubI--;
  583.                 StrI--;
  584.             }
  585.             while (UpperChar(m_pszChar[StrI])==UpperChar(SubString.m_pszChar[SubI]));
  586.             SubI=SubLength;
  587.             StrI = First; // !!, eg */ in ***/ nicht gefunden!
  588.         }
  589.     }
  590.   }
  591.   
  592.   return FALSE;
  593. }
  594.  
  595. BOOL XString::Search(const XString &SubString, XSIZE_T From, XSIZE_T inTo, BOOL inInCase) const
  596. {  XSIZE_T dummy;
  597.     return Find(dummy, SubString, From, inTo, inInCase);
  598. }
  599.  
  600.  
  601. BOOL XString::SearchRev(const XString &SubString, XSIZE_T From, XSIZE_T inTo, BOOL inInCase) const
  602. {  XSIZE_T dummy;
  603.    return FindRev(dummy, SubString, From, inTo, inInCase);
  604. }
  605.  
  606.  
  607. BOOL XString::FindWhitespace ( XSIZE_T &outPos, XSIZE_T inFrom, XSIZE_T inTo) const
  608. {
  609.     if (inTo==0) inTo = GetLength();
  610.     if (inFrom>inTo) return FALSE;
  611.     
  612.  
  613.     X_ASSERT (m_pszChar!=NULL);
  614.  
  615.     outPos = inFrom;
  616.  
  617.     while ( outPos < GetLength() )
  618.     {
  619.         if ( isspace( At ( outPos ) ) ) return TRUE;
  620.         outPos ++;
  621.     }
  622.     return FALSE;
  623. }
  624.  
  625. BOOL XString::FindAlpha ( XSIZE_T &outPos, XSIZE_T inFrom, XSIZE_T inTo) const
  626. {
  627.     if (inTo==0) inTo = GetLength();
  628.     if (inFrom>inTo) return FALSE;
  629.     
  630.  
  631.     X_ASSERT (m_pszChar!=NULL);
  632.  
  633.     outPos = inFrom;
  634.  
  635.     while ( outPos < GetLength() )
  636.     {
  637.         if ( isalpha( At ( outPos ) ) ) return TRUE;
  638.         outPos ++;
  639.     }
  640.     return FALSE;
  641. }
  642.  
  643. BOOL XString::FindNonAlpha ( XSIZE_T &outPos, XSIZE_T inFrom , XSIZE_T inTo) const
  644. {
  645.     if (inTo==0) inTo = GetLength();
  646.     if (inFrom>inTo) return FALSE;
  647.     
  648.  
  649.     X_ASSERT (m_pszChar!=NULL);
  650.  
  651.     outPos = inFrom;
  652.  
  653.     while ( outPos < GetLength() )
  654.     {
  655.         if ( !isalpha( At ( outPos ) ) ) return TRUE;
  656.         outPos ++;
  657.     }
  658.     return FALSE;
  659. }
  660.  
  661. BOOL XString::SearchAlpha( XSIZE_T inFrom, XSIZE_T inTo ) const
  662. {
  663.     if (inTo==0) inTo = GetLength();
  664.     if (inFrom>inTo) return FALSE;
  665.     
  666.  
  667.     X_ASSERT (m_pszChar!=NULL);
  668.  
  669.     inFrom;
  670.  
  671.     while ( inFrom < GetLength() )
  672.     {
  673.         if ( isalpha( At ( inFrom ) ) ) return TRUE;
  674.         inFrom ++;
  675.     }
  676.     return FALSE;
  677. }
  678.  
  679.  
  680. BOOL XString::SearchNonAlpha ( XSIZE_T inFrom , XSIZE_T inTo ) const
  681. {
  682.     if (inTo==0) inTo = GetLength();
  683.     if (inFrom>inTo) return FALSE;
  684.     
  685.  
  686.     X_ASSERT (m_pszChar!=NULL);
  687.  
  688.     inFrom;
  689.  
  690.     while ( inFrom < GetLength() )
  691.     {
  692.         if ( !isalpha( At ( inFrom ) ) ) return TRUE;
  693.         inFrom ++;
  694.     }
  695.     return FALSE;
  696. }
  697.  
  698.  
  699. BOOL XString::SearchWhitespace ( XSIZE_T inFrom, XSIZE_T inTo) const
  700. {
  701.     if (inTo==0) inTo = GetLength();
  702.     if (inFrom>inTo) return FALSE;
  703.     
  704.  
  705.     X_ASSERT (m_pszChar!=NULL);
  706.  
  707.     inFrom;
  708.  
  709.     while ( inFrom < GetLength() )
  710.     {
  711.         if ( isspace( At ( inFrom ) ) ) return TRUE;
  712.         inFrom ++;
  713.     }
  714.     return FALSE;
  715. }
  716.  
  717.  
  718. /*@ XString::GetLength()
  719. @group Get
  720. @remarks Returns the length of the string!
  721. */
  722. XSIZE_T XString::GetLength() const
  723. { return m_Length; }
  724.  
  725.  
  726. /*@ XString::GetBuffer(XSIZE_T Size)
  727. @group Caster
  728. @remarks This is the most dangerous function, because it allows you access to the heart of XString, the
  729. char-buffer! Don't use this function for dircet manipulations of the buffer! This function has
  730. another job to do!
  731.  
  732. The job of this method is to work as a caster, when some awefull and dirty C-functions needs a
  733. char-pointer, like sprintf. Size is the size you initialize the string, take care that the size
  734. is great enough!
  735.  
  736. Don't forget to call the ReleaseBuffer()-Function after GetBuffer()! ReleaseBuffer correct the length
  737. of the string.
  738.  
  739. The Size is exactly the size of chars in the buffer, the byte for the zero-byte is automatically added!
  740.  
  741. See the example!
  742. EXAMPLE
  743. XString a;
  744.  
  745. double pi=3.14;
  746.  
  747. sprintf(a.GetBuffer(100), "Pi = %2.3f", pi); a.ReleaseBuffer();
  748. */
  749. char* XString::GetBuffer(XSIZE_T Size)
  750. {
  751.   if (Size==0)
  752.   {
  753.       return m_pszChar;
  754.   }
  755.  
  756.     
  757.   char *temp;
  758.  
  759.   temp = (char *) calloc(sizeof(char), Size+1);
  760.   X_ASSERT (temp != NULL);
  761.  
  762.   XSIZE_T MinLength;
  763.   if (Size>m_Length) MinLength = m_Length; else MinLength = Size;
  764.  
  765.   memcpy(temp, m_pszChar, MinLength);
  766.  
  767.   free(m_pszChar);
  768.   m_pszChar = temp;
  769.   m_Length = Size;
  770.   
  771.   return m_pszChar;
  772. }
  773.  
  774. /*@ XString::GetBuffer(int Size=0)
  775. @remarks Sometimes an int is available for the length..
  776. */
  777. char* XString::GetBuffer(int Size)
  778. { X_ASSERT (Size>=0);
  779.   return GetBuffer((XSIZE_T) Size);
  780. }
  781.  
  782. /*
  783. int ReleaseBuffer(int Length)
  784. { if (Length<0) Length=0;
  785.    return ReleaseBuffer((XSIZE_T) Length);
  786. }
  787. */
  788.  
  789. /*@ XString::ReleaseBuffer(XSIZE_T Length)
  790. @group Caster
  791. @remarks After getting the buffer with GetBuffer, and after setting the size of the string to Size, this function
  792. correct the size of the buffer, so that the size of the buffer is equal to the length of the string.
  793. Don't use any other function after GetBuffer, before not calling ReleaseBuffer!!!!!!!!!!
  794. */
  795. int XString::ReleaseBuffer(XSIZE_T Length)
  796.   m_isNULL = FALSE;
  797.  
  798.   if (Length==0) Length = strlen(m_pszChar); 
  799.  
  800.   X_ASSERT (Length<=m_Length);
  801.  
  802.   char *temp = (char *) malloc(Length+1);
  803.  
  804.   memcpy(temp, m_pszChar, Length);
  805.  
  806.   temp[Length] = 0;
  807.  
  808.   free(m_pszChar);
  809.   m_pszChar = temp;
  810.   m_Length = Length;
  811.  
  812.   X_ASSERT(m_Length == strlen(m_pszChar));
  813.  
  814.   return Length;
  815. }
  816.  
  817.  
  818. /*@ XString::Strip(int inWhere, char inChar)
  819. @group Enhanced
  820. @returns Number of removed chars
  821. @remarks Strip removes all inChars at the beginning (inWhere=XLEFT), at the end (inWhere=XRIGHT), at both ends
  822. (inWhere=XBOTH) or removes all inChars (inWhere=XALL) from the string!
  823. If you have to remove substring, use Replace() instead!
  824. */
  825. int XString::Strip(int inWhere, char inChar)
  826. {
  827.   m_isNULL = FALSE;    
  828.  
  829.   X_ASSERT(m_pszChar != NULL);
  830.   if (m_Length == 0) return 0;
  831.  
  832.   XSIZE_T First=0, Last=m_Length;  // Last 1index (>0)...
  833.  
  834.   if (inWhere != XRIGHT) // then strip left
  835.   { 
  836.     while ((First<m_Length) && (m_pszChar[First] == inChar)) First++;
  837.  
  838.     if (First==m_Length) // Stripp all
  839.     { free(m_pszChar);
  840.       m_pszChar = (char *) malloc(1);
  841.       X_ASSERT(m_pszChar != NULL);
  842.       m_pszChar[0] = '\0';
  843.       m_Length = 0;
  844.  
  845.       X_ASSERT(m_Length == strlen(m_pszChar));
  846.  
  847.       return Last;
  848.     }
  849.   }
  850.  
  851.   if (inWhere != XLEFT) // then strip right
  852.   { 
  853.  
  854.     while ((Last>0) && (m_pszChar[Last-1] == inChar))
  855.     {  Last--; }
  856.     if (Last==0) // Stripp all
  857.     { free(m_pszChar);
  858.       m_pszChar = (char *) malloc(1);
  859.       X_ASSERT(m_pszChar != NULL);
  860.       m_pszChar[0] = '\0';
  861.       Last = m_Length;
  862.       m_Length = 0;
  863.  
  864.       X_ASSERT(m_Length == strlen(m_pszChar));
  865.  
  866.       return Last;
  867.     }
  868.   }
  869.  
  870.   char *stripped;
  871.  
  872.   if (inWhere != XALL) // then  build result string
  873.   {
  874.     if ((First==0) && (Last==m_Length)) // then nothing to do
  875.       return 0;
  876.  
  877.     stripped = (char *) malloc(Last-First+1);
  878.     X_ASSERT (stripped != NULL);
  879.     memcpy(stripped, m_pszChar+First, Last-First);
  880.  
  881.     stripped[Last-First] = 0;
  882.     free(m_pszChar);
  883.     m_pszChar = stripped;
  884.     XSIZE_T ret=m_Length;
  885.     m_Length = Last-First;
  886.  
  887.     X_ASSERT(m_Length == strlen(m_pszChar));
  888.  
  889.     return ret-m_Length;
  890.   }
  891.  
  892.   // inWhere == ALL
  893.   stripped = (char *) malloc(Last-First+1);
  894.   X_ASSERT (stripped != NULL);
  895.   
  896.   XSIZE_T index=First, strindex=0;    // 0-index
  897.   while (index<Last)
  898.   { if (m_pszChar[index] != inChar) // else ignore this char
  899.     { stripped[strindex] = m_pszChar[index];
  900.       strindex++;
  901.     }
  902.     index++;
  903.   }
  904.  
  905.   free(m_pszChar);
  906.   XSIZE_T oldL=m_Length;
  907.   m_pszChar = (char *) malloc(strindex+1);
  908.   X_ASSERT (m_pszChar != NULL);
  909.   memcpy(m_pszChar, stripped, strindex);
  910.   m_pszChar[strindex] = 0;
  911.  
  912.   free(stripped);
  913.   m_Length = strindex;
  914.  
  915.   X_ASSERT(m_Length == strlen(m_pszChar));
  916.   return oldL-m_Length;
  917. }
  918.  
  919. /*@ XString::StripWhitespaces ( int inWhere = XBOTH )
  920. @group Enhanced
  921. @returns Number of removed chars
  922. @remarks Strip whitespaces ( Space, Tab, Linefeed, Carriage return )
  923.         like function "Strip"
  924. */
  925. int XString::StripWhitespaces ( int inWhere )
  926. {
  927.  
  928.   m_isNULL = FALSE;
  929.  
  930.   X_ASSERT(m_pszChar != NULL);
  931.   if (m_Length == 0) return 0;
  932.  
  933.   XSIZE_T First=0, Last=m_Length;  // Last 1index (>0)...
  934.  
  935.   if (inWhere != XRIGHT) // then strip left
  936.   { 
  937.     while ((First<m_Length) && (isspace(m_pszChar[First]))) First++;
  938.  
  939.     if (First==m_Length) // Stripp all
  940.     { free(m_pszChar);
  941.       m_pszChar = (char *) malloc(1);
  942.       X_ASSERT(m_pszChar != NULL);
  943.       m_pszChar[0] = '\0';
  944.       m_Length = 0;
  945.  
  946.       X_ASSERT(m_Length == strlen(m_pszChar));
  947.  
  948.       return Last;
  949.     }
  950.   }
  951.  
  952.   if (inWhere != XLEFT) // then strip right
  953.   { 
  954.  
  955.     while ((Last>0) && (isspace(m_pszChar[Last-1])))
  956.     {  Last--; }
  957.     if (Last==0) // Stripp all
  958.     { free(m_pszChar);
  959.       m_pszChar = (char *) malloc(1);
  960.       X_ASSERT(m_pszChar != NULL);
  961.       m_pszChar[0] = '\0';
  962.       Last = m_Length;
  963.       m_Length = 0;
  964.  
  965.       X_ASSERT(m_Length == strlen(m_pszChar));
  966.  
  967.       return Last;
  968.     }
  969.   }
  970.  
  971.   char *stripped;
  972.  
  973.   if (inWhere != XALL) // then  build result string
  974.   {
  975.     if ((First==0) && (Last==m_Length)) // then nothing to do
  976.       return 0;
  977.  
  978.     stripped = (char *) malloc(Last-First+1);
  979.     X_ASSERT (stripped != NULL);
  980.     memcpy(stripped, m_pszChar+First, Last-First);
  981.  
  982.     stripped[Last-First] = 0;
  983.     free(m_pszChar);
  984.     m_pszChar = stripped;
  985.     XSIZE_T ret=m_Length;
  986.     m_Length = Last-First;
  987.  
  988.     X_ASSERT(m_Length == strlen(m_pszChar));
  989.  
  990.     return ret-m_Length;
  991.   }
  992.  
  993.   // inWhere == ALL
  994.   stripped = (char *) malloc(Last-First+1);
  995.   X_ASSERT (stripped != NULL);
  996.   
  997.   XSIZE_T index=First, strindex=0;    // 0-index
  998.   while (index<Last)
  999.   { if (!isspace(m_pszChar[index])) // else ignore this char
  1000.     { stripped[strindex] = m_pszChar[index];
  1001.       strindex++;
  1002.     }
  1003.     index++;
  1004.   }
  1005.  
  1006.   free(m_pszChar);
  1007.   XSIZE_T oldL=m_Length;
  1008.   m_pszChar = (char *) malloc(strindex+1);
  1009.   X_ASSERT (m_pszChar != NULL);
  1010.   memcpy(m_pszChar, stripped, strindex);
  1011.   m_pszChar[strindex] = 0;
  1012.  
  1013.   free(stripped);
  1014.   m_Length = strindex;
  1015.  
  1016.   X_ASSERT(m_Length == strlen(m_pszChar));
  1017.   return oldL-m_Length;
  1018. }
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024. /*@ XString::DelSubString(XString inSubString)
  1025. @group Set
  1026. @remarks Deletes the first place occurrence of inSubString
  1027. */
  1028. int XString::DelSubString(XString inSubString)
  1029. {
  1030.   m_isNULL = FALSE;
  1031.   X_ASSERT(inSubString.m_pszChar!=NULL);
  1032.   X_ASSERT(inSubString.m_Length>0);
  1033.  
  1034.   XSIZE_T pos;
  1035.   if (Find(pos, inSubString)) return DelSubString(pos, inSubString.m_Length);
  1036.   return X_ERR;
  1037. }
  1038.  
  1039. /*@ XString::DelSubString
  1040. @group Set
  1041. @remarks Deletes inCount-chars from inFrom (Zero-Index!).
  1042. */
  1043. int XString::DelSubString(XSIZE_T inFrom, XSIZE_T inCount)
  1044. {
  1045.   m_isNULL = FALSE;
  1046.   X_ASSERT(inFrom<m_Length);
  1047.   if (inCount==0) return X_ERR;
  1048.  
  1049.   if (inFrom+inCount>m_Length) inCount=m_Length-inFrom;
  1050.  
  1051.   char *temp = (char *) malloc(m_Length-inCount+1);
  1052.   X_ASSERT(temp!=NULL);
  1053.  
  1054.   memcpy(temp, m_pszChar, inFrom);
  1055.   memcpy(temp+inFrom, m_pszChar+inFrom+inCount, m_Length-(inCount+inFrom));
  1056.   temp[m_Length-inCount] = '\0';
  1057.   m_Length -= inCount;
  1058.   free(m_pszChar);
  1059.   m_pszChar = temp;
  1060.  
  1061.   X_ASSERT(m_Length == strlen(m_pszChar));
  1062.  
  1063.   return X_OK;
  1064. }
  1065.  
  1066. /*@ XString::Replace(XString inSearch, XString inReplace, int inTimes, XSIZE_T inFrom, XSIZE_T inTo)
  1067. @group Enhanced
  1068. @returns Number of replacements
  1069. @parameters inSearch is the substring to search, inReplace is the string wich replaces the searchstring, the substring
  1070. is max. inTimes replaced and inFrom and inTo mark the scope.
  1071. @remarks This is one of the most powerful methods of XString. It works as the Search-Replace-Function of you editor.
  1072. Of course, the search- and the replace-substring must NOT have the same length! The methods is working very fast,
  1073. because it first searches the substring, allocs new memory by calculing the new size, and then a new string is build.
  1074. When the new string is build, there is no more search necessary (only if the replacement-string is greater then the
  1075. searchstring and the length of the searchstring is smaller then the size of a XSIZE_T-type!).
  1076.  
  1077. In this moment I'm working on another Replace-method: Replace(BadEnglish, CorrectEnglish, everywhere in this docu...) ;-)
  1078. */
  1079. int XString::Replace(XString inSearch, XString inReplace, int inTimes, XSIZE_T inFrom, XSIZE_T inTo, BOOL inInCase)
  1080. {
  1081.   m_isNULL = FALSE;
  1082.  
  1083.   XSIZE_T pos=inFrom;
  1084.   int count=0;
  1085.   char *temp;
  1086.  
  1087.  
  1088.   if (inTo==0) inTo=GetLength();
  1089.   if (inTo<inFrom)
  1090.   { count = inTo; inTo = inFrom; inFrom = count; count =0; }
  1091.   if (inFrom>inTo) return 0;
  1092.  
  1093.  
  1094.   X_ASSERT(m_Length == strlen(m_pszChar));
  1095.  
  1096.   if (inSearch.GetLength() == inReplace.GetLength())
  1097.   { 
  1098.     while (Find(pos,inSearch, pos, inTo, inInCase))
  1099.     { count++;
  1100.       memcpy(&m_pszChar[pos], inReplace.m_pszChar, inReplace.GetLength());
  1101.       if (count==inTimes) break;
  1102.       pos += inSearch.GetLength();
  1103.     }
  1104.   }
  1105.   else
  1106.   if (inSearch.GetLength() > inReplace.GetLength())
  1107.   { 
  1108.     while (Find(pos,inSearch, pos, inTo, inInCase))
  1109.     { count++;
  1110.       memcpy(&m_pszChar[pos], inReplace.m_pszChar, inReplace.GetLength());
  1111.       memmove(&m_pszChar[pos+inReplace.GetLength()],
  1112.               &m_pszChar[pos+inSearch.GetLength()], GetLength()+1-(pos+inSearch.GetLength()));
  1113.       if (count==inTimes) break;
  1114.       pos += inReplace.GetLength();
  1115.     }
  1116.     if (count>0)
  1117.     {
  1118.     temp = (char *) malloc(GetLength()+1-count*(inSearch.GetLength()-inReplace.GetLength()));
  1119.     memcpy(temp, m_pszChar,GetLength()+1-count*(inSearch.GetLength()-inReplace.GetLength()));
  1120.     free(m_pszChar);
  1121.     m_pszChar = temp;
  1122.     m_Length = GetLength()-count*(inSearch.GetLength()-inReplace.GetLength());
  1123.     }
  1124.   }
  1125.   else // inSearch.GetLength() < inReplace.GetLength()
  1126.   { 
  1127.     XSIZE_T *posptr, firstpos, lastpos;
  1128.     unsigned char nextNull=0, offsets=0;
  1129.  
  1130.     if (inSearch.GetLength()>=sizeof(XSIZE_T))    // ptrlist in string
  1131.     {
  1132.  
  1133.       while (Find(pos,inSearch, pos, inTo, inInCase))
  1134.       { count++;
  1135.         if (count==1) firstpos = pos;
  1136.         else *posptr = pos;
  1137.  
  1138.         posptr = (XSIZE_T*) (&m_pszChar[pos]);
  1139.         if (count==inTimes) break;
  1140.         pos += inSearch.GetLength();
  1141.       }
  1142.  
  1143.     }
  1144.     else 
  1145.     { offsets = 1;
  1146.       while (Find(pos, inSearch, pos, inTo, inInCase))
  1147.       {  count++;
  1148.          if (count==1) firstpos=pos;
  1149.          if (count==inTimes) break; // 97-03-14: Fehler behoben: inTimes wurde hier ignoriert
  1150.          pos += inSearch.GetLength();
  1151.       }
  1152.     }
  1153.     if (count>0)
  1154.     { XSIZE_T  nextpos = 0;
  1155.       int i=0;
  1156.       lastpos = 0;
  1157.       pos = firstpos;
  1158.  
  1159.       temp = (char *) malloc(GetLength()+1+count*(inReplace.GetLength()-inSearch.GetLength()));
  1160.  
  1161.       while (i<count)
  1162.       { 
  1163.        if (offsets)   Find(nextpos, inSearch, pos+inSearch.GetLength(), inTo, inInCase);
  1164.        else           nextpos = *( (XSIZE_T*) (m_pszChar+pos) ) ;
  1165.  
  1166.         if (i>0)
  1167.         {  memcpy(&temp[inSearch.GetLength()+lastpos+(inReplace.GetLength()-inSearch.GetLength())*i ],
  1168.                &m_pszChar[lastpos+inSearch.GetLength()],
  1169.                pos-(lastpos+inSearch.GetLength()));                    // ...RRRxxxx...
  1170.            memcpy(&temp[inSearch.GetLength()+pos+(inReplace.GetLength()-inSearch.GetLength())*i
  1171.                          -inSearch.GetLength()],
  1172.                 inReplace.m_pszChar, inReplace.GetLength()+1);           //...RRRxxxxRRR
  1173.         }
  1174.         else
  1175.         { memcpy(temp, m_pszChar, pos);
  1176.           memcpy(&temp[pos],inReplace.m_pszChar, inReplace.GetLength()+1);
  1177.         }
  1178.        
  1179.  
  1180.         lastpos = pos;
  1181.         pos = nextpos;
  1182.         i++;
  1183.       } 
  1184.  
  1185.       memcpy(&temp[inSearch.GetLength()+lastpos+(inReplace.GetLength()-inSearch.GetLength())*i],    /// RRRxxxxx
  1186.              &m_pszChar[lastpos+inSearch.GetLength()],
  1187.              GetLength()-(lastpos+inSearch.GetLength())+1);
  1188.  
  1189.       XSIZE_T A1, A2;
  1190.       A1 =inSearch.GetLength()+lastpos+(inReplace.GetLength()-inSearch.GetLength())*i+GetLength()-(lastpos+inSearch.GetLength());
  1191.       A2 = GetLength()+count*(inReplace.GetLength()-inSearch.GetLength());
  1192.  
  1193. X_ASSERT(A1==A2);
  1194.  
  1195.  
  1196.       free(m_pszChar);
  1197.       m_pszChar = temp;
  1198.       m_Length = GetLength()+count*(inReplace.GetLength()-inSearch.GetLength());
  1199.  
  1200.     }
  1201.   }
  1202.   return count;
  1203. }
  1204.  
  1205.  
  1206.  
  1207. void XString::MakeUpper()
  1208.     m_isNULL = FALSE;    
  1209.  
  1210.   X_ASSERT(m_pszChar != NULL);
  1211.   X_ASSERT(m_Length == strlen(m_pszChar));
  1212.  
  1213.   strupr(m_pszChar);
  1214.  
  1215.   XSIZE_T pos;
  1216.   for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == 'Σ') m_pszChar[pos] = '─';
  1217.   for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == '÷') m_pszChar[pos] = '╓';
  1218.   for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == 'ⁿ') m_pszChar[pos] = '▄';
  1219.  
  1220.   Replace("▀", "SS");
  1221.  
  1222. }  
  1223.  
  1224. void XString::MakeLower()
  1225.     m_isNULL = FALSE;
  1226.     
  1227.     X_ASSERT(m_pszChar != NULL);
  1228.   X_ASSERT(m_Length == strlen(m_pszChar));
  1229.  
  1230.   strlwr(m_pszChar);
  1231.  
  1232.   XSIZE_T pos;
  1233.   for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == '─') m_pszChar[pos] = 'Σ';
  1234.   for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == '╓') m_pszChar[pos] = '÷';
  1235.   for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == '▄') m_pszChar[pos] = 'ⁿ';
  1236. }
  1237.  
  1238.  
  1239. const char __Xlow[ ] = "ΘΓΣαστΩδΦ∩ε∞─┼╔µ╞⌠÷≥√∙ ╓▄óúÑPâßφ≤·±";
  1240. const char __Xupp[ ] = "╔┬─└┼╟╩E╚I╬╠─┼╔╞╞╘╓╥█┘Y╓▄óúÑPâ┴═╙┌╤";
  1241.  
  1242. char XString::UpperChar(char inChar)
  1243. {    
  1244.     if (inChar<'a') return inChar;            // Gro▀buchstaben und Steuerzeichen
  1245.     if (inChar>=165) return inChar;            // Grafikzeichen
  1246.     if (inChar<='z') return inChar - 32;    // a..z -> A--Z
  1247.     if (inChar<'ⁿ') return inChar;            // {...╟
  1248.     return __Xupp[inChar-'Θ'];
  1249. }
  1250.  
  1251.  
  1252.  
  1253. /*****************************************************
  1254. FRIEND HELPERS:
  1255. ********************************************************/
  1256.  
  1257. // FriendOperatoren:
  1258.  
  1259. int operator ==(const XString &inS1, const XString &inS2) 
  1260. { X_ASSERT(inS1.m_pszChar!=NULL);
  1261.   X_ASSERT(inS2.m_pszChar!=NULL);
  1262.   
  1263.   return strcmp(inS1.m_pszChar, inS2.m_pszChar)==0;
  1264. }
  1265.  
  1266. int operator ==(const XString &inS1, const char *pszChar2) 
  1267. {
  1268.     X_ASSERT(inS1.m_pszChar!=NULL);
  1269.     X_ASSERT(pszChar2!=NULL);
  1270.   
  1271.     return strcmp(inS1.m_pszChar, pszChar2)==0;
  1272. }
  1273.  
  1274. int operator ==(const char *pszChar1, const XString &inS2)
  1275. {
  1276.     X_ASSERT(pszChar1!=NULL);
  1277.     X_ASSERT(inS2.m_pszChar!=NULL);
  1278.  
  1279.     return strcmp(pszChar1, inS2.m_pszChar)==0;
  1280. }
  1281.  
  1282. int operator <(const XString &inS1, const XString &inS2)
  1283. { X_ASSERT(inS1.m_pszChar!=NULL);
  1284.   X_ASSERT(inS2.m_pszChar!=NULL);
  1285.  
  1286.   return strcmp(inS1.m_pszChar, inS2.m_pszChar)<0;
  1287. }
  1288.  
  1289. int operator <(const XString &inS1,const char *pszChar2)
  1290. {
  1291.     X_ASSERT(inS1.m_pszChar!=NULL);
  1292.     X_ASSERT(pszChar2!=NULL);
  1293.   
  1294.     return strcmp(inS1.m_pszChar, pszChar2)<0;
  1295. }
  1296.  
  1297. int operator <( const char *pszChar1, const XString &inS2)
  1298. {
  1299.     X_ASSERT(pszChar1!=NULL);
  1300.     X_ASSERT(inS2.m_pszChar!=NULL);
  1301.  
  1302.     return strcmp(pszChar1, inS2.m_pszChar)<0;
  1303. }
  1304.  
  1305.  
  1306. int operator !=(const XString &inS1, const XString &inS2) 
  1307. {    return !(inS1==inS2);        }
  1308.  
  1309. int operator !=(const XString &inS1,  const char *pszChar2) 
  1310. {    return !(inS1 == pszChar2); }
  1311.  
  1312. int operator !=(const char *pszChar1, const XString &inS2)
  1313. {    return !(pszChar1 == inS2);    }
  1314.  
  1315. int operator >(const XString &inS1, const XString &inS2)
  1316. {    return (inS2 < inS1);    }
  1317.  
  1318. int operator >(const XString &inS1, const char *pszChar2)
  1319. {    return (pszChar2 < inS1);   }
  1320.  
  1321. int operator >( const char *pszChar1, const XString &inS2)
  1322. {    return (inS2 < pszChar1 );    }
  1323.  
  1324. int operator <=(const XString &inS1, const XString &inS2)
  1325. {    return !(inS2<inS1);    }
  1326.  
  1327. int operator <=(const XString &inS1,  const char *pszChar2)
  1328. {    return !(pszChar2 < inS1);    }
  1329.  
  1330. int operator <=(const char *pszChar1, const XString &inS2)
  1331. {    return !(inS2 < pszChar1);    }
  1332.  
  1333. int operator >=(const XString &inS1, const XString &inS2)
  1334. {    return !(inS1<inS2);        }
  1335.  
  1336. int operator >=(const XString &inS1, const char *pszChar2)
  1337. {    return !(inS1 < pszChar2);    }
  1338.  
  1339. int operator >=(const char *pszChar1, const XString &inS2)
  1340. {    return !(pszChar1 < inS2);    }
  1341.  
  1342.  
  1343.  
  1344. // Friend-Functionen:
  1345. // TBO
  1346. #ifndef __WATCOMC__
  1347. XString operator +(const XString Str1, const char *pszChar2)
  1348. #else
  1349. XString operator +(XString Str1, const char *pszChar2)
  1350. #endif
  1351. {
  1352.   X_ASSERT(Str1.m_pszChar!=NULL);
  1353.   X_ASSERT(pszChar2!=NULL);
  1354.  
  1355.   X_ASSERT(Str1.m_Length == strlen(Str1.m_pszChar));
  1356.  
  1357.   XString Res;
  1358.   XSIZE_T C2Length=strlen(pszChar2);
  1359.  
  1360.   Res.m_Length = Str1.m_Length+C2Length;
  1361.   free(Res.m_pszChar);
  1362.   Res.m_pszChar = (char *) malloc(Res.m_Length+1);
  1363.  
  1364.   X_ASSERT(Res.m_pszChar != NULL);
  1365.    
  1366.   memcpy(Res.m_pszChar, Str1.m_pszChar, Str1.m_Length);
  1367.   memcpy(&Res.m_pszChar[Str1.m_Length], pszChar2, C2Length+1);
  1368.  
  1369.   X_ASSERT(Res.GetLength() == strlen(Res.m_pszChar));
  1370.  
  1371.   return Res;
  1372. }
  1373.  
  1374. // TBO
  1375. #ifndef __WATCOMC__
  1376. XString operator +(const char *pszChar1, const XString Str2)
  1377. #else
  1378. XString operator +(const char *pszChar1, XString Str2)
  1379. #endif
  1380. {
  1381.   X_ASSERT(Str2.m_pszChar!=NULL);
  1382.   X_ASSERT(pszChar1!=NULL);
  1383.  
  1384.   X_ASSERT(Str2.m_Length == strlen(Str2.m_pszChar));
  1385.  
  1386.   XString Res;
  1387.   XSIZE_T C1Length = strlen(pszChar1);
  1388.  
  1389.   Res.m_Length = Str2.m_Length+C1Length;
  1390.   free(Res.m_pszChar);
  1391.   Res.m_pszChar = (char *) malloc(Res.m_Length+1);
  1392.  
  1393.   X_ASSERT(Res.m_pszChar != NULL);
  1394.  
  1395.   memcpy(Res.m_pszChar, pszChar1, C1Length);
  1396.   memcpy(&Res.m_pszChar[C1Length], Str2.m_pszChar, Str2.m_Length+1);
  1397.  
  1398.   X_ASSERT(Res.m_Length == strlen(Res.m_pszChar));
  1399.  
  1400.   return Res;
  1401. }
  1402.  
  1403. // TBO
  1404. #ifndef __WATCOMC__
  1405. XString operator +(const XString& Str1, const XString& Str2)
  1406. #else
  1407. XString operator +(XString& Str1, XString& Str2)
  1408. #endif
  1409. {
  1410.   X_ASSERT(Str2.m_pszChar!=NULL);
  1411.   X_ASSERT(Str1.m_pszChar!=NULL);
  1412.  
  1413.   X_ASSERT(Str1.m_Length == strlen(Str1.m_pszChar));
  1414.   X_ASSERT(Str2.m_Length == strlen(Str2.m_pszChar));
  1415.   
  1416.   XString Res;
  1417.  
  1418.   Res.m_Length = Str2.m_Length+Str1.m_Length;
  1419.   free(Res.m_pszChar);
  1420.   Res.m_pszChar = (char *) malloc(Res.m_Length+1);
  1421.  
  1422.   X_ASSERT(Res.m_pszChar != NULL);
  1423.  
  1424.   memcpy(Res.m_pszChar, Str1.m_pszChar, Str1.m_Length);
  1425.   memcpy(&Res.m_pszChar[Str1.m_Length], Str2.m_pszChar, Str2.m_Length+1);
  1426.  
  1427.   X_ASSERT(Res.GetLength() == strlen(Res.m_pszChar));
  1428.  
  1429.   return Res;
  1430. }
  1431.  
  1432. /* Vereinfachung:
  1433.     x==y und x<y definiert, ansonsten:
  1434.     x!=y : !(x==y)
  1435.     x>y  : y<x
  1436.     x<=y : !(y<x)
  1437.     x>=< : !(x<y)
  1438. */
  1439.  
  1440. /////////////////////////////////////////////////
  1441. // streams:
  1442. ostream& operator<<(ostream& outStream, const XString& outString)
  1443. {
  1444.     return outStream << outString.m_pszChar;
  1445. }
  1446.  
  1447. istream& operator>>(istream& inStream, XString& inString)
  1448. {
  1449.     char buf[100];
  1450.     char c;
  1451.     while (inStream.get(c) && (c!= '\n'))
  1452.     {
  1453.         inString += c;
  1454.         inStream.get (buf, 100, '\n');
  1455.         inString += buf;
  1456.  
  1457.     }
  1458.     return inStream;