home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / base / string.h < prev    next >
C/C++ Source or Header  |  1995-04-08  |  19KB  |  557 lines

  1.  
  2.  
  3. #ifndef _string_h_
  4. #define _string_h_
  5.  
  6.  
  7.  
  8.  
  9.  
  10. /*
  11.  *
  12.  *          Copyright (C) 1994, M. A. Sridhar
  13.  *  
  14.  *
  15.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  16.  *     to copy, modify or distribute this software  as you see fit,
  17.  *     and to use  it  for  any  purpose, provided   this copyright
  18.  *     notice and the following   disclaimer are included  with all
  19.  *     copies.
  20.  *
  21.  *                        DISCLAIMER
  22.  *
  23.  *     The author makes no warranties, either expressed or implied,
  24.  *     with respect  to  this  software, its  quality, performance,
  25.  *     merchantability, or fitness for any particular purpose. This
  26.  *     software is distributed  AS IS.  The  user of this  software
  27.  *     assumes all risks  as to its quality  and performance. In no
  28.  *     event shall the author be liable for any direct, indirect or
  29.  *     consequential damages, even if the  author has been  advised
  30.  *     as to the possibility of such damages.
  31.  *
  32.  */
  33.  
  34.  
  35.  
  36. // This class provides the basic functionality for manipulating a
  37. // printable string of characters.
  38.  
  39.  
  40.  
  41.  
  42. #ifdef __GNUC__
  43. #pragma interface
  44. #endif
  45.  
  46. #include "base/object.h"
  47.  
  48. class CL_EXPORT CL_StringSequence;
  49. class CL_EXPORT CL_Substring;
  50. class CL_EXPORT CL_StringSplitter;
  51.  
  52. class CL_EXPORT  CL_String: public CL_Object {
  53.  
  54. public:
  55.     //
  56.     // ----------------------------- Constructors -------------------------
  57.     //
  58.  
  59.     CL_String ();
  60.     // Default: construct the null string.
  61.  
  62.     CL_String (const char* strg);
  63.     // Construct a string from the given null-terminated char array.
  64.  
  65.     CL_String (long value, short minwidth = 1, char padChar = ' ');
  66.     // Construct a string containing the digits of 'value', in a field
  67.     // at least minwidth characters wide. Pad, if necessary, with as many of
  68.     // the given padding characters as necessary on the left.
  69.  
  70.     CL_String (CL_ByteArray& b);
  71.     // Copy b's contents and append a null byte.
  72.     
  73.     CL_String (char c, short count);
  74.     // Produce a string with c  repeated count times.
  75.                 
  76.     CL_String (const CL_String& strg);
  77.     // Copy constructor.
  78.     
  79.     
  80.     ~CL_String();
  81.     // Destructor.
  82.  
  83.     //
  84.     // -------------------------- Conversion -------------------------------
  85.     //
  86.  
  87.     operator const char* () const;
  88.     // Return pointer to null-terminated char array representation.
  89.     // The caller of this method should not modify the returned char
  90.     // array.
  91.  
  92.     const char* AsPtr() const;
  93.     // Synonym for {\tt operator const char*}.
  94.  
  95.     long AsLong() const;
  96.     // Find the longest prefix that is all digits, and return them as
  97.     // a long value.
  98.  
  99.     double AsDouble () const;
  100.     // Find our longest prefix that looks like a double number, and
  101.     // return it as a double value.
  102.     
  103.  
  104.     // ----------- Structural manipulations, substrings ------------------
  105.  
  106.     long Size() const {return _size;} ;
  107.     // Return the size of the string.
  108.  
  109.     long Length() const { return _size; };
  110.     // Return the size of the string.
  111.     
  112.     char operator[] (long index) const;
  113.     // Return character at given index.
  114.  
  115.  
  116.     CL_Substring operator() (long position, long size);
  117.     // Return the substring beginning at the given position and of the
  118.     // given size. Note that this is not a const method, because the
  119.     // returned substring can be assigned to.
  120.  
  121.     CL_Substring Suffix (long position);
  122.     // Return our suffix beginning at the given position. Note that this
  123.     // is not a const method, because the returned substring can be
  124.     // assigned to.
  125.  
  126.     // -------------------- Search-related methods ---------------------
  127.  
  128.  
  129.     // --- Character searches --
  130.     
  131.     long CharIndex (char c, long pos = 0L) const;
  132.     // Return the index of the first position, at or right of 'pos', that
  133.     // contains the character c. Return -1 if no such position.
  134.  
  135.     long NCharIndex (char c, long pos = 0L) const;
  136.     // Return the index of the first position, at or right of 'pos', that
  137.     // does not contain the character c. Return -1 if no such position.
  138.  
  139.          
  140.     long CharIndex (const char* s, long pos = 0L) const;
  141.     // Return the index of the first position, at or right of 'pos', that
  142.     // contains any one of the characters in s. Return -1 if no such position.
  143.  
  144.     long NCharIndex (const char* s, long pos = 0L) const;
  145.     // Return the index of the first position, at or right of 'pos', that
  146.     // contains none of the characters in s. Return -1 if no such position.
  147.  
  148.     
  149.     // ---- String searches ---
  150.  
  151.     
  152.     bool IsPrefixOf (const char* p) const;
  153.     // Are we a prefix of the given string?
  154.  
  155.     long Index (const char* s, long pos = 0, long n = 1) const;
  156.     // Return the left end of the n-th occurrence of the string s in
  157.     // our string; begin the search for s at position pos. Return -1 if 
  158.     // no more than n-1 such occurrences of s were found.
  159.  
  160.     long Replace (const char* s1, const char* s2, long pos = 0, long n = 1);
  161.     // Scan our string beginning at position pos, and replace the
  162.     // first n occurrences of s1 in our string with s2. 
  163.     // Return the number of successful replacements that occurred.
  164.     // Note that if s2 is NULL or points to a null string, the
  165.     // occurrences of s1 are removed. If s1 is null, no replacements
  166.     // will be made.
  167.     //    This method returns 0 if memory allocation fails.
  168.  
  169.     long ReplaceAll (const char* s1, const char* s2, long pos = 0);
  170.     // Beginning at position pos, replace all occurrences of s1 with
  171.     // s2, as in Replace. Return the number of replacements that took
  172.     // place.
  173.  
  174.     
  175.  
  176.     // ------------------------ Decomposition ----------------------------
  177.     //
  178.     
  179.     CL_String Field (long n, const char field_seps[] = " \t") const;
  180.     // View our string as being made up of fields, separated by one or
  181.     // more characters from the null-terminated string field_seps. Return
  182.     // the n-th field. Fields are indexed from 1, i.e., n == 1 returns the
  183.     // leftmost field. If n is 0, the entire string is returned. (This
  184.     // function is similar to the functionality in awk.)
  185.  
  186.     CL_StringSequence Split (const char field_seps[] = " \t") const;
  187.     // View our string as being made up of fields, separated by one or
  188.     // more characters from the null-terminated string field_seps. Return
  189.     // the sequence of fields in us.
  190.     
  191.     CL_StringSequence Split (char field_sep) const;
  192.     // View our string as being made up of fields, separated by {\it one\/}
  193.     // occurence of the given character. Return the sequence of fields in
  194.     // our string.
  195.     
  196.     long Split (CL_String fld[], long n, const char field_seps[] = " \t")
  197.         const;
  198.     // View our string as being made up of fields, separated by one or
  199.     // more characters from the string field_seps. Return the value of
  200.     // fld as follows:
  201.     //      fld[0..n-2]    contains the first n-1 fields, if there are
  202.     //                     that many fields
  203.     //      fld[n-1]       contains the remaining part of the string
  204.     // Return the actual number of cells used in fld as the function
  205.     // value.
  206.     // Note that fld is an array of CL_String objects provided by the
  207.     // caller, and must have at least n CL_Strings in it.
  208.  
  209.     
  210.     //
  211.     // ------------------------ Comparison -----------------------------------
  212.     
  213.     bool operator<  (const CL_Object& strg) const;
  214.  
  215.     bool operator<= (const CL_Object& strg) const;
  216.  
  217.     bool operator>  (const CL_Object& strg) const;
  218.  
  219.     bool operator>= (const CL_Object& strg) const;
  220.  
  221.     bool operator== (const CL_Object& strg) const;
  222.  
  223.     bool operator!= (const CL_Object& strg) const;
  224.  
  225.     
  226.  
  227.     virtual bool operator<  (const char* strg) const;
  228.  
  229.     virtual bool operator<= (const char* strg) const;
  230.  
  231.     virtual bool operator>  (const char* strg) const;
  232.  
  233.     virtual bool operator>= (const char* strg) const;
  234.  
  235.     virtual bool operator== (const char* strg) const;
  236.  
  237.     virtual bool operator!= (const char* strg) const;
  238.  
  239.     short Compare (const CL_Object& obj) const;
  240.     // Compare returns -1 if we are less than the given string, 0 if
  241.     // the two are equal, and +1 if we are greater. The method issues a
  242.     // runtime error message if the given object does not have the class id
  243.     // of a string.
  244.     
  245.     short Compare (const CL_String& s) const;
  246.     // Compare returns -1 if we are less than the given string, 0 if
  247.     // the two are equal, and +1 if we are greater.
  248.  
  249.     bool CompareWith (const CL_String& obj,
  250.                       CL_Object::ComparisonOperator op) const;
  251.  
  252.     bool CompareWith (const CL_Object& obj,
  253.                       CL_Object::ComparisonOperator op) const;
  254.     // Overrides CL_Object's CompareWith method. Checks that obj's class id
  255.     // is the same as ours and then invokes Compare with obj cast down to
  256.     // CL_String. (Returns FALSE if class id does not match.)
  257.  
  258.  
  259.  
  260.     // --------------------------String modification ----------------------
  261.  
  262.     virtual bool Insert (char c, long position = -1);
  263.     // Insert a character into the string, immediately to the right of the
  264.     // given position, thus expanding the string. The default position of
  265.     // -1 specifies insertion at the left end of the string. 
  266.     // Return TRUE if successful, FALSE if either an invalid position is
  267.     // specified, a pre-change dependent refused change, or else memory
  268.     // allocation failure occurred.
  269.  
  270.     virtual bool Insert (const char* p, long position = -1);
  271.     // Insert a null-terminated character string into ourselves. Note that the
  272.     // effect is equivalent to assigning to the null substring at the
  273.     // given position; i.e., {\tt s.Insert (p, pos)} is the same as {\tt s
  274.     // (position+1, 0) = p;}
  275.  
  276.     bool Append (char c);
  277.     // Append the given character to the string. This method is equivalent
  278.     // to using the += operator, but is a little more efficient for single
  279.     // character appends.
  280.  
  281.     bool AssignWithFormat (const char* format, ...);
  282.     // Create a char buffer whose contents are identical to those produced
  283.     // if the parameters were passed to printf; assign the result to this
  284.     // string. The resulting string should not exceed 1000 chars in
  285.     // length; if it does, this method issues a memory corruption warning
  286.     // and returns FALSE. Otherwise, it returns TRUE.
  287.     
  288.     // --------- Assignments of various kinds
  289.     
  290.     virtual void operator= (const char* strg);
  291.  
  292.     virtual void operator= (const CL_String& strg);
  293.  
  294.     virtual void operator= (const CL_Object& strg);
  295.     // Check that the given parameter is really a string (via the
  296.     // inherited {\tt IsA} method), and
  297.     // assign its value to this string.
  298.     
  299.     virtual void operator= (long l);
  300.     // Convert the given long value into a string, and assign it to
  301.     // this string.
  302.  
  303.     virtual void operator= (double d);
  304.     // Convert the given double value into a string and assign it to
  305.     // this string.
  306.  
  307.     
  308.  
  309.     // Concatenations of various kinds
  310.     
  311.     virtual CL_String operator+  (const char* strg) const;
  312.     // Return the string obtained by concatenating the null-terminated
  313.     // parameter strg to this string.
  314.  
  315.     virtual CL_String operator+  (const CL_String& strg) const;
  316.     // Return the string obtained by concatenating strg to our value.
  317.  
  318.     virtual CL_String& operator+= (const char* strg);
  319.     // Append the given (null-terminated) string to this string, and then
  320.     // return this string.
  321.  
  322.     virtual CL_String& operator+= (const CL_String& strg);
  323.  
  324.     CL_String operator+ (long v) const;
  325.     // Convert the long value into a decimal string and return the result of
  326.     // appending it to ourselves.
  327.  
  328.     CL_String& operator+= (long v);
  329.     // Append the string representation of the long value to ourselves.
  330.     
  331.     virtual CL_String operator- (const char* s) const;
  332.     // "Subtraction" operator:
  333.     // Return the string resulting from the removal of the suffix
  334.     // beginning with the first occurrence of the given string.
  335.     // Thus "Alpha Beta Gamma" - "Beta" yields "Alpha ". If the given
  336.     // string does not occur in us, simply return (a copy of) ourselves.
  337.  
  338.     void operator-= (const char* s)
  339.         { *this = *this - s;};
  340.     
  341.  
  342.     // --------------------- Storage and restoration -------------------
  343.     
  344.     virtual long StorableFormWidth () const;
  345.  
  346.     virtual bool ReadFrom (const CL_Stream&);
  347.     // Read and reconstruct ourselves from the binary representation in
  348.     // the given stream. Return TRUE on success, FALSE if failed for any
  349.     // reason, including when a pre-change dependent disallows the change.
  350.  
  351.     virtual bool WriteTo  (CL_Stream&) const;
  352.     // Write the passive binary representation of this object into the
  353.     // given stream. Return TRUE if successful, FALSE otherwise.
  354.  
  355.     CL_String AsString () const
  356.         { return *this; };
  357.     // Override the method inherited from {\small\tt CL_Object}.
  358.  
  359.     void FromStream (istream& stream);
  360.     // Override the method inherited from {\small\tt CL_Object}. The
  361.     // implementation skips any occurrences of the current fill character
  362.     // of the stream, and then collects non-fill characters into this
  363.     // string.
  364.  
  365.     virtual istream& ReadLine (istream& stream);
  366.     // Read everything upto and including the next end-of-line marker (or
  367.     // end-of-file) on the given stream, and set our value to the result.
  368.  
  369.     
  370.     // ------------------------ Miscellaneous methods ----------------
  371.     
  372.     virtual bool PadTo (long num_chars, char pad_char = ' ',
  373.                         bool left_justified = TRUE);
  374.     // Pad ourselves (if necessary)  to fill out  to  the given number of
  375.     // characters.   The padding  character is the second parameter, and  the
  376.     // third parameter specifies whether the padding occurs on the right side
  377.     // (i.e.,  left   justification)   or   the   left   side   (i.e.,  right
  378.     // justification).   If  num_chars is smaller than our size, we  remain
  379.     // unchanged. Return TRUE if padding occurred, FALSE if either the string
  380.     // remained unchanged or memory allocation failed.
  381.  
  382.     CL_String InUpperCase () const;
  383.     // Return this string with all lower-case letters replaced by upper-case
  384.     // ones.
  385.  
  386.     CL_String InLowerCase () const;
  387.     // Return this string with all upper-case letters replaced by
  388.     // lower-case ones.
  389.  
  390.     virtual long ToUpper ();
  391.     // Convert all lower-case characters to upper case. Return the number of
  392.     // characters converted. Note that this can be combined with the
  393.     // operator() to operate on substrings; e.g.,
  394.     //               myString (10,3).ToUpper();
  395.     // converts all lower-case characters between positions 10 and 12 to
  396.     // upper-case.
  397.  
  398.     virtual long ToLower ();
  399.     // Convert all upper-case characters to lower case. Return the number of
  400.     // characters converted.
  401.  
  402.     virtual bool WordCapitalize ();
  403.     // If this string begins with an alphabet, render the first letter
  404.     // of the first word upper case, and all other letters in that
  405.     // word lower case. Return TRUE if this change was effected, and
  406.     // FALSE otherwise.
  407.     
  408.     //
  409.     // ------------- Basic methods -------------------------
  410.     //
  411.  
  412.     const char* ClassName() const {return "CL_String";};
  413.  
  414.     CL_ClassId ClassId() const { return _CL_String_CLASSID;};
  415.  
  416.     CL_Object* Clone() const {return new CL_String (*this);};
  417.  
  418.     // -------------------- End public protocol ------------------
  419.  
  420.  
  421.     
  422. protected:
  423.  
  424.     CL_String (const char* s, long len); // Protected constructor
  425.  
  426.     virtual bool _Init (long size);
  427.  
  428.     bool _DoInsert (const char*, long);
  429.     // Do insertion without notification
  430.     
  431.     friend CL_Substring;
  432.     friend CL_StringSplitter;
  433.     
  434.     char* _string;
  435.     long  _capacity;
  436.     long  _size;
  437. };
  438.  
  439.  
  440.  
  441.  
  442.  
  443. class CL_EXPORT CL_Substring: public CL_String {
  444.  
  445. public:
  446.  
  447.     virtual void operator= (const char* strg)
  448.         {CL_String::operator= (strg);};
  449.     // Ensure that all assignment operators are inherited.
  450.     
  451.     virtual void operator= (const CL_String& strg)
  452.         {CL_String::operator= (strg);};
  453.  
  454.     virtual void operator= (const CL_Object& strg);
  455.  
  456.     virtual void operator= (long l)
  457.         {CL_String::operator= (l);};
  458.  
  459.     virtual void operator= (double d)
  460.         {CL_String::operator= (d);};
  461.     
  462.     ~CL_Substring ();
  463.  
  464. protected:
  465.     
  466.     CL_Substring (CL_String& s, long pos, long length);
  467.     // The constructor is protected, so that a Substring cannot be directly
  468.     // constructed.
  469.  
  470.     CL_Substring (const CL_Substring&);
  471.  
  472.     bool _Modified (CL_Object&, long);
  473.     // The method called to notify us when our value changes, so that we may
  474.     // modify the real client.
  475.  
  476.     friend CL_String;
  477.     CL_String& _client; // The string that we are a substring of
  478.     long       _pos;    // Where the substring begins
  479.     long       _len;    // How long the substring was when constructed
  480. };
  481.  
  482.  
  483.  
  484. // Return pointer to char array representation
  485. inline const char* CL_String::AsPtr() const
  486. {
  487.     return _string;
  488. }
  489.  
  490. inline CL_String::operator const char* () const
  491. {
  492.     return _string;
  493. }
  494.  
  495.  
  496.  
  497. // Return character at given index
  498. inline char CL_String::operator[] (long index) const
  499. {
  500.     assert (index >= 0 && index < _size,
  501.             ("CL_String::operator[]:"
  502.             " invalid index %ld string size %ld", index, Size()));
  503. #if defined(__DOS__) || defined(__MS_WINDOWS__)
  504.     return _string[(short) index];
  505. #else
  506.     return _string[index];
  507. #endif
  508. }
  509.  
  510.  
  511.  
  512. inline void CL_String::operator= (const CL_Object& s)
  513. {
  514.     if (CheckClassType (s, "CL_String::op="))
  515.         *this = (const CL_String&) s;
  516. }
  517.  
  518.  
  519. inline CL_Substring CL_String::Suffix (long position)
  520. {
  521.     return (*this) (position, Size() - position);
  522. }
  523.  
  524.  
  525. inline CL_String operator+ (const char* s1, const CL_String& s2)
  526. {
  527.     return CL_String (s1) + s2;
  528. }
  529.  
  530. inline bool CL_String::Append (char c)
  531. {
  532.     long pos = Size() - 1;
  533.     return Insert (c, pos);
  534. }
  535.  
  536.  
  537. inline CL_String& CL_String::operator+= (long v)
  538. {
  539.     *this = *this + v;
  540.     return *this;
  541. }
  542.  
  543.  
  544. inline bool CL_String::CompareWith (const CL_Object& obj,
  545.                                     CL_Object::ComparisonOperator op) const
  546. {
  547.     return ClassId() == obj.ClassId() ?
  548.         CompareWith ((const CL_String&) obj, op) : FALSE;
  549. }
  550.  
  551. inline void CL_Substring::operator= (const CL_Object& strg)
  552. {
  553.     CL_String::operator= (strg);
  554. }
  555.  
  556. #endif
  557.