wvstring.h

00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Implementation of a simple and efficient printable-string class.
00006  * 
00007  * It leaves out many of the notational conveniences provided by other
00008  * string classes, because they waste too much CPU time and space.
00009  * It does the one thing really missing from char* strings, that is,
00010  * dynamic buffer management.
00011  * 
00012  * The 'str' member is the actual (char*) string.  You should never
00013  * need to access it directly.
00014  */
00015 #ifndef __WVSTRING_H
00016 #define __WVSTRING_H
00017 
00018 #include <string.h>
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string> // no code is actually used from here
00022 
00023 
00024 /* 1 byte for terminating NUL */
00025 #define WVSTRING_EXTRA 1
00026 
00027 
00028 #define __WVS_F(n) WvStringParm __wvs_##n
00029 #define __WVS_FORM(n) WvStringParm __wvs_##n = WvFastString::null
00030 #define WVSTRING_FORMAT_DECL WvStringParm __wvs_format, \
00031                 WvStringParm __wvs_a0, \
00032                 __WVS_FORM( a1), __WVS_FORM( a2), __WVS_FORM( a3), \
00033                 __WVS_FORM( a4), __WVS_FORM( a5), __WVS_FORM( a6), \
00034                 __WVS_FORM( a7), __WVS_FORM( a8), __WVS_FORM( a9), \
00035                 __WVS_FORM(a10), __WVS_FORM(a11), __WVS_FORM(a12), \
00036                 __WVS_FORM(a13), __WVS_FORM(a14), __WVS_FORM(a15), \
00037                 __WVS_FORM(a16), __WVS_FORM(a17), __WVS_FORM(a18), \
00038                 __WVS_FORM(a19)
00039 #define WVSTRING_FORMAT_DEFN WvStringParm __wvs_format, \
00040                 WvStringParm __wvs_a0, \
00041                 __WVS_F( a1), __WVS_F( a2), __WVS_F( a3), \
00042                 __WVS_F( a4), __WVS_F( a5), __WVS_F( a6), \
00043                 __WVS_F( a7), __WVS_F( a8), __WVS_F( a9), \
00044                 __WVS_F(a10), __WVS_F(a11), __WVS_F(a12), \
00045                 __WVS_F(a13), __WVS_F(a14), __WVS_F(a15), \
00046                 __WVS_F(a16), __WVS_F(a17), __WVS_F(a18), \
00047                 __WVS_F(a19)
00048 #define WVSTRING_FORMAT_CALL __wvs_format, __wvs_a0, \
00049                 __wvs_a1, __wvs_a2, __wvs_a3, __wvs_a4, __wvs_a5, \
00050                 __wvs_a6, __wvs_a7, __wvs_a8, __wvs_a9, __wvs_a10, \
00051                 __wvs_a11, __wvs_a12, __wvs_a13, __wvs_a14, __wvs_a15, \
00052                 __wvs_a16, __wvs_a17, __wvs_a18, __wvs_a19
00053 
00054 struct WvStringBuf;
00055 class WvFastString;
00056 class WvString;
00057 class QString; // for operator QString()
00058 class QCString;
00059 
00060 // all WvFastString objects are const - they should _only_ be created
00061 // automatically by automatic typecasting in parameter passing.  So let's
00062 // create a handy alias.
00063 typedef const WvFastString &   WvStringParm;
00064 
00065 
00066 
00067 struct WvStringBuf
00068 {
00069     size_t size;        // string length - if zero, use strlen!!
00070     unsigned links;     // number of WvStrings using this buf.
00071     char data[1];       // optional room for extra string data
00072 };
00073 
00074 
00075 // the _actual_ space taken by a WvStringBuf, without the data[] array
00076 // (which is variable-sized, not really 1 byte)
00077 #define WVSTRINGBUF_SIZE(s) (s->data - (char *)s)
00078 
00093 class WvFastString
00094 {
00095     friend class WvString; // so WvString can access members of _other_ objects
00096     
00097 protected:
00098     WvStringBuf *buf;
00099     char *str;
00100     
00101     // WvStringBuf used for char* strings that have not been cloned.
00102     static WvStringBuf nullbuf;
00103     
00104 public:
00105     // a null string, converted to char* as "(nil)"
00106     static const WvFastString null;
00107 
00114     WvFastString();
00115     void setsize(size_t i);
00116     
00123     WvFastString(const WvFastString &s);
00124     WvFastString(const WvString &s);
00125     
00132     WvFastString(const char *_str);
00133     
00138     WvFastString(const QString &s);
00139     WvFastString(const QCString &s);
00140     
00145     inline WvFastString(const std::string &s);
00146 
00151     WvFastString(short i);
00152     WvFastString(unsigned short i);
00153     WvFastString(int i);
00154     WvFastString(unsigned int i);
00155     WvFastString(long i);
00156     WvFastString(unsigned long i);
00157     WvFastString(long long i);
00158     WvFastString(unsigned long long i);
00159     WvFastString(double i);
00160     
00162     static void do_format(WvFastString &output, const char *format,
00163                           const WvFastString * const *a);
00164     
00165     
00182     WvFastString(WVSTRING_FORMAT_DECL) 
00183     {
00184         const WvFastString *x[20];
00185         
00186         if (&__wvs_a0  != &null) x[ 0] = &__wvs_a0;
00187         if (&__wvs_a1  != &null) x[ 1] = &__wvs_a1;
00188         if (&__wvs_a2  != &null) x[ 2] = &__wvs_a2;
00189         if (&__wvs_a3  != &null) x[ 3] = &__wvs_a3;
00190         if (&__wvs_a4  != &null) x[ 4] = &__wvs_a4;
00191         if (&__wvs_a5  != &null) x[ 5] = &__wvs_a5;
00192         if (&__wvs_a6  != &null) x[ 6] = &__wvs_a6;
00193         if (&__wvs_a7  != &null) x[ 7] = &__wvs_a7;
00194         if (&__wvs_a8  != &null) x[ 8] = &__wvs_a8;
00195         if (&__wvs_a9  != &null) x[ 9] = &__wvs_a9;
00196         if (&__wvs_a10 != &null) x[10] = &__wvs_a10;
00197         if (&__wvs_a11 != &null) x[11] = &__wvs_a11;
00198         if (&__wvs_a12 != &null) x[12] = &__wvs_a12;
00199         if (&__wvs_a13 != &null) x[13] = &__wvs_a13;
00200         if (&__wvs_a14 != &null) x[14] = &__wvs_a14;
00201         if (&__wvs_a15 != &null) x[15] = &__wvs_a15;
00202         if (&__wvs_a16 != &null) x[16] = &__wvs_a16;
00203         if (&__wvs_a17 != &null) x[17] = &__wvs_a17;
00204         if (&__wvs_a18 != &null) x[18] = &__wvs_a18;
00205         if (&__wvs_a19 != &null) x[19] = &__wvs_a19;
00206         
00207         link(&nullbuf, NULL);
00208         do_format(*this, __wvs_format.str, x);
00209     }
00210     
00211     ~WvFastString();
00212     
00213     /*
00214      * Figure out the length of this string.  ==0 if NULL or empty.
00215      */
00216     size_t len() const;
00217 
00218 protected:
00219     void construct(const char *_str);
00220 
00221     // this doesn't exist - it's just here to keep it from being auto-created
00222     // by stupid C++.
00223     WvFastString &operator= (const WvFastString &s2);
00224     
00225     // connect/disconnect ourselves from a WvStringBuf.
00226     void link(WvStringBuf *_buf, const char *_str);
00227     void unlink();
00228     
00229     // allocate new space for buffers - needed only by the (int i) constructor,
00230     // for now.
00231     WvStringBuf *alloc(size_t size);
00232     void newbuf(size_t size);
00233     
00234 public:
00235     // string comparison
00236     bool operator== (WvStringParm s2) const;
00237     bool operator!= (WvStringParm s2) const;
00238     bool operator< (WvStringParm s2) const;
00239     bool operator== (const char *s2) const;
00240     bool operator!= (const char *s2) const;
00241     bool operator< (const char *s2) const;
00242     
00244     bool operator! () const;
00245 
00246     // pointer arithmetic
00247     const char *operator+ (int i) const
00248         { return str + i; }
00249     const char *operator- (int i) const
00250         { return str - i; }
00251     
00253     operator const char*() const
00254         { return str; }
00255     
00261     const char *cstr() const
00262         { return str; }
00263     
00268     operator QString() const;
00269     
00274     //inline operator std::string() const;
00275     
00280     int num() const
00281         { return str ? atoi(str) : 0; }
00282     
00284     bool isnull() const
00285         { return str == NULL; }
00286     
00288     const WvFastString &ifnull(WvStringParm defval) const
00289         { return isnull() ? defval : *this; }
00290 };
00291 
00292 
00323 class WvString : public WvFastString
00324 {
00325 public:
00326     // an empty string, converted to char* as ""
00327     static const WvString empty;
00328  
00329     WvString() {} // nothing special needed
00330     WvString(short i) : WvFastString(i) { } // nothing special
00331     WvString(unsigned short i) : WvFastString(i) { } // nothing special
00332     WvString(int i) : WvFastString(i) { } // nothing special
00333     WvString(unsigned int i) : WvFastString(i) { } // nothing special
00334     WvString(long i) : WvFastString(i) { } // nothing special
00335     WvString(unsigned long i) : WvFastString(i) { } // nothing special
00336     WvString(long long i) : WvFastString(i) { } // nothing special
00337     WvString(unsigned long long i) : WvFastString(i) { } // nothing special
00338     WvString(double i) : WvFastString(i) { } // nothing special
00339     
00346     WvString(const WvString &s)
00347         { copy_constructor(s); }
00348     WvString(const WvFastString &s)
00349         { copy_constructor(s); }
00350     
00357     WvString(const char *_str);
00358 
00363     WvString(const QString &);
00364     WvString(const QCString &);
00365 
00370     inline WvString(const std::string &s);
00371 
00372     WvString(WVSTRING_FORMAT_DECL) : WvFastString(WVSTRING_FORMAT_CALL)
00373         { }
00374     
00375     WvString &append(WvStringParm s);
00376     WvString &append(WVSTRING_FORMAT_DECL)
00377         { return append(WvString(WVSTRING_FORMAT_CALL)); }
00378     
00379     WvString &operator= (int i);
00380     WvString &operator= (const WvFastString &s2);
00381     WvString &operator= (const char *s2)
00382         { return *this = WvFastString(s2); }
00383     
00385     WvString &unique();
00386     
00388     bool is_unique() const;
00389 
00391     char *edit()
00392         { return unique().str; }
00393     
00394 protected:
00395     void copy_constructor(const WvFastString &s);
00396     inline void construct(const char *_str)
00397         {
00398             link(&nullbuf, _str);
00399     
00400             // apenwarr (2002/04/24): from now on, all WvString objects are created
00401             // with unique(), so you should _never_ have to call it explicitly.  We
00402             // still can (and should!) use fast parameter passing via WvFastString.
00403             unique();
00404         }
00405 };
00406 
00407 
00414 class WvStringStar : public WvFastString
00415 {
00416 public:
00417     WvStringStar(WvStringParm s) : WvFastString(s)
00418         { }
00419     WvFastString *operator -> ()
00420         { return this; }
00421 };
00422 
00423 
00424 inline bool operator== (const char *s1, WvStringParm s2)
00425 {
00426     return s2 == s1;
00427 }
00428 
00429 
00430 inline bool operator!= (const char *s1, WvStringParm s2)
00431 {
00432     return s2 != s1;
00433 }
00434 
00435 #endif // __WVSTRING_H

Generated on Mon Feb 5 10:54:30 2007 for WvStreams by  doxygen 1.5.1