home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 6.ddi / MWHC.006 / Y0 < prev    next >
Encoding:
Text File  |  1992-06-07  |  14.0 KB  |  355 lines

  1. #ifndef __RWCSTRING_H__
  2. #define __RWCSTRING_H__
  3. pragma push_align_members(64);
  4.  
  5. /*
  6.  * Declarations for the RWCString class
  7.  *
  8.  * $Header:   E:/vcs/rw/cstring.h_v   1.4   17 Mar 1992 19:21:08   KEFFER  $
  9.  *
  10.  ****************************************************************************
  11.  *
  12.  * Rogue Wave Software, Inc.
  13.  * P.O. Box 2328
  14.  * Corvallis, OR 97339
  15.  * Voice: (503) 754-3010    FAX: (503) 757-6650
  16.  *
  17.  * Copyright (C) 1989, 1990, 1991, 1992. 
  18.  * This software is subject to copyright protection under the laws of 
  19.  * the United States and other countries.
  20.  *
  21.  ***************************************************************************
  22.  *
  23.  * This class is extremely similar to the old RWString class.  The only
  24.  * difference is that its copy constructor and assignment operator uses
  25.  * copy semantics instead of reference semantics.
  26.  *
  27.  * It accomplishes this through a technique called "copy-on-write".
  28.  * Multiple instances of a string can refer to the same piece of data
  29.  * so long as it is in a "readonly" situation.  If a string writes to
  30.  * the data, then a copy is automatically made if more than one string
  31.  * is referring to it.
  32.  *
  33.  ***************************************************************************
  34.  *
  35.  * $Log:   E:/vcs/rw/cstring.h_v  $
  36.  * 
  37.  *    Rev 1.4   17 Mar 1992 19:21:08   KEFFER
  38.  * Changed BOUNDS_CHECK to RWBOUNDS_CHECK
  39.  * 
  40.  *    Rev 1.3   17 Mar 1992 11:55:30   KEFFER
  41.  * 
  42.  *    Rev 1.2   17 Mar 1992 11:36:48   KEFFER
  43.  * RWStringRef now inherits from RWReference.
  44.  * 
  45.  *    Rev 1.1   07 Mar 1992 12:33:06   KEFFER
  46.  * Fine tuned copy-on-write.
  47.  * 
  48.  */
  49.  
  50. #include "rw/tooldefs.h"
  51. #include "rw/ref.h"
  52. #include "rw/procinit.h"    /* Uses instance mgr. */
  53. STARTWRAP
  54. #include <string.h>
  55. #include <ctype.h>
  56. #include <stddef.h>
  57. ENDWRAP
  58.  
  59. class RWExport RWCString;
  60. class RWExport RWRegexp;
  61. class RWExport RWCSubString;
  62.  
  63. /****************************************
  64.  *                    *
  65.  *        RWStringRef        *
  66.  *                    *
  67.  ****************************************/
  68.  
  69. /*
  70.  * This is the dynamically allocated part of a RWCString.
  71.  * It maintains a reference count.
  72.  * There are no public member functions.  
  73.  */
  74. class RWExport RWStringRef : public RWReference {
  75. friend class RWExport RWCString;
  76. friend class RWExport RWCSubString;
  77.   char*            array;        // Pointer to the data
  78.   unsigned        nchars;        // String length (excluding terminating null)
  79.   unsigned        capacity;    // String capacity
  80.  
  81.   // All constructors are private:
  82.   RWStringRef();
  83.   RWStringRef(unsigned N);
  84.   RWStringRef(unsigned N, char c);
  85.   RWStringRef(const char*);
  86.   RWStringRef(const char* a, unsigned N);
  87.   RWStringRef(const RWCString& s, const char* a);
  88.   ~RWStringRef();
  89.  
  90.   void            checkFreeboard();
  91.   void            growTo(unsigned N);
  92.   void            readToDelim(istream&, char delim);
  93.   void            readToken(istream&);
  94.   void            restoreFrom(RWvistream&);
  95.   void            restoreFrom(RWFile&);
  96.   static unsigned    roundCapacity(unsigned);
  97.   void            splice(unsigned start, unsigned extent, const char* dat, unsigned N);
  98. };
  99.  
  100.  
  101. /****************************************
  102.  *                    *
  103.  *        RWCSubString        *
  104.  *                    *
  105.  ****************************************/
  106.  
  107. /*
  108.  * The RWCSubString class allows selected elements to be addressed.
  109.  * There are no public constructors.
  110.  */
  111.  
  112. class RWExport RWCSubString : public RWMemoryPool {
  113. private:
  114.   friend class RWExport RWCString;
  115.   RWCString*      S;      // Pointer to the RWCString
  116.   int        begin;      // Index of starting character
  117.   unsigned    extent;      // Length of RWCSubString
  118. private:
  119.   RWCSubString(const RWCString* s, int start, unsigned len); // Constructor is private
  120. protected:
  121.   void        subStringError(unsigned, int, unsigned) const;
  122.   void        assertElement(int i) const;    // Verifies i is valid index
  123. public:
  124.   RWCSubString(const RWCSubString& SP)
  125.      {S=SP.S;begin=SP.begin;extent=SP.extent;}
  126.  
  127.   RWCSubString&    operator=(const char*);        // Assignment to char*
  128.   RWCSubString&    operator=(const RWCString&);    // Assignment to RWCString
  129.   RWBoolean    operator==(const char* s) const;// Test for equality.
  130.   RWBoolean    operator==(const RWCString& str) const;
  131.   RWBoolean    operator!=(const char* s) const {return !operator==(s);}
  132.   RWBoolean    operator!=(const RWCString& str) const;
  133.   char&      operator()(int i);        // Index with optional bounds checking
  134.   char&      operator[](int i);        // Index with bounds checking
  135. #ifdef CONST_OVERLOADS
  136.   char      operator()(int i) const;    // Index with optional bounds checking
  137.   char      operator[](int i) const;    // Index with bounds checking
  138. #endif
  139.   unsigned    length() const        {return extent;}
  140.   int        start() const        {return begin;}
  141.   void        toLower();            // Convert self to lower-case
  142.   void        toUpper();            // Convert self to upper-case
  143.  
  144.   // For detecting null substrings:
  145.   RWBoolean    isNull() const        {return begin<0;}
  146.   int        operator!() const    {return begin<0;}
  147. //  operator    const char*() const;    // Returns start of substring
  148. };
  149.  
  150.  
  151. /****************************************
  152.  *                    *
  153.  *        RWCString        *
  154.  *                    *
  155.  ****************************************/
  156.  
  157. class RWExport RWCString {
  158.   RWStringRef        *p;
  159. #ifndef RW_MULTI_THREAD
  160.   /* If not compiling for an MT situation, then use static data--- */
  161.   static RWBoolean    caseSensitive;        // For pattern matching.
  162.   static RWBoolean    paranoidCheck;        // If matching hash isn't good enough.
  163.   static RWBoolean    skipWhite;        // True to skip whitespace after token read.
  164.   static unsigned    initialCapac;        // Initial allocation capacity
  165.   static unsigned    resizeInc;        // Resizing increment
  166.   static unsigned    freeboard;        // Max empty space before reclaim
  167. #endif
  168. private:
  169.   friend class RWExport RWCSubString;
  170.   friend class RWExport RWStringRef;
  171.   void            clone(); /* used during copy on write */
  172.   int            findCaseIndex(const char*, int, unsigned& patl) const;    // Case sensitive, used internally
  173.   int            findIndex(const char*, int, unsigned& patl) const;    // Switchable sensitivity
  174.   unsigned        hashCase() const;                    // Case sensitive hash, used internally
  175. protected:
  176.   void assertElement(int) const;    // Index in range
  177.   RWCString(const RWCString&, const char*);
  178.   void cow();                // Do copy on write as needed
  179. public:
  180.   enum stripType {leading, trailing, both};
  181.  
  182.   RWCString();                // Construct null string;
  183.   RWCString(const char *);        // Conversion from char*
  184.   RWCString(const char *, unsigned N);    // Construct from at most N characters.
  185.   RWCString(unsigned N, char c = ' ');    // N characters (default blank).
  186.   RWCString(const RWCString&);        // Copy constructor.
  187.   RWCString(const RWCSubString&);        // Conversion from sub-string.
  188.   ~RWCString();                // Destructor.
  189.  
  190.   // Type conversion:
  191. #ifndef ZTC_TYPE_CONVERSION_BUG  
  192.   operator        const char*() const {return p->array;}
  193. #endif
  194.  
  195.   // Assignment:
  196.   RWCString&    operator=(const RWCString&);    // Replace string
  197.   RWCString&    operator+=(const char*);    // Append string.
  198.   RWCString&    operator+=(const RWCString& s) {return operator+=(s.data());}
  199.  
  200.   // Logical operators:
  201.   RWBoolean    operator==(const char* s) const;
  202.   RWBoolean    operator!=(const char* s) const {return !operator==(s);}
  203.   RWBoolean    operator< (const char* s) const;
  204.   RWBoolean    operator> (const char* s) const;
  205.   RWBoolean    operator<=(const char* s) const {return !operator>(s);}
  206.   RWBoolean    operator>=(const char* s) const {return !operator<(s);}
  207.  
  208.   // Too many compilers have problems to rely on type conversion:
  209.   RWBoolean    operator==(const RWCString& s) const {return  operator==(s.data());}
  210.   RWBoolean    operator!=(const RWCString& s) const {return !operator==(s.data());}
  211.   RWBoolean    operator< (const RWCString& s) const {return  operator< (s.data());}
  212.   RWBoolean    operator> (const RWCString& s) const {return  operator> (s.data());}
  213.   RWBoolean    operator<=(const RWCString& s) const {return !operator> (s.data());}
  214.   RWBoolean    operator>=(const RWCString& s) const {return !operator< (s.data());}
  215.  
  216.   // Indexing operators:
  217.   char&        operator[](int);            // Indexing with bounds checking
  218.   char&        operator()(int);            // Indexing with optional bounds checking
  219.   RWCSubString    operator()(int start, unsigned len);    // Sub-string operator
  220.   RWCSubString    operator()(const RWRegexp& re);            // Substring matching the RE
  221.   RWCSubString    operator()(const RWRegexp& re, int start);    // Substring matching the RE
  222.   RWCSubString    subString(const char* pat, int start=0);    // Substring matching pat; must be m.f. else type conversion ambiguity
  223. #ifdef CONST_OVERLOADS
  224.   char            operator[](int) const;
  225.   char            operator()(int) const;
  226.   const RWCSubString    operator()(int start, unsigned len) const;
  227.   const RWCSubString    operator()(const RWRegexp& pat) const;            // Substring matching RE
  228.   const RWCSubString    operator()(const RWRegexp& pat, int start) const;    // Substring matching RE
  229.   const RWCSubString    subString(const char* pat, int start=0) const;        // Substring matching pat
  230. #endif
  231.   
  232.   // Static member functions:
  233.   static RWBoolean    setCaseSensitive(RWBoolean tf = TRUE);    // For pattern matching.
  234.   static RWBoolean    setParanoidCheck(RWBoolean ck = TRUE);    // If matching hash isn't good enough.
  235.   static RWBoolean    skipWhitespace(RWBoolean sk = TRUE);    // True to skip whitespace after token read.
  236.   static unsigned    initialCapacity(unsigned ic = 63);    // Initial allocation capacity
  237.   static unsigned    resizeIncrement(unsigned ri = 64);    // Resizing increment
  238.   static unsigned    maxWaste(unsigned mw = 63);        // Max empty space before reclaim
  239. #ifdef RW_MULTI_THREAD
  240.   // Just declarations --- static data must be retrieved from the instance manager.
  241.   static RWBoolean    getCaseSensitiveFlag();
  242.   static RWBoolean    getParanoidCheckFlag();
  243.   static RWBoolean    getSkipWhitespaceFlag();
  244.   static unsigned    getInitialCapacity();
  245.   static unsigned    getResizeIncrement();
  246.   static unsigned    getMaxWaste();
  247. #else
  248.   static RWBoolean    getCaseSensitiveFlag()    {return caseSensitive;}
  249.   static RWBoolean    getParanoidCheckFlag()    {return paranoidCheck;}
  250.   static RWBoolean    getSkipWhitespaceFlag()    {return skipWhite;}
  251.   static unsigned    getInitialCapacity()    {return initialCapac;}
  252.   static unsigned    getResizeIncrement()    {return resizeInc;}
  253.   static unsigned    getMaxWaste()        {return freeboard;}
  254. #endif
  255.  
  256.   // Non-static member functions:
  257.   RWCString&    append(const char* str, unsigned N); // append N character of str
  258.   unsigned    binaryStoreSize() const    {return length()+sizeof(unsigned);}
  259.   unsigned    capacity() const {return p->capacity;}
  260.   int        compareTo(const RWCString&) const;    // Compare strings lexicographically.
  261.   RWBoolean    contains(const char* pattern) const;
  262.   RWBoolean    contains(const RWCString& s) const      {return contains(s.data());}
  263.   RWCString        copy() const;                // Distinct copy of self.
  264.   const char*      data() const {return p->array;}        // Access to start of string.
  265.   int        first(char c) const;            // First occurrence of c
  266.   int        first(const char* cs) const;        // First occurrence of any char in cs
  267.   unsigned    hash() const;                    // Return hashing value.
  268.   int        index(const char* pat, int i=0) const;    // Search for string.
  269.   int        index(const RWCString& s, int i=0) const {return index(s.data(), i);}
  270.   int        index(const RWRegexp& pat, int i=0) const; // Search for Regular Expression
  271.   int        index(const RWRegexp& pat, int* ext, int i=0) const;
  272.   RWBoolean    isNull() const {return *p->array==0;}    // Is this the null string?
  273.   int        last(char c) const;            // Last occurrence of char c
  274.   unsigned      length() const { return p->nchars; }    // Excluding terminating null character.
  275.   RWCString&    prepend(const char*);            // Prepend a character string
  276.   RWCString&    prepend(const char* str, unsigned N);    // prepend N chars of str
  277.   RWCString&    prepend(const RWCString& s) {return prepend(s.data());}
  278.   istream&    readFile(istream&);            // Read to EOF or null character.
  279.   istream&    readLine(istream&);            // Read to EOF or newline.
  280.   istream&    readString(istream&);            // Read to EOF or null character.
  281.   istream&    readToDelim(istream&, char delim='\n');    // Read to EOF or delimitor.
  282.   istream&    readToken(istream&);            // Read separated by white space.
  283.   void        resize(unsigned m);             // Truncate or add blanks as necessary.
  284.   void        restoreFrom(RWvistream&);        // Restore from ASCII store
  285.   void        restoreFrom(RWFile&);            // Restore string
  286.   void        saveOn(RWvostream&) const;        // Store ASCII
  287.   void        saveOn(RWFile&) const;            // Store string
  288.   RWCSubString    strip(stripType s = trailing, char c=' ');
  289.   void        toLower();                // Change self to lower-case
  290.   void        toUpper();                // Change self to upper-case
  291.  
  292.   // Friend functions:
  293.   friend RWCString rwexport    operator+(const RWCString&, const char*);
  294. };
  295.  
  296. // Related global functions:
  297. istream&  rwexport operator>>(istream&, RWCString&);
  298. ostream&  rwexport operator<<(ostream& os, const RWCString& s);
  299. RWCString rwexport toLower(const RWCString&); // Return lower-case version of argument.
  300. RWCString rwexport toUpper(const RWCString&); // Return upper-case version of argument.
  301. RWCString rwexport operator+(const char* c, const RWCString& s);
  302. RWCString rwexport operator+(const RWCString& a, const RWCString& s);
  303. inline    unsigned rwhash(const RWCString& s) { return s.hash(); }
  304. inline    unsigned rwhash(const RWCString* s) { return s->hash(); }
  305.  
  306. /************************** RWCString inlines ****************************/
  307.  
  308. #ifdef CONST_OVERLOADS
  309. inline char
  310. RWCString::operator[](int i) const
  311. {assertElement(i); return p->array[i];}
  312.  
  313. inline char
  314. RWCString::operator()(int i) const
  315. #ifdef RWBOUNDS_CHECK    
  316.   assertElement(i); 
  317. #endif
  318.   return p->array[i];
  319. }
  320. #endif
  321.  
  322. inline void
  323. RWCString::cow()  {  if(p->references() > 1)  clone();  }
  324.  
  325. /************************ RWCSubString inlines ****************************/
  326.  
  327. // Access to elements of sub-string with bounds checking
  328.  
  329. #ifdef CONST_OVERLOADS
  330. inline char
  331. RWCSubString::operator[](int i) const
  332. {assertElement(i); return S->p->array[begin+i];}
  333.  
  334. inline char
  335. RWCSubString::operator()(int i) const
  336. #ifdef RWBOUNDS_CHECK    
  337.    assertElement(i);
  338. #endif
  339.    return S->p->array[begin+i];
  340. }
  341. #endif
  342.  
  343. inline RWBoolean
  344. RWCSubString::operator==(const RWCString& str) const
  345. {return operator==(str.data());}
  346.  
  347. inline RWBoolean
  348. RWCSubString::operator!=(const RWCString& str) const
  349. {return !operator==(str.data());}
  350.  
  351. pragma pop_align_members();
  352. #endif /* __RWCSTRING_H__ */
  353.