Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvstring.h

Go to the documentation of this file.
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 00022 00023 /* 00024 * 1 byte for terminating NUL, 4 more to kludge around libc5+efence 00025 * incompatibility with strcat(). 00026 */ 00027 #define WVSTRING_EXTRA 5 00028 00029 00030 #define __WVS_FORM(n) WvStringParm __wvs_##n = WvFastString::null 00031 #define WVSTRING_FORMAT_DECL WvStringParm __wvs_format, \ 00032 WvStringParm __wvs_a0, \ 00033 __WVS_FORM( a1), __WVS_FORM( a2), __WVS_FORM( a3), \ 00034 __WVS_FORM( a4), __WVS_FORM( a5), __WVS_FORM( a6), \ 00035 __WVS_FORM( a7), __WVS_FORM( a8), __WVS_FORM( a9), \ 00036 __WVS_FORM(a10), __WVS_FORM(a11), __WVS_FORM(a12), \ 00037 __WVS_FORM(a13), __WVS_FORM(a14), __WVS_FORM(a15), \ 00038 __WVS_FORM(a16), __WVS_FORM(a17), __WVS_FORM(a18), \ 00039 __WVS_FORM(a19) 00040 #define WVSTRING_FORMAT_CALL __wvs_format, __wvs_a0, \ 00041 __wvs_a1, __wvs_a2, __wvs_a3, __wvs_a4, __wvs_a5, \ 00042 __wvs_a6, __wvs_a7, __wvs_a8, __wvs_a9, __wvs_a10, \ 00043 __wvs_a11, __wvs_a12, __wvs_a13, __wvs_a14, __wvs_a15, \ 00044 __wvs_a16, __wvs_a17, __wvs_a18, __wvs_a19 00045 00046 struct WvStringBuf; 00047 class WvFastString; 00048 class WvString; 00049 class QString; // for operator QString() 00050 class QCString; 00051 00052 // all WvFastString objects are const - they should _only_ be created 00053 // automatically by automatic typecasting in parameter passing. So let's 00054 // create a handy alias. 00055 typedef const WvFastString & WvStringParm; 00056 00057 00058 00059 struct WvStringBuf 00060 { 00061 size_t size; // string length - if zero, use strlen!! 00062 unsigned links; // number of WvStrings using this buf. 00063 char data[1]; // optional room for extra string data 00064 }; 00065 00066 00067 // the _actual_ space taken by a WvStringBuf, without the data[] array 00068 // (which is variable-sized, not really 1 byte) 00069 #define WVSTRINGBUF_SIZE(s) (s->data - (char *)s) 00070 00071 /** 00072 * A WvFastString acts exactly like a WvString, but can take (const char *) 00073 * strings without needing to allocate any memory, thus making it faster. 00074 * 00075 * When we copy to a normal WvString object, _then_ we allocate the memory. 00076 * If that never happens, we never need to allocate. 00077 * 00078 * DON'T CREATE INSTANCES OF THIS! It's mostly useful for parameter passing, 00079 * and for that you should use WvStringParm. You can get yourself into _big_ 00080 * trouble if you have an instance of a WvFastString created from a (char *) 00081 * object and then you modify the original (char *). 00082 * 00083 * For almost all purposes, use WvString instead. At worst, it's a bit slower. 00084 */ 00085 class WvFastString 00086 { 00087 friend class WvString; // so WvString can access members of _other_ objects 00088 00089 protected: 00090 WvStringBuf *buf; 00091 char *str; 00092 00093 // WvStringBuf used for char* strings that have not been cloned. 00094 static WvStringBuf nullbuf; 00095 00096 public: 00097 // a null string, converted to char* as "(nil)" 00098 static const WvFastString null; 00099 00100 /** 00101 * Create an empty, NULL string. In the past, these were dangerous 00102 * and could only be filled with operator= or setsize(); nowadays, NULL 00103 * strings are explicitly allowed, since it's useful to express the 00104 * difference between a zero-length string and a NULL result. 00105 */ 00106 WvFastString(); 00107 void setsize(size_t i); 00108 00109 /** 00110 * Copy constructor. We can safely copy from a normal WvString like this 00111 * too, since no special behaviour is required in this direction. (Note 00112 * that copying from a WvFastString to a WvString _does_ require special 00113 * care!) 00114 */ 00115 WvFastString(const WvFastString &s); 00116 WvFastString(const WvString &s); 00117 00118 /** 00119 * Create a string out of a (char *)-style string _without_ copying any 00120 * memory. It's fast, but we have to trust that the _str won't change 00121 * for the lifetime of our WvFastString. That's usually safe, if you 00122 * didn't use WvFastString where you should have used a WvString. 00123 */ 00124 WvFastString(const char *_str); 00125 00126 /** 00127 * Create a string out of a Qt library QString. If you use this, 00128 * you need to link with libwvqt.so. 00129 */ 00130 WvFastString(const QString &s); 00131 WvFastString(const QCString &s); 00132 00133 /** 00134 * NOTE: make sure that 32 bytes is big enough for your longest 00135 * int. This is true up to at least 64 bits. 00136 */ 00137 WvFastString(short i); 00138 WvFastString(unsigned short i); 00139 WvFastString(int i); 00140 WvFastString(unsigned int i); 00141 WvFastString(long i); 00142 WvFastString(unsigned long i); 00143 WvFastString(long long i); 00144 WvFastString(unsigned long long i); 00145 WvFastString(double i); 00146 00147 /** when this is called, we assume output.str == NULL; it will be filled. */ 00148 static void do_format(WvFastString &output, const char *format, 00149 const WvFastString * const *a); 00150 00151 00152 /** 00153 * Now, you're probably thinking to yourself: Boy, does this ever 00154 * look ridiculous. And indeed it does. However, it is 00155 * completely type-safe and when functions are enabled, it 00156 * reduces automatically to its minimum possible implementation. 00157 * (ie. all extra comparisons with wv_null go away if the 00158 * parameter really _is_ wv_null, and that is the default!) 00159 * 00160 * I failed to find a way to optimize out the comparisons for 00161 * parameters that _are_ provided, however. 00162 * 00163 * There is a small problem, which is that only up to 20 (numbers 00164 * 0 to 19) additional arguments are allowed. Luckily, no one has 00165 * ever used that many on one "printf"-type line in the history of 00166 * the world. 00167 */ 00168 WvFastString(WVSTRING_FORMAT_DECL) 00169 { 00170 const WvFastString *x[20]; 00171 00172 if (&__wvs_a0 != &null) x[ 0] = &__wvs_a0; 00173 if (&__wvs_a1 != &null) x[ 1] = &__wvs_a1; 00174 if (&__wvs_a2 != &null) x[ 2] = &__wvs_a2; 00175 if (&__wvs_a3 != &null) x[ 3] = &__wvs_a3; 00176 if (&__wvs_a4 != &null) x[ 4] = &__wvs_a4; 00177 if (&__wvs_a5 != &null) x[ 5] = &__wvs_a5; 00178 if (&__wvs_a6 != &null) x[ 6] = &__wvs_a6; 00179 if (&__wvs_a7 != &null) x[ 7] = &__wvs_a7; 00180 if (&__wvs_a8 != &null) x[ 8] = &__wvs_a8; 00181 if (&__wvs_a9 != &null) x[ 9] = &__wvs_a9; 00182 if (&__wvs_a10 != &null) x[10] = &__wvs_a10; 00183 if (&__wvs_a11 != &null) x[11] = &__wvs_a11; 00184 if (&__wvs_a12 != &null) x[12] = &__wvs_a12; 00185 if (&__wvs_a13 != &null) x[13] = &__wvs_a13; 00186 if (&__wvs_a14 != &null) x[14] = &__wvs_a14; 00187 if (&__wvs_a15 != &null) x[15] = &__wvs_a15; 00188 if (&__wvs_a16 != &null) x[16] = &__wvs_a16; 00189 if (&__wvs_a17 != &null) x[17] = &__wvs_a17; 00190 if (&__wvs_a18 != &null) x[18] = &__wvs_a18; 00191 if (&__wvs_a19 != &null) x[19] = &__wvs_a19; 00192 00193 link(&nullbuf, NULL); 00194 do_format(*this, __wvs_format.str, x); 00195 } 00196 00197 ~WvFastString(); 00198 00199 /* 00200 * Figure out the length of this string. ==0 if NULL or empty. 00201 */ 00202 size_t len() const; 00203 00204 protected: 00205 // this doesn't exist - it's just here to keep it from being auto-created 00206 // by stupid C++. 00207 WvFastString &operator= (const WvFastString &s2); 00208 00209 // connect/disconnect ourselves from a WvStringBuf. 00210 void link(WvStringBuf *_buf, const char *_str); 00211 void unlink(); 00212 00213 // allocate new space for buffers - needed only by the (int i) constructor, 00214 // for now. 00215 WvStringBuf *alloc(size_t size); 00216 void newbuf(size_t size); 00217 00218 public: 00219 // string comparison 00220 bool operator== (WvStringParm s2) const; 00221 bool operator!= (WvStringParm s2) const; 00222 bool operator< (WvStringParm s2) const; 00223 bool operator== (const char *s2) const; 00224 bool operator!= (const char *s2) const; 00225 bool operator< (const char *s2) const; 00226 00227 /** the not operator is 'true' if string is empty */ 00228 bool operator! () const; 00229 00230 // pointer arithmetic 00231 const char *operator+ (int i) const 00232 { return str + i; } 00233 const char *operator- (int i) const 00234 { return str - i; } 00235 00236 /** auto-convert WvString to (const char *), when needed. */ 00237 operator const char*() const 00238 { return str; } 00239 00240 /** 00241 * return a (const char *) for this string. The typecast operator does 00242 * this automatically when needed, but sometimes (especially with varargs 00243 * like in printf()) that isn't convenient enough. 00244 */ 00245 const char *cstr() const 00246 { return str; } 00247 00248 /** 00249 * return a Qt library QString containing the contents of this string. 00250 * You need to link to libwvqt.so if you use this. 00251 */ 00252 operator QString() const; 00253 00254 /** 00255 * used to convert WvString to int, when needed. 00256 * we no longer provide a typecast, because it causes annoyance. 00257 */ 00258 int num() const 00259 { return str ? atoi(str) : 0; } 00260 00261 /** returns true if this string is null */ 00262 bool isnull() const 00263 { return str == NULL; } 00264 }; 00265 00266 00267 /** 00268 * WvString is an implementation of a simple and efficient 00269 * printable-string class. It leaves out many of the notational 00270 * conveniences provided by other string classes, because they waste 00271 * too much CPU time and space. 00272 * 00273 * It does the one thing really missing from char* strings, that is, 00274 * dynamic buffer management. 00275 * 00276 * When you copy one WvString to another, it does _not_ duplicate the 00277 * buffer; it just creates another pointer to it. To really duplicate 00278 * the buffer, call the unique() member function. 00279 * 00280 * To change the contents of a WvString, you need to run its edit() 00281 * member function, which executes unique() and then returns a char* 00282 * pointer to the WvString contents. 00283 * 00284 * The most annoying side-effect of this implementation is that if you 00285 * construct a WvString from a char* buffer or static string, WvString 00286 * won't duplicate it. Usually this is okay and much faster (for 00287 * example, if you just want to print a static string). However, if 00288 * you construct a WvString from a dynamic variable, changing the 00289 * dynamic variable will change the WvString unless you run unique() 00290 * or edit(). Worse still, deleting the dynamic variable will make 00291 * WvString act unpredictably. 00292 * 00293 * But it does cut out extra dynamic memory allocation for the most 00294 * common cases, and it almost always avoids manual 'new' and 'delete' 00295 * of string objects. 00296 */ 00297 class WvString : public WvFastString 00298 { 00299 public: 00300 // an empty string, converted to char* as "" 00301 static const WvString empty; 00302 00303 WvString() {} // nothing special needed 00304 WvString(short i) : WvFastString(i) { } // nothing special 00305 WvString(unsigned short i) : WvFastString(i) { } // nothing special 00306 WvString(int i) : WvFastString(i) { } // nothing special 00307 WvString(unsigned int i) : WvFastString(i) { } // nothing special 00308 WvString(long i) : WvFastString(i) { } // nothing special 00309 WvString(unsigned long i) : WvFastString(i) { } // nothing special 00310 WvString(long long i) : WvFastString(i) { } // nothing special 00311 WvString(unsigned long long i) : WvFastString(i) { } // nothing special 00312 WvString(double i) : WvFastString(i) { } // nothing special 00313 00314 /** 00315 * Magic copy constructor for "fast" char* strings. When we copy from 00316 * a "fast" string to a real WvString, we might need to allocate memory 00317 * (equivalent to unique()) so the original char* can be safely changed 00318 * or destroyed. 00319 */ 00320 WvString(const WvString &s) 00321 { copy_constructor(s); } 00322 WvString(const WvFastString &s) 00323 { copy_constructor(s); } 00324 00325 /** 00326 * Create a WvString out of a char* string. We always allocate memory 00327 * and make a copy here. To avoid memory copies, you can (carefully) 00328 * use a WvFastString. To just have quick parameter passing, use a 00329 * WvStringParm instead. 00330 */ 00331 WvString(const char *_str); 00332 00333 /** 00334 * Create a WvString out of a Qt library QString. You have to link with 00335 * libwvqt.so if you want to use this. 00336 */ 00337 WvString(const QString &); 00338 WvString(const QCString &); 00339 00340 WvString(WVSTRING_FORMAT_DECL) : WvFastString(WVSTRING_FORMAT_CALL) 00341 { } 00342 00343 WvString &append(WvStringParm s); 00344 WvString &append(WVSTRING_FORMAT_DECL) 00345 { return append(WvString(WVSTRING_FORMAT_CALL)); } 00346 00347 WvString &operator= (int i); 00348 WvString &operator= (const WvFastString &s2); 00349 WvString &operator= (const char *s2) 00350 { return *this = WvFastString(s2); } 00351 00352 /** make the buf and str pointers owned only by this WvString. */ 00353 WvString &unique(); 00354 00355 /** make the string editable, and return a non-const (char*) */ 00356 char *edit() 00357 { return unique().str; } 00358 00359 protected: 00360 void copy_constructor(const WvFastString &s); 00361 00362 }; 00363 00364 00365 inline bool operator== (const char *s1, WvStringParm s2) 00366 { 00367 return s2 == s1; 00368 } 00369 00370 00371 inline bool operator!= (const char *s1, WvStringParm s2) 00372 { 00373 return s2 != s1; 00374 } 00375 00376 #endif // __WVSTRING_H

Generated on Tue Oct 5 01:09:21 2004 for WvStreams by doxygen 1.3.7