home *** CD-ROM | disk | FTP | other *** search
- #ifndef __RWCSTRING_H__
- #define __RWCSTRING_H__
- pragma push_align_members(64);
-
- /*
- * Declarations for the RWCString class
- *
- * $Header: E:/vcs/rw/cstring.h_v 1.4 17 Mar 1992 19:21:08 KEFFER $
- *
- ****************************************************************************
- *
- * Rogue Wave Software, Inc.
- * P.O. Box 2328
- * Corvallis, OR 97339
- * Voice: (503) 754-3010 FAX: (503) 757-6650
- *
- * Copyright (C) 1989, 1990, 1991, 1992.
- * This software is subject to copyright protection under the laws of
- * the United States and other countries.
- *
- ***************************************************************************
- *
- * This class is extremely similar to the old RWString class. The only
- * difference is that its copy constructor and assignment operator uses
- * copy semantics instead of reference semantics.
- *
- * It accomplishes this through a technique called "copy-on-write".
- * Multiple instances of a string can refer to the same piece of data
- * so long as it is in a "readonly" situation. If a string writes to
- * the data, then a copy is automatically made if more than one string
- * is referring to it.
- *
- ***************************************************************************
- *
- * $Log: E:/vcs/rw/cstring.h_v $
- *
- * Rev 1.4 17 Mar 1992 19:21:08 KEFFER
- * Changed BOUNDS_CHECK to RWBOUNDS_CHECK
- *
- * Rev 1.3 17 Mar 1992 11:55:30 KEFFER
- *
- * Rev 1.2 17 Mar 1992 11:36:48 KEFFER
- * RWStringRef now inherits from RWReference.
- *
- * Rev 1.1 07 Mar 1992 12:33:06 KEFFER
- * Fine tuned copy-on-write.
- *
- */
-
- #include "rw/tooldefs.h"
- #include "rw/ref.h"
- #include "rw/procinit.h" /* Uses instance mgr. */
- STARTWRAP
- #include <string.h>
- #include <ctype.h>
- #include <stddef.h>
- ENDWRAP
-
- class RWExport RWCString;
- class RWExport RWRegexp;
- class RWExport RWCSubString;
-
- /****************************************
- * *
- * RWStringRef *
- * *
- ****************************************/
-
- /*
- * This is the dynamically allocated part of a RWCString.
- * It maintains a reference count.
- * There are no public member functions.
- */
- class RWExport RWStringRef : public RWReference {
- friend class RWExport RWCString;
- friend class RWExport RWCSubString;
- char* array; // Pointer to the data
- unsigned nchars; // String length (excluding terminating null)
- unsigned capacity; // String capacity
-
- // All constructors are private:
- RWStringRef();
- RWStringRef(unsigned N);
- RWStringRef(unsigned N, char c);
- RWStringRef(const char*);
- RWStringRef(const char* a, unsigned N);
- RWStringRef(const RWCString& s, const char* a);
- ~RWStringRef();
-
- void checkFreeboard();
- void growTo(unsigned N);
- void readToDelim(istream&, char delim);
- void readToken(istream&);
- void restoreFrom(RWvistream&);
- void restoreFrom(RWFile&);
- static unsigned roundCapacity(unsigned);
- void splice(unsigned start, unsigned extent, const char* dat, unsigned N);
- };
-
-
- /****************************************
- * *
- * RWCSubString *
- * *
- ****************************************/
-
- /*
- * The RWCSubString class allows selected elements to be addressed.
- * There are no public constructors.
- */
-
- class RWExport RWCSubString : public RWMemoryPool {
- private:
- friend class RWExport RWCString;
- RWCString* S; // Pointer to the RWCString
- int begin; // Index of starting character
- unsigned extent; // Length of RWCSubString
- private:
- RWCSubString(const RWCString* s, int start, unsigned len); // Constructor is private
- protected:
- void subStringError(unsigned, int, unsigned) const;
- void assertElement(int i) const; // Verifies i is valid index
- public:
- RWCSubString(const RWCSubString& SP)
- {S=SP.S;begin=SP.begin;extent=SP.extent;}
-
- RWCSubString& operator=(const char*); // Assignment to char*
- RWCSubString& operator=(const RWCString&); // Assignment to RWCString
- RWBoolean operator==(const char* s) const;// Test for equality.
- RWBoolean operator==(const RWCString& str) const;
- RWBoolean operator!=(const char* s) const {return !operator==(s);}
- RWBoolean operator!=(const RWCString& str) const;
- char& operator()(int i); // Index with optional bounds checking
- char& operator[](int i); // Index with bounds checking
- #ifdef CONST_OVERLOADS
- char operator()(int i) const; // Index with optional bounds checking
- char operator[](int i) const; // Index with bounds checking
- #endif
- unsigned length() const {return extent;}
- int start() const {return begin;}
- void toLower(); // Convert self to lower-case
- void toUpper(); // Convert self to upper-case
-
- // For detecting null substrings:
- RWBoolean isNull() const {return begin<0;}
- int operator!() const {return begin<0;}
- // operator const char*() const; // Returns start of substring
- };
-
-
- /****************************************
- * *
- * RWCString *
- * *
- ****************************************/
-
- class RWExport RWCString {
- RWStringRef *p;
- #ifndef RW_MULTI_THREAD
- /* If not compiling for an MT situation, then use static data--- */
- static RWBoolean caseSensitive; // For pattern matching.
- static RWBoolean paranoidCheck; // If matching hash isn't good enough.
- static RWBoolean skipWhite; // True to skip whitespace after token read.
- static unsigned initialCapac; // Initial allocation capacity
- static unsigned resizeInc; // Resizing increment
- static unsigned freeboard; // Max empty space before reclaim
- #endif
- private:
- friend class RWExport RWCSubString;
- friend class RWExport RWStringRef;
- void clone(); /* used during copy on write */
- int findCaseIndex(const char*, int, unsigned& patl) const; // Case sensitive, used internally
- int findIndex(const char*, int, unsigned& patl) const; // Switchable sensitivity
- unsigned hashCase() const; // Case sensitive hash, used internally
- protected:
- void assertElement(int) const; // Index in range
- RWCString(const RWCString&, const char*);
- void cow(); // Do copy on write as needed
- public:
- enum stripType {leading, trailing, both};
-
- RWCString(); // Construct null string;
- RWCString(const char *); // Conversion from char*
- RWCString(const char *, unsigned N); // Construct from at most N characters.
- RWCString(unsigned N, char c = ' '); // N characters (default blank).
- RWCString(const RWCString&); // Copy constructor.
- RWCString(const RWCSubString&); // Conversion from sub-string.
- ~RWCString(); // Destructor.
-
- // Type conversion:
- #ifndef ZTC_TYPE_CONVERSION_BUG
- operator const char*() const {return p->array;}
- #endif
-
- // Assignment:
- RWCString& operator=(const RWCString&); // Replace string
- RWCString& operator+=(const char*); // Append string.
- RWCString& operator+=(const RWCString& s) {return operator+=(s.data());}
-
- // Logical operators:
- RWBoolean operator==(const char* s) const;
- RWBoolean operator!=(const char* s) const {return !operator==(s);}
- RWBoolean operator< (const char* s) const;
- RWBoolean operator> (const char* s) const;
- RWBoolean operator<=(const char* s) const {return !operator>(s);}
- RWBoolean operator>=(const char* s) const {return !operator<(s);}
-
- // Too many compilers have problems to rely on type conversion:
- RWBoolean operator==(const RWCString& s) const {return operator==(s.data());}
- RWBoolean operator!=(const RWCString& s) const {return !operator==(s.data());}
- RWBoolean operator< (const RWCString& s) const {return operator< (s.data());}
- RWBoolean operator> (const RWCString& s) const {return operator> (s.data());}
- RWBoolean operator<=(const RWCString& s) const {return !operator> (s.data());}
- RWBoolean operator>=(const RWCString& s) const {return !operator< (s.data());}
-
- // Indexing operators:
- char& operator[](int); // Indexing with bounds checking
- char& operator()(int); // Indexing with optional bounds checking
- RWCSubString operator()(int start, unsigned len); // Sub-string operator
- RWCSubString operator()(const RWRegexp& re); // Substring matching the RE
- RWCSubString operator()(const RWRegexp& re, int start); // Substring matching the RE
- RWCSubString subString(const char* pat, int start=0); // Substring matching pat; must be m.f. else type conversion ambiguity
- #ifdef CONST_OVERLOADS
- char operator[](int) const;
- char operator()(int) const;
- const RWCSubString operator()(int start, unsigned len) const;
- const RWCSubString operator()(const RWRegexp& pat) const; // Substring matching RE
- const RWCSubString operator()(const RWRegexp& pat, int start) const; // Substring matching RE
- const RWCSubString subString(const char* pat, int start=0) const; // Substring matching pat
- #endif
-
- // Static member functions:
- static RWBoolean setCaseSensitive(RWBoolean tf = TRUE); // For pattern matching.
- static RWBoolean setParanoidCheck(RWBoolean ck = TRUE); // If matching hash isn't good enough.
- static RWBoolean skipWhitespace(RWBoolean sk = TRUE); // True to skip whitespace after token read.
- static unsigned initialCapacity(unsigned ic = 63); // Initial allocation capacity
- static unsigned resizeIncrement(unsigned ri = 64); // Resizing increment
- static unsigned maxWaste(unsigned mw = 63); // Max empty space before reclaim
- #ifdef RW_MULTI_THREAD
- // Just declarations --- static data must be retrieved from the instance manager.
- static RWBoolean getCaseSensitiveFlag();
- static RWBoolean getParanoidCheckFlag();
- static RWBoolean getSkipWhitespaceFlag();
- static unsigned getInitialCapacity();
- static unsigned getResizeIncrement();
- static unsigned getMaxWaste();
- #else
- static RWBoolean getCaseSensitiveFlag() {return caseSensitive;}
- static RWBoolean getParanoidCheckFlag() {return paranoidCheck;}
- static RWBoolean getSkipWhitespaceFlag() {return skipWhite;}
- static unsigned getInitialCapacity() {return initialCapac;}
- static unsigned getResizeIncrement() {return resizeInc;}
- static unsigned getMaxWaste() {return freeboard;}
- #endif
-
- // Non-static member functions:
- RWCString& append(const char* str, unsigned N); // append N character of str
- unsigned binaryStoreSize() const {return length()+sizeof(unsigned);}
- unsigned capacity() const {return p->capacity;}
- int compareTo(const RWCString&) const; // Compare strings lexicographically.
- RWBoolean contains(const char* pattern) const;
- RWBoolean contains(const RWCString& s) const {return contains(s.data());}
- RWCString copy() const; // Distinct copy of self.
- const char* data() const {return p->array;} // Access to start of string.
- int first(char c) const; // First occurrence of c
- int first(const char* cs) const; // First occurrence of any char in cs
- unsigned hash() const; // Return hashing value.
- int index(const char* pat, int i=0) const; // Search for string.
- int index(const RWCString& s, int i=0) const {return index(s.data(), i);}
- int index(const RWRegexp& pat, int i=0) const; // Search for Regular Expression
- int index(const RWRegexp& pat, int* ext, int i=0) const;
- RWBoolean isNull() const {return *p->array==0;} // Is this the null string?
- int last(char c) const; // Last occurrence of char c
- unsigned length() const { return p->nchars; } // Excluding terminating null character.
- RWCString& prepend(const char*); // Prepend a character string
- RWCString& prepend(const char* str, unsigned N); // prepend N chars of str
- RWCString& prepend(const RWCString& s) {return prepend(s.data());}
- istream& readFile(istream&); // Read to EOF or null character.
- istream& readLine(istream&); // Read to EOF or newline.
- istream& readString(istream&); // Read to EOF or null character.
- istream& readToDelim(istream&, char delim='\n'); // Read to EOF or delimitor.
- istream& readToken(istream&); // Read separated by white space.
- void resize(unsigned m); // Truncate or add blanks as necessary.
- void restoreFrom(RWvistream&); // Restore from ASCII store
- void restoreFrom(RWFile&); // Restore string
- void saveOn(RWvostream&) const; // Store ASCII
- void saveOn(RWFile&) const; // Store string
- RWCSubString strip(stripType s = trailing, char c=' ');
- void toLower(); // Change self to lower-case
- void toUpper(); // Change self to upper-case
-
- // Friend functions:
- friend RWCString rwexport operator+(const RWCString&, const char*);
- };
-
- // Related global functions:
- istream& rwexport operator>>(istream&, RWCString&);
- ostream& rwexport operator<<(ostream& os, const RWCString& s);
- RWCString rwexport toLower(const RWCString&); // Return lower-case version of argument.
- RWCString rwexport toUpper(const RWCString&); // Return upper-case version of argument.
- RWCString rwexport operator+(const char* c, const RWCString& s);
- RWCString rwexport operator+(const RWCString& a, const RWCString& s);
- inline unsigned rwhash(const RWCString& s) { return s.hash(); }
- inline unsigned rwhash(const RWCString* s) { return s->hash(); }
-
- /************************** RWCString inlines ****************************/
-
- #ifdef CONST_OVERLOADS
- inline char
- RWCString::operator[](int i) const
- {assertElement(i); return p->array[i];}
-
- inline char
- RWCString::operator()(int i) const
- {
- #ifdef RWBOUNDS_CHECK
- assertElement(i);
- #endif
- return p->array[i];
- }
- #endif
-
- inline void
- RWCString::cow() { if(p->references() > 1) clone(); }
-
- /************************ RWCSubString inlines ****************************/
-
- // Access to elements of sub-string with bounds checking
-
- #ifdef CONST_OVERLOADS
- inline char
- RWCSubString::operator[](int i) const
- {assertElement(i); return S->p->array[begin+i];}
-
- inline char
- RWCSubString::operator()(int i) const
- {
- #ifdef RWBOUNDS_CHECK
- assertElement(i);
- #endif
- return S->p->array[begin+i];
- }
- #endif
-
- inline RWBoolean
- RWCSubString::operator==(const RWCString& str) const
- {return operator==(str.data());}
-
- inline RWBoolean
- RWCSubString::operator!=(const RWCString& str) const
- {return !operator==(str.data());}
-
- pragma pop_align_members();
- #endif /* __RWCSTRING_H__ */
-