WvStreams
|
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 00121 WvFastString offset(size_t i) const; 00122 00129 WvFastString(const WvFastString &s); 00130 WvFastString(const WvString &s); 00131 00138 WvFastString(const char *_str); 00139 00144 WvFastString(const QString &s); 00145 WvFastString(const QCString &s); 00146 00151 inline WvFastString(const std::string &s); 00152 00157 WvFastString(short i); 00158 WvFastString(unsigned short i); 00159 WvFastString(int i); 00160 WvFastString(unsigned int i); 00161 WvFastString(long i); 00162 WvFastString(unsigned long i); 00163 WvFastString(long long i); 00164 WvFastString(unsigned long long i); 00165 WvFastString(double i); 00166 00168 static void do_format(WvFastString &output, const char *format, 00169 const WvFastString * const *a); 00170 00171 00188 WvFastString(WVSTRING_FORMAT_DECL) 00189 { 00190 const WvFastString *x[20]; 00191 00192 x[ 0] = (&__wvs_a0 != &null)? &__wvs_a0 : 0; 00193 x[ 1] = (&__wvs_a1 != &null)? &__wvs_a1 : 0; 00194 x[ 2] = (&__wvs_a2 != &null)? &__wvs_a2 : 0; 00195 x[ 3] = (&__wvs_a3 != &null)? &__wvs_a3 : 0; 00196 x[ 4] = (&__wvs_a4 != &null)? &__wvs_a4 : 0; 00197 x[ 5] = (&__wvs_a5 != &null)? &__wvs_a5 : 0; 00198 x[ 6] = (&__wvs_a6 != &null)? &__wvs_a6 : 0; 00199 x[ 7] = (&__wvs_a7 != &null)? &__wvs_a7 : 0; 00200 x[ 8] = (&__wvs_a8 != &null)? &__wvs_a8 : 0; 00201 x[ 9] = (&__wvs_a9 != &null)? &__wvs_a9 : 0; 00202 x[10] = (&__wvs_a10 != &null)? &__wvs_a10 : 0; 00203 x[11] = (&__wvs_a11 != &null)? &__wvs_a11 : 0; 00204 x[12] = (&__wvs_a12 != &null)? &__wvs_a12 : 0; 00205 x[13] = (&__wvs_a13 != &null)? &__wvs_a13 : 0; 00206 x[14] = (&__wvs_a14 != &null)? &__wvs_a14 : 0; 00207 x[15] = (&__wvs_a15 != &null)? &__wvs_a15 : 0; 00208 x[16] = (&__wvs_a16 != &null)? &__wvs_a16 : 0; 00209 x[17] = (&__wvs_a17 != &null)? &__wvs_a17 : 0; 00210 x[18] = (&__wvs_a18 != &null)? &__wvs_a18 : 0; 00211 x[19] = (&__wvs_a19 != &null)? &__wvs_a19 : 0; 00212 00213 link(&nullbuf, NULL); 00214 do_format(*this, __wvs_format.str, x); 00215 } 00216 00217 ~WvFastString(); 00218 00219 /* 00220 * Figure out the length of this string. ==0 if NULL or empty. 00221 */ 00222 size_t len() const; 00223 00224 protected: 00225 void construct(const char *_str); 00226 00227 // this doesn't exist - it's just here to keep it from being auto-created 00228 // by stupid C++. 00229 WvFastString &operator= (const WvFastString &s2); 00230 00231 // connect/disconnect ourselves from a WvStringBuf. 00232 void link(WvStringBuf *_buf, const char *_str); 00233 void unlink(); 00234 00235 // allocate new space for buffers - needed only by the (int i) constructor, 00236 // for now. 00237 WvStringBuf *alloc(size_t size); 00238 void newbuf(size_t size); 00239 00240 public: 00241 // string comparison 00242 bool operator== (WvStringParm s2) const; 00243 bool operator!= (WvStringParm s2) const; 00244 bool operator< (WvStringParm s2) const; 00245 bool operator== (const char *s2) const; 00246 bool operator!= (const char *s2) const; 00247 bool operator< (const char *s2) const; 00248 00250 bool operator! () const; 00251 00252 // pointer arithmetic 00253 const char *operator+ (int i) const 00254 { return str + i; } 00255 const char *operator- (int i) const 00256 { return str - i; } 00257 00259 operator const char*() const 00260 { return str; } 00261 00267 const char *cstr() const 00268 { return str; } 00269 00274 operator QString() const; 00275 00280 //inline operator std::string() const; 00281 00286 int num() const 00287 { return str ? atoi(str) : 0; } 00288 00290 bool isnull() const 00291 { return str == NULL; } 00292 00294 const WvFastString &ifnull(WvStringParm defval) const 00295 { return isnull() ? defval : *this; } 00296 }; 00297 00298 00329 class WvString : public WvFastString 00330 { 00331 public: 00332 // an empty string, converted to char* as "" 00333 static const WvString empty; 00334 00335 WvString() {} // nothing special needed 00336 WvString(short i) : WvFastString(i) { } // nothing special 00337 WvString(unsigned short i) : WvFastString(i) { } // nothing special 00338 WvString(int i) : WvFastString(i) { } // nothing special 00339 WvString(unsigned int i) : WvFastString(i) { } // nothing special 00340 WvString(long i) : WvFastString(i) { } // nothing special 00341 WvString(unsigned long i) : WvFastString(i) { } // nothing special 00342 WvString(long long i) : WvFastString(i) { } // nothing special 00343 WvString(unsigned long long i) : WvFastString(i) { } // nothing special 00344 WvString(double i) : WvFastString(i) { } // nothing special 00345 00352 WvString(const WvString &s) 00353 { copy_constructor(s); } 00354 WvString(const WvFastString &s) 00355 { copy_constructor(s); } 00356 00363 WvString(const char *_str); 00364 00369 WvString(const QString &); 00370 WvString(const QCString &); 00371 00376 inline WvString(const std::string &s); 00377 00378 WvString(WVSTRING_FORMAT_DECL) : WvFastString(WVSTRING_FORMAT_CALL) 00379 { } 00380 00381 WvString &append(WvStringParm s); 00382 WvString &append(WVSTRING_FORMAT_DECL) 00383 { return append(WvString(WVSTRING_FORMAT_CALL)); } 00384 00385 WvString &operator= (int i); 00386 WvString &operator= (const WvFastString &s2); 00387 WvString &operator= (const char *s2) 00388 { return *this = WvFastString(s2); } 00389 00391 WvString &unique(); 00392 00394 bool is_unique() const; 00395 00397 char *edit() 00398 { return unique().str; } 00399 00400 protected: 00401 void copy_constructor(const WvFastString &s); 00402 inline void construct(const char *_str) 00403 { 00404 link(&nullbuf, _str); 00405 00406 // apenwarr (2002/04/24): from now on, all WvString objects are created 00407 // with unique(), so you should _never_ have to call it explicitly. We 00408 // still can (and should!) use fast parameter passing via WvFastString. 00409 unique(); 00410 } 00411 }; 00412 00413 00420 class WvStringStar : public WvFastString 00421 { 00422 public: 00423 WvStringStar(WvStringParm s) : WvFastString(s) 00424 { } 00425 WvFastString *operator -> () 00426 { return this; } 00427 }; 00428 00429 00430 inline bool operator== (const char *s1, WvStringParm s2) 00431 { 00432 return s2 == s1; 00433 } 00434 00435 00436 inline bool operator!= (const char *s1, WvStringParm s2) 00437 { 00438 return s2 != s1; 00439 } 00440 00441 #endif // __WVSTRING_H