--- deliantra/server/include/shstr.h 2006/09/03 00:18:41 1.5 +++ deliantra/server/include/shstr.h 2006/09/03 23:33:01 1.8 @@ -1,68 +1,88 @@ #ifndef SHSTR_H__ #define SHSTR_H__ -extern int buf_overflow(const char *buf1, const char *buf2, int bufsize); +#include "util.h" + +extern int buf_overflow (const char *buf1, const char *buf2, int bufsize); struct shstr { + static const char *null; + const char *s; - int &refcnt () + static int &refcnt (const char *s) { return *((int *)s - 1); } + static int &length (const char *s) + { + return *((int *)s - 2); + } + + int &refcnt () const + { + return refcnt (s); + } + + int length () const + { + return length (s); + } + static const char *find (const char *s); static const char *intern (const char *s); static void gc (); // garbage collect a few strings - // this is used for informational messages and the like I/O - const char *operator &() const { return s ? s : ""; } - - const char &operator [](int i) { return s[i]; } - operator const char *() const { return s; } + // this is used for informational messages and the like + const char *operator &() const { return s; } - int length () const - { - return s ? *((int *)s - 2) : 0; - } + const char &operator [](int i) const { return s[i]; } + operator const char *() const { return s == null ? 0 : s; } shstr () - : s (0) + : s (null) { } - shstr (shstr &sh) + shstr (const shstr &sh) : s (sh.s) { - if (s) ++refcnt (); + ++refcnt (); } explicit shstr (const char *s) : s (intern (s)) { - if (s) ++refcnt (); } ~shstr () { - if (s) --refcnt (); + --refcnt (); } const shstr &operator =(const shstr &sh) { - if (s) --refcnt (); + --refcnt (); s = sh.s; - if (s) ++refcnt (); + ++refcnt (); return *this; } const shstr &operator =(const char *str) { - if (s) --refcnt (); - s = intern (str); + --refcnt (); + +#if 0 + // this optimises the important case of str == constant 0 + if (is_constant (str)) + s = str ? intern (str) : null; + else +#endif + s = intern (str); return *this; }