home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tlx501.zip / SRC / STRINGS.CPP < prev    next >
C/C++ Source or Header  |  1996-07-08  |  32KB  |  908 lines

  1. /****************************************************************************
  2.     $Id: strings.cpp 501.0 1995/03/07 12:26:24 RON Exp $
  3.  
  4.     Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
  5.  
  6.     Project:    Tarma Library for C++ V5.0
  7.     Author:    Ron van der Wal
  8.  
  9.     Implementation of class TLString. This class represents a character
  10.     string, i.e. a sequence of characters of known length. The string
  11.     resizes itself each time an expansion is necessary. (Contractions are
  12.     only performed on request.)
  13.  
  14.     The string is not a 0-terminated C-style string, although conversions
  15.     from and to these strings are implemented. Character indexing starts at
  16.     0, just as with C-style strings.
  17.  
  18.     TODO:
  19.  
  20.     - check whether change from 1-based to 0-based indexing is correct
  21.     - make sure that C-style functions result in a C-style string
  22.     - check logic for invisible extra character
  23.  
  24.     $Log: strings.cpp $
  25.     Revision 501.0  1995/03/07 12:26:24  RON
  26.     Updated for TLX 5.01
  27.     Revision 1.8  1995/01/31 16:30:28  RON
  28.     Update for release 012
  29.     Added partial support for SunPro C++ compiler
  30.     Revision 1.7  1995/01/06  15:58:31  ron
  31.     Corrected Revision keyword
  32.  
  33.     Revision 1.6  1994/11/16  15:43:57  ron
  34.     Added module info; rearranged #include directives
  35.  
  36.     Revision 1.5  1994/10/05  18:43:42  ron
  37.     Renamed TLx...() functions to tl...()
  38.  
  39.     Revision 1.4  1994/09/28  14:22:48  ron
  40.     Removed Macintosh-style #include references
  41.  
  42.     Revision 1.3  1994/09/27  20:23:08  ron
  43.     Changed path separator from / to \
  44.  
  45.     Revision 1.2  1994/09/26  15:48:16  ron
  46.     Renamed SetSize() to Resize()
  47.  
  48.     Revision 1.1  1994/08/16  18:13:16  ron
  49.     Initial revision
  50.  
  51. ****************************************************************************/
  52.  
  53. #include <tlx\501\_build.h>
  54.  
  55. TLX_MODULE_INFO("$Revision: 501.0 $");
  56.  
  57. //-----    System headers
  58.  
  59. #include <ctype.h>        // For tolower(), toupper()
  60. #include <iostream.h>
  61. #include <stdlib.h>        // For malloc() etc.
  62. #include <string.h>        // C string-handling functions
  63.  
  64. //----- Library headers
  65.  
  66. #include <tlx\501\except.h>
  67. #include <tlx\501\strings.h>        // class TLString
  68.  
  69. /*---------------------------------------------------------------------------
  70.     Implementation notes:
  71.     ---------------------
  72.  
  73. 1.  We use the malloc() family of memory allocations rather than operators
  74.     new and delete, because the frequent reallocations might benefit from
  75.     the availability of realloc().
  76.  
  77. 2.  We silently allocate 1 extra character at the end of each string buffer.
  78.     This extra character ensures that we will always be able to append a
  79.     '\0' terminator to each string. The extra character is not included in
  80.     any count, not even in 'mSize'.
  81. ---------------------------------------------------------------------------*/
  82.  
  83. /*-------------------------------------------------------------------------*/
  84.     TLString::TLString(size_t aSize)
  85.  
  86. /*  Constructor, initializing the string as a character buffer of the
  87.     specified length. The buffer's contents are set to 0.
  88. ---------------------------------------------------------------------------*/
  89. {
  90.     Create(0, 0, aSize);
  91.     TLX_ASSERT_PTR(mString);
  92.     TLX_ASSERT(Size() == aSize);
  93. }
  94.  
  95. /*-------------------------------------------------------------------------*/
  96.     TLString::TLString(char c, size_t extra)
  97.  
  98. /*  Constructor initializing the string as a character buffer with a length
  99.     of 1 + 'extra'. The first character of the buffer is set to 'c'. The
  100.     length of the string is set to 1.
  101. ---------------------------------------------------------------------------*/
  102. {
  103.     Create(&c, 1, extra);
  104.     TLX_ASSERT_PTR(mString);
  105.     TLX_ASSERT(Size() == extra + 1);
  106.     TLX_ASSERT(Length() == 1);
  107. }
  108.  
  109. /*-------------------------------------------------------------------------*/
  110.     TLString::TLString(const char *s, size_t extra)
  111.  
  112. /*  Constructor initializing the string as a character buffer with a length
  113.     of n = strlen(s) + 'extra'. The first n characters are copied from 's'.
  114.     The length of the string is set to n.
  115. ---------------------------------------------------------------------------*/
  116. {
  117.     TLX_ASSERT_PTR(s);
  118.  
  119.     Create(s, strlen(s), extra);
  120.     TLX_ASSERT_PTR(mString);
  121.     TLX_ASSERT(Size() == strlen(s) + extra);
  122.     TLX_ASSERT(Length() == strlen(s));
  123. }
  124.  
  125. /*-------------------------------------------------------------------------*/
  126.     TLString::TLString(const TLString &s)
  127.  
  128. /*  Copy constructor. Initializes the string as a character buffer with a
  129.     length of n = s.mLen.
  130. ---------------------------------------------------------------------------*/
  131. {
  132.     Create(s.mString, s.mLen, s.mSize - s.mLen);
  133.     TLX_ASSERT_PTR(mString);
  134.     TLX_ASSERT(Size() == s.Size());
  135. }
  136.  
  137. /*-------------------------------------------------------------------------*/
  138.     TLString::~TLString()
  139.  
  140. /*  Destructor. Frees the character buffer.
  141. ---------------------------------------------------------------------------*/
  142. {
  143.     TLX_ASSERT_PTR(mString);
  144.     free(mString);
  145. }
  146.  
  147. /*-------------------------------------------------------------------------*/
  148.     TLString &TLString::Assign(const char *s, size_t n)
  149.  
  150. /*  Assigns the character string to the string as its contents. If the
  151.     character buffer size is less than required, an attempt is made to
  152.     expand the buffer. In any case, only as many characters as will fit
  153.     in the buffer are copied.
  154.  
  155.     This member function does not determine the string length itself, but
  156.     relies on the value provided in the 'n' parameter. This allows us to
  157.     capture the code that is common to several assignment operations.
  158. ---------------------------------------------------------------------------*/
  159. {
  160.     TLX_ASSERT_PTR(s);
  161.     TLX_ASSERT_PTR(mString);
  162.  
  163.     if (mSize < n) Resize(n);          // Try to resize
  164.     if (mSize == 0) return *this;
  165.     if (n > mSize) n = mSize;           // Truncate if necessary
  166.  
  167.     memcpy(mString, s, n);
  168.     mLen = n;
  169.     Terminate();
  170.     return *this;
  171. }
  172.  
  173. /*-------------------------------------------------------------------------*/
  174.     void TLString::Clear()
  175.  
  176. /*  Clears the contents of the string by setting its length to 0 and NUL-
  177.     terminating the character string.
  178. ---------------------------------------------------------------------------*/
  179. {
  180.     TLX_ASSERT_PTR(mString);
  181.  
  182.     mLen = 0;
  183.     Terminate();
  184. }
  185.  
  186. /*-------------------------------------------------------------------------*/
  187.     void TLString::CompactStorage()
  188.  
  189. /*  Reduces the size of the character buffer to the size required by the
  190.     string stored in it.
  191. ---------------------------------------------------------------------------*/
  192. {
  193.     Resize(mLen);
  194. }
  195.  
  196. /*-------------------------------------------------------------------------*/
  197.     TLString TLString::Copy(size_t pos, size_t n)
  198.  
  199. /*  Creates a new string that contains a substring from the current string.
  200. ---------------------------------------------------------------------------*/
  201. {
  202.     TLX_ASSERT_PTR(mString);
  203.  
  204.     if (pos >= mLen) return TLString(0u);
  205.     if (pos + n >= mLen) n = mLen - pos;
  206.  
  207.     TLString result(n);
  208.     if (result.mString) {
  209.         memcpy(result.mString, mString + pos, n);
  210.     result.mLen = n;
  211.     result.Terminate();
  212.     }
  213.     return result;
  214. }
  215.  
  216. /*-------------------------------------------------------------------------*/
  217.     void TLString::Create(const char *s, size_t n, size_t extra)
  218.  
  219. /*  Creates a character buffer of the specified size, and initializes the
  220.     other data members accordingly. The first 'n' characters of the buffer
  221.     are copied from 's'.
  222.  
  223.     NOTE: this function can only be used safely by constructors.
  224. ---------------------------------------------------------------------------*/
  225. {
  226.     mString = 0;
  227.     mLen    =
  228.     mSize   = 0;
  229.  
  230.     Resize(n + extra);
  231.     TLX_ASSERT_PTR(mString);
  232.  
  233.     if (s) memcpy(mString, s, n);
  234.     mLen = n;
  235.     Terminate();
  236. }
  237.  
  238. /*-------------------------------------------------------------------------*/
  239.     void TLString::Remove(size_t pos, size_t n)
  240.  
  241. /*  Removes 'n' characters from the string, starting at position 'pos'.
  242. ---------------------------------------------------------------------------*/
  243. {
  244.     TLX_ASSERT_PTR(mString);
  245.  
  246.     if (pos >= mLen) return;
  247.     if (pos + n >= mLen) n = mLen - pos;
  248.  
  249.     memmove(mString + pos, mString + pos + n, mLen - pos - n);
  250.     mLen -= n;
  251. }
  252.  
  253. /*-------------------------------------------------------------------------*/
  254.     TLString TLString::Extract(size_t pos, size_t n)
  255.  
  256. /*  Removes and returns a substring from the current string.
  257. ---------------------------------------------------------------------------*/
  258. {
  259.     TLString result(Copy(pos, n));
  260.     Remove(pos, n);
  261.     return result;
  262. }
  263.  
  264. /*-------------------------------------------------------------------------*/
  265.     void TLString::Fill(char c, size_t pos, size_t len)
  266.  
  267. /*  Fills the character buffer with the specified character. If pos >= mSize,
  268.     nothing happens; if len > remainder, only the remainder is filled.
  269. ---------------------------------------------------------------------------*/
  270. {
  271.     TLX_ASSERT_PTR(mString);
  272.  
  273.     if (pos >= mSize) return;
  274.     if (len > mSize - pos) len = mSize - pos;
  275.     memset(mString + pos, c, len);
  276. }
  277.  
  278. /*-------------------------------------------------------------------------*/
  279.     size_t TLString::IndexOf(char c, size_t pos)
  280.  
  281. /*  Returns the index of the first occurrence of 'c', starting at position
  282.     'pos'. It returns 0 if not found.
  283. ---------------------------------------------------------------------------*/
  284. {
  285.     TLX_ASSERT_PTR(mString);
  286.  
  287.     if (pos >= mLen) return 0;
  288.     char *cptr = (char *) memchr(mString + pos, c, mLen - pos);
  289.     ptrdiff_t i = cptr ? cptr - mString + 1 : 0;
  290.  
  291.     TLX_ASSERT(i >= 0);
  292.     TLX_TODO(Change to 0-based indexing; use index_t for return type);
  293.  
  294.     return (size_t) i;
  295. }
  296.  
  297. /*-------------------------------------------------------------------------*/
  298.     size_t TLString::IndexOf(const char *s, size_t pos)
  299.  
  300. /*  Returns the index of the first occurrence of 's', starting at position
  301.     'pos'. It returns 0 if not found.
  302. ---------------------------------------------------------------------------*/
  303. {
  304.     TLX_ASSERT_PTR(mString);
  305.  
  306.     if (pos >= mLen) return 0;
  307.     char *sptr = strstr(mString + pos, s);
  308.     ptrdiff_t i = sptr ? sptr - mString + 1 : 0;
  309.  
  310.     TLX_ASSERT(i >= 0);
  311.     TLX_TODO(Change to 0-based indexing; use index_t for return type);
  312.  
  313.     return (size_t) i;
  314. }
  315.  
  316. /*-------------------------------------------------------------------------*/
  317.     size_t TLString::IndexOf(const TLString &s, size_t pos)
  318.  
  319. /*  Returns the index of the first occurrence of 's', starting at position
  320.     'pos'. It returns 0 if not found.
  321. ---------------------------------------------------------------------------*/
  322. {
  323.     return IndexOf(s.mString, pos);
  324. }
  325.  
  326. /*-------------------------------------------------------------------------*/
  327.     void TLString::Insert(char c, size_t pos)
  328.  
  329. /*  Inserts the character at the indicated position. The previous character
  330.     at that position and all remaining characters are moved up. If necessary
  331.     and allowed, the character buffer is expanded.
  332. ---------------------------------------------------------------------------*/
  333. {
  334.     Insert(&c, 1, pos);
  335. }
  336.  
  337. /*-------------------------------------------------------------------------*/
  338.     void TLString::Insert(const char *s, size_t pos)
  339.  
  340. /*  Inserts the character string at the indicated position.
  341. ---------------------------------------------------------------------------*/
  342. {
  343.     TLX_ASSERT_PTR(s);
  344.     Insert(s, strlen(s), pos);
  345. }
  346.  
  347. /*-------------------------------------------------------------------------*/
  348.     void TLString::Insert(const TLString &s, size_t pos)
  349.  
  350. /*  Inserts the other string at the indicated position.
  351. ---------------------------------------------------------------------------*/
  352. {
  353.     Insert(s.mString, s.mLen, pos);
  354. }
  355.  
  356. /*-------------------------------------------------------------------------*/
  357.     void TLString::Insert(const char *s, size_t n, size_t pos)
  358.  
  359. /*  Inserts 'n' characters from 's' into the string. If necessary, the
  360.     string is first expanded to make room for the new characters.
  361. ---------------------------------------------------------------------------*/
  362. {
  363.     TLX_ASSERT_PTR(s);
  364.     TLX_ASSERT_PTR(mString);
  365.  
  366.     // First try to expand the string to the required size
  367.     if (mSize < mLen + n) Resize(mLen + n);
  368.  
  369.     // Truncate the copy operation if necessary
  370.     if (mLen >= mSize) return;
  371.     if (n > mSize - mLen) n = mSize - mLen;
  372.  
  373.     // Make sure the insert position is reasonable
  374.     if (pos > mLen) pos = mLen;
  375.  
  376.     // Create a hole, then copy the characters into it
  377.     memmove(mString + pos + n, mString + pos, mSize - pos - n);
  378.     memcpy(mString + pos, s, n);
  379.     mLen += n;
  380. }
  381.  
  382. /*-------------------------------------------------------------------------*/
  383.     TLString &TLString::operator =(char c)
  384.  
  385. /*  Assigns the character to the string as its single character.
  386. ---------------------------------------------------------------------------*/
  387. {
  388.     return Assign(&c, 1);
  389. }
  390.  
  391. /*-------------------------------------------------------------------------*/
  392.     TLString &TLString::operator =(const char *s)
  393.  
  394. /*  Assigns the character string to the string as its contents. If the
  395.     character buffer size is less than required, the buffer is resized.
  396. ---------------------------------------------------------------------------*/
  397. {
  398.     TLX_ASSERT_PTR(s);
  399.     TLX_ASSERT_PTR(mString);
  400.  
  401.     if (s != mString)
  402.     Assign(s, strlen(s));
  403.  
  404.     return *this;
  405. }
  406.  
  407. /*-------------------------------------------------------------------------*/
  408.     TLString &TLString::operator =(const TLString &s)
  409.  
  410. /*  Assigns the contents of the other string to the current one. The _flex
  411.     parameter is NOT copied. If the character buffer size is less than
  412.     required, the buffer is expanded.
  413.  
  414.     NOTE: s.mLen is used as the length of the string to be copied.
  415. ---------------------------------------------------------------------------*/
  416. {
  417.     if (&s != this)
  418.     Assign(s.mString, s.mLen);
  419.  
  420.     TLX_ASSERT_PTR(mString);
  421.     TLX_ASSERT(Length() == strlen(mString));
  422.  
  423.     return *this;
  424. }
  425.  
  426. /*-------------------------------------------------------------------------*/
  427.     TLString &TLString::operator +=(char c)
  428.  
  429. /*  Appends the character at the end of the character buffer. The buffer
  430.     is supposed to end at position 'mLen', i.e. 'c' is inserted at that
  431.     position.
  432. ---------------------------------------------------------------------------*/
  433. {
  434.     Insert(&c, 1, mLen);
  435.  
  436.     TLX_ASSERT_PTR(mString);
  437.     TLX_ASSERT(Length() == strlen(mString));
  438.  
  439.     return *this;
  440. }
  441.  
  442. /*-------------------------------------------------------------------------*/
  443.     TLString &TLString::operator +=(const char *s)
  444.  
  445. /*  Appends the character string at the end of the character buffer. The
  446.     buffer is supposed to end at position 'mLen', i.e. the contents of 's'
  447.     are inserted started at that position.
  448. ---------------------------------------------------------------------------*/
  449. {
  450.     TLX_ASSERT_PTR(s);
  451.  
  452.     Insert(s, strlen(s), mLen);
  453.  
  454.     TLX_ASSERT_PTR(mString);
  455.     TLX_ASSERT(Length() == strlen(mString));
  456.  
  457.     return *this;
  458. }
  459.  
  460. /*-------------------------------------------------------------------------*/
  461.     TLString &TLString::operator +=(const TLString &s)
  462.  
  463. /*  Appends the other string at the end of the character buffer. The buffer
  464.     is supposed to end at position 'mLen', i.e. the contents of 's' are
  465.     inserted started at that position.
  466.  
  467.     NOTE: s.mLen is used as the length of the string to be copied.
  468. ---------------------------------------------------------------------------*/
  469. {
  470.     TLX_ASSERT_PTR(mString);
  471.  
  472.     Insert(s.mString, s.mLen, mLen);
  473.  
  474.     TLX_ASSERT(Length() == strlen(mString));
  475.  
  476.     return *this;
  477. }
  478.  
  479. #if 0
  480. TLString::operator char *()
  481. /*
  482.     Turns the string into a C-style 0-terminated string, and returns a pointer
  483.     to it. A '\0' is inserted at position mString[mLen], which is guaranteed to
  484.     exist (we have a hidden extra character at the end of each buffer).
  485. */
  486. {
  487.     if (mString) mString[mLen] = '\0';
  488.     return mString;
  489. }
  490. #endif
  491.  
  492. /*-------------------------------------------------------------------------*/
  493.     char &TLString::operator [](size_t i)
  494.  
  495. /*  Returns a reference to the 'i'th character, or throws a TLXIndex
  496.     exception if the index is invalid.
  497. ---------------------------------------------------------------------------*/
  498. {
  499.     TLX_ASSERT_PTR(mString);
  500.  
  501.     if (!IsValidIndex(i))
  502.     THROW(TLXIndex(LOCUS, i));
  503.  
  504.     return mString[i];
  505. }
  506.  
  507. /*-------------------------------------------------------------------------*/
  508.     char TLString::operator [](size_t i) const
  509.  
  510. /*  Returns the value of the 'i'th character, or throws a TLXIndex
  511.     exception if the index is invalid.
  512. ---------------------------------------------------------------------------*/
  513. {
  514.     TLX_ASSERT_PTR(mString);
  515.  
  516.     if (!IsValidIndex(i))
  517.     THROW(TLXIndex(LOCUS, i));
  518.  
  519.     return mString[i];
  520. }
  521.  
  522. /*-------------------------------------------------------------------------*/
  523.     void TLString::Reserve(size_t sz)
  524.  
  525. /*  Expands the string buffer to hold at least 'sz' characters. Space for
  526.     the terminating 0 is always added silently.
  527. ---------------------------------------------------------------------------*/
  528. {
  529.     if (Size() < sz)
  530.     Resize(sz);
  531. }
  532.  
  533. /*-------------------------------------------------------------------------*/
  534.     void TLString::Resize(size_t size)
  535.  
  536. /*  Resizes an existing string to the requested size. If the operation
  537.     succeeds, the mSize data member is adjusted. If not, a TLXAlloc
  538.     exception is thrown. The contents that the reallocated character buffer
  539.     has in common with the old buffer remain unchanged; the new positions
  540.     (if any) are uninitialized.
  541.  
  542.     NOTE: we silently allocate an extra character at the end of each buffer.
  543. ---------------------------------------------------------------------------*/
  544. {
  545.     TLX_ASSERT(size <= MaxSize());
  546.  
  547.     // Perform reallocation, but keep mString intact. Allocated size is
  548.     // always > 0.
  549.     char *tmp = (char *) realloc(mString, size + 1);
  550.     if (!tmp)
  551.     THROW(TLXAlloc(LOCUS, size + 1));
  552.  
  553.     mString = tmp;
  554.     mSize   = size;
  555. }
  556.  
  557. /*-------------------------------------------------------------------------*/
  558.     void TLString::Reverse()
  559.  
  560. /*  Reverses the contents of the buffer.
  561. ---------------------------------------------------------------------------*/
  562. {
  563.     TLX_ASSERT_PTR(mString);
  564.  
  565.     size_t n    = mLen/2;
  566.     char *head = mString;
  567.     char *tail = mString + mLen - 1;
  568.  
  569.     while (n--) {
  570.         char c  = *head;
  571.         *head++ = *tail;
  572.         *tail-- = c;
  573.     }
  574.     TLX_ASSERT(Length() == strlen(mString));
  575. }
  576.  
  577. /*-------------------------------------------------------------------------*/
  578.     void TLString::Sync()
  579.  
  580. /*  Brings the mLen data member up to date with the position of the first
  581.     '\0' character in the buffer. If there is no such character, mLen
  582.     becomes equal to mSize.
  583. ---------------------------------------------------------------------------*/
  584. {
  585.     TLX_ASSERT_PTR(mString);
  586.  
  587.     char *nul = (char *) memchr(mString, 0, mSize);
  588.     ptrdiff_t len = nul ? nul - mString : mSize;
  589.  
  590.     TLX_ASSERT(len >= 0);
  591.     mLen = (size_t) len;
  592. }
  593.  
  594. /*-------------------------------------------------------------------------*/
  595.     void TLString::Terminate()
  596.  
  597. /*  Appends a '\0' character to terminate the string according to C usage.
  598. ---------------------------------------------------------------------------*/
  599. {
  600.     TLX_ASSERT_PTR(mString);
  601.     TLX_ASSERT(Size() >= mLen);
  602.  
  603.     mString[mLen] = '\0';    // Always at least 1 position allocated
  604. }
  605.  
  606. /*-------------------------------------------------------------------------*/
  607.     void TLString::ToLower()
  608.  
  609. /*  Converts all characters up to mLen to lowercase.
  610. ---------------------------------------------------------------------------*/
  611. {
  612.     TLX_ASSERT_PTR(mString);
  613.  
  614.     size_t n    = mLen;
  615.     char *cptr = mString;
  616.  
  617.     while (n--) {
  618.         *cptr = (char)tolower(*cptr);
  619.         cptr++;
  620.     }
  621. }
  622.  
  623. /*-------------------------------------------------------------------------*/
  624.     void TLString::ToUpper()
  625.  
  626. /*  Converts all characters up to mLen to uppercase.
  627. ---------------------------------------------------------------------------*/
  628. {
  629.     TLX_ASSERT_PTR(mString);
  630.  
  631.     size_t n    = mLen;
  632.     char *cptr = mString;
  633.  
  634.     while (n--) {
  635.     *cptr = (char)toupper(*cptr);
  636.     cptr++;
  637.     }
  638. }
  639.  
  640. /*-------------------------------------------------------------------------*/
  641.     int _TLXFUNC operator ==(const TLString &aStr1, const TLString &aStr2)
  642.  
  643. /*  Compares two strings for equality, returning nonzero if the are equal.
  644.     The comparison is case sensitive.
  645. ---------------------------------------------------------------------------*/
  646. {
  647.     TLX_ASSERT_PTR(aStr1.mString);
  648.     TLX_ASSERT_PTR(aStr2.mString);
  649.     return strcmp(aStr1.mString, aStr2.mString) == 0;
  650. }
  651.  
  652. /*-------------------------------------------------------------------------*/
  653.     int _TLXFUNC operator ==(const TLString &aStr1, const char *aStr2)
  654.  
  655. /*  Compares two strings for equality, returning nonzero if the are equal.
  656.     The comparison is case sensitive.
  657. ---------------------------------------------------------------------------*/
  658. {
  659.     TLX_ASSERT_PTR(aStr1.mString);
  660.     TLX_ASSERT_PTR(aStr2);
  661.     return strcmp(aStr1.mString, aStr2) == 0;
  662. }
  663.  
  664. /*-------------------------------------------------------------------------*/
  665.     int _TLXFUNC operator ==(const char *aStr1, const TLString &aStr2)
  666.  
  667. /*  Compares two strings for equality, returning nonzero if the are equal.
  668.     The comparison is case sensitive.
  669. ---------------------------------------------------------------------------*/
  670. {
  671.     TLX_ASSERT_PTR(aStr1);
  672.     TLX_ASSERT_PTR(aStr2.mString);
  673.     return strcmp(aStr1, aStr2.mString) == 0;
  674. }
  675.  
  676. /*-------------------------------------------------------------------------*/
  677.     int _TLXFUNC operator !=(const TLString &aStr1, const TLString &aStr2)
  678.  
  679. /*  Compares two strings for inequality, returning zero if the are equal.
  680.     The comparison is case sensitive.
  681. ---------------------------------------------------------------------------*/
  682. {
  683.     TLX_ASSERT_PTR(aStr1.mString);
  684.     TLX_ASSERT_PTR(aStr2.mString);
  685.     return strcmp(aStr1.mString, aStr2.mString) != 0;
  686. }
  687.  
  688. /*-------------------------------------------------------------------------*/
  689.     int _TLXFUNC operator !=(const TLString &aStr1, const char *aStr2)
  690.  
  691. /*  Compares two strings for inequality, returning zero if the are equal.
  692.     The comparison is case sensitive.
  693. ---------------------------------------------------------------------------*/
  694. {
  695.     TLX_ASSERT_PTR(aStr1.mString);
  696.     TLX_ASSERT_PTR(aStr2);
  697.     return strcmp(aStr1.mString, aStr2) == 0;
  698. }
  699.  
  700. /*-------------------------------------------------------------------------*/
  701.     int _TLXFUNC operator !=(const char *aStr1, const TLString &aStr2)
  702.  
  703. /*  Compares two strings for inequality, returning zero if the are equal.
  704.     The comparison is case sensitive.
  705. ---------------------------------------------------------------------------*/
  706. {
  707.     TLX_ASSERT_PTR(aStr1);
  708.     TLX_ASSERT_PTR(aStr2.mString);
  709.     return strcmp(aStr1, aStr2.mString) == 0;
  710. }
  711.  
  712. /*-------------------------------------------------------------------------*/
  713.     int _TLXFUNC operator <=(const TLString &aStr1, const TLString &aStr2)
  714.  
  715. /*  Compares two strings for less than or equal, returning nonzero if the
  716.     first string is less than or equal to the second one. The comparison
  717.     is case sensitive.
  718. ---------------------------------------------------------------------------*/
  719. {
  720.     TLX_ASSERT_PTR(aStr1.mString);
  721.     TLX_ASSERT_PTR(aStr2.mString);
  722.     return strcmp(aStr1.mString, aStr2.mString) <= 0;
  723. }
  724.  
  725. /*-------------------------------------------------------------------------*/
  726.     int _TLXFUNC operator <=(const TLString &aStr1, const char *aStr2)
  727.  
  728. /*  Compares two strings for less than or equal, returning nonzero if the
  729.     first string is less than or equal to the second one. The comparison
  730.     is case sensitive.
  731. ---------------------------------------------------------------------------*/
  732. {
  733.     TLX_ASSERT_PTR(aStr1.mString);
  734.     TLX_ASSERT_PTR(aStr2);
  735.     return strcmp(aStr1.mString, aStr2) <= 0;
  736. }
  737.  
  738. /*-------------------------------------------------------------------------*/
  739.     int _TLXFUNC operator <=(const char *aStr1, const TLString &aStr2)
  740.  
  741. /*  Compares two strings for less than or equal, returning nonzero if the
  742.     first string is less than or equal to the second one. The comparison
  743.     is case sensitive.
  744. ---------------------------------------------------------------------------*/
  745. {
  746.     TLX_ASSERT_PTR(aStr1);
  747.     TLX_ASSERT_PTR(aStr2.mString);
  748.     return strcmp(aStr1, aStr2.mString) <= 0;
  749. }
  750.  
  751. /*-------------------------------------------------------------------------*/
  752.     int _TLXFUNC operator < (const TLString &aStr1, const TLString &aStr2)
  753.  
  754. /*  Compares two strings for less than, returning nonzero if the first
  755.     string is less than the second one. The comparison is case sensitive.
  756. ---------------------------------------------------------------------------*/
  757. {
  758.     TLX_ASSERT_PTR(aStr1.mString);
  759.     TLX_ASSERT_PTR(aStr2.mString);
  760.     return strcmp(aStr1.mString, aStr2.mString) < 0;
  761. }
  762.  
  763. /*-------------------------------------------------------------------------*/
  764.     int _TLXFUNC operator < (const TLString &aStr1, const char *aStr2)
  765.  
  766. /*  Compares two strings for less than, returning nonzero if the first
  767.     string is less than the second one. The comparison is case sensitive.
  768. ---------------------------------------------------------------------------*/
  769. {
  770.     TLX_ASSERT_PTR(aStr1.mString);
  771.     TLX_ASSERT_PTR(aStr2);
  772.     return strcmp(aStr1.mString, aStr2) < 0;
  773. }
  774.  
  775. /*-------------------------------------------------------------------------*/
  776.     int _TLXFUNC operator < (const char *aStr1, const TLString &aStr2)
  777.  
  778. /*  Compares two strings for less than, returning nonzero if the first
  779.     string is less than the second one. The comparison is case sensitive.
  780. ---------------------------------------------------------------------------*/
  781. {
  782.     TLX_ASSERT_PTR(aStr1);
  783.     TLX_ASSERT_PTR(aStr2.mString);
  784.     return strcmp(aStr1, aStr2.mString) == 0;
  785. }
  786.  
  787. /*-------------------------------------------------------------------------*/
  788.     int _TLXFUNC operator >=(const TLString &aStr1, const TLString &aStr2)
  789.  
  790. /*  Compares two strings for greater than or equal, returning nonzero if the
  791.     first string is greater than or equal to the second one. The comparison
  792.     is case sensitive.
  793. ---------------------------------------------------------------------------*/
  794. {
  795.     TLX_ASSERT_PTR(aStr1.mString);
  796.     TLX_ASSERT_PTR(aStr2.mString);
  797.     return strcmp(aStr1.mString, aStr2.mString) >= 0;
  798. }
  799.  
  800. /*-------------------------------------------------------------------------*/
  801.     int _TLXFUNC operator >=(const TLString &aStr1, const char *aStr2)
  802.  
  803. /*  Compares two strings for greater than or equal, returning nonzero if the
  804.     first string is greater than or equal to the second one. The comparison
  805.     is case sensitive.
  806. ---------------------------------------------------------------------------*/
  807. {
  808.     TLX_ASSERT_PTR(aStr1.mString);
  809.     TLX_ASSERT_PTR(aStr2);
  810.     return strcmp(aStr1.mString, aStr2) >= 0;
  811. }
  812.  
  813. /*-------------------------------------------------------------------------*/
  814.     int _TLXFUNC operator >=(const char *aStr1, const TLString &aStr2)
  815.  
  816. /*  Compares two strings for greater than or equal, returning nonzero if the
  817.     first string is greater than or equal to the second one. The comparison
  818.     is case sensitive.
  819. ---------------------------------------------------------------------------*/
  820. {
  821.     TLX_ASSERT_PTR(aStr1);
  822.     TLX_ASSERT_PTR(aStr2.mString);
  823.     return strcmp(aStr1, aStr2.mString) >= 0;
  824. }
  825.  
  826. /*-------------------------------------------------------------------------*/
  827.     int _TLXFUNC operator > (const TLString &aStr1, const TLString &aStr2)
  828.  
  829. /*  Compares two strings for greater than, returning nonzero if the
  830.     first string is greater than the second one. The comparison
  831.     is case sensitive.
  832. ---------------------------------------------------------------------------*/
  833. {
  834.     TLX_ASSERT_PTR(aStr1.mString);
  835.     TLX_ASSERT_PTR(aStr2.mString);
  836.     return strcmp(aStr1.mString, aStr2.mString) > 0;
  837. }
  838.  
  839. /*-------------------------------------------------------------------------*/
  840.     int _TLXFUNC operator > (const TLString &aStr1, const char *aStr2)
  841.  
  842. /*  Compares two strings for greater than, returning nonzero if the
  843.     first string is greater than the second one. The comparison
  844.     is case sensitive.
  845. ---------------------------------------------------------------------------*/
  846. {
  847.     TLX_ASSERT_PTR(aStr1.mString);
  848.     TLX_ASSERT_PTR(aStr2);
  849.     return strcmp(aStr1.mString, aStr2) > 0;
  850. }
  851.  
  852. /*-------------------------------------------------------------------------*/
  853.     int _TLXFUNC operator > (const char *aStr1, const TLString &aStr2)
  854.  
  855. /*  Compares two strings for greater than, returning nonzero if the
  856.     first string is greater than the second one. The comparison
  857.     is case sensitive.
  858. ---------------------------------------------------------------------------*/
  859. {
  860.     TLX_ASSERT_PTR(aStr1);
  861.     TLX_ASSERT_PTR(aStr2.mString);
  862.     return strcmp(aStr1, aStr2.mString) > 0;
  863. }
  864.  
  865. /*-------------------------------------------------------------------------*/
  866.     ostream & _TLXFUNC operator <<(ostream &os, const TLString &s)
  867.  
  868. /*  Output operator for strings.
  869. ---------------------------------------------------------------------------*/
  870. {
  871.     // The call to os.write() causes problems when linking with BC++ 4.0
  872.     // DLL RTL. It appears that the os.write() is not properly exported
  873.     // under these circumstances, and the linker therefore fails to find it.
  874.     // Until we have sorted this out, we remove the call.
  875.     //
  876.     // The BC++ 4.0 compiler has __BORLANDC__ version # 0x452
  877.  
  878. #if defined(OS_WINXXX) && defined(__BORLANDC__) && (__BORLANDC__ == 0x452)
  879.     // Warn our users
  880.     TLX_NOTIMPLEMENTED(operator <<(ostream &os, const TLString &s));
  881.     return os;
  882. #else
  883.     // Normal behavior
  884.     return os.write(s.mString, s.mLen);
  885. #endif
  886. }
  887.  
  888. /*-------------------------------------------------------------------------*/
  889.     void _TLXFUNC tlSwap(TLString &s1, TLString &s2)
  890.  
  891. /*  Swaps the contents of two strings efficiently.
  892. ---------------------------------------------------------------------------*/
  893. {
  894.     if (&s1 == &s2) return;
  895.  
  896.     char *tmps = s1.mString;
  897.     s1.mString = s2.mString;
  898.     s2.mString = tmps;
  899.  
  900.     size_t tmpsz = s1.mSize;
  901.     s1.mSize = s2.mSize;
  902.     s2.mSize = tmpsz;
  903.  
  904.     size_t tmpl = s1.mLen;
  905.     s1.mLen = s2.mLen;
  906.     s2.mLen = tmpl;
  907. }
  908.