ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/include/shstr.h
Revision: 1.23
Committed: Sun Dec 28 06:59:27 2008 UTC (15 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_74
Changes since 1.22: +13 -5 lines
Log Message:
smell, remove gcfclient support, material fixes, cfpod parse fixes, refactoring

File Contents

# User Rev Content
1 root 1.16 /*
2 root 1.20 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 root 1.16 *
4 root 1.22 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 root 1.16 *
6 root 1.20 * Deliantra is free software: you can redistribute it and/or modify
7 root 1.17 * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10 root 1.16 *
11 root 1.17 * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15 root 1.16 *
16 root 1.17 * You should have received a copy of the GNU General Public License
17     * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 root 1.16 *
19 root 1.20 * The authors can be reached via e-mail to <support@deliantra.net>
20 root 1.16 */
21    
22 root 1.2 #ifndef SHSTR_H__
23     #define SHSTR_H__
24    
25 root 1.13 #include <sstream>
26    
27 root 1.8 #include "util.h"
28    
29 root 1.19 extern size_t shstr_alloc;
30    
31 root 1.8 extern int buf_overflow (const char *buf1, const char *buf2, int bufsize);
32 root 1.5
33     struct shstr
34     {
35 root 1.8 static const char *null;
36    
37 root 1.5 const char *s;
38 root 1.4
39 root 1.7 static int &refcnt (const char *s)
40 root 1.5 {
41     return *((int *)s - 1);
42     }
43    
44 root 1.7 static int &length (const char *s)
45     {
46     return *((int *)s - 2);
47     }
48    
49     int &refcnt () const
50     {
51     return refcnt (s);
52     }
53    
54     int length () const
55     {
56 root 1.8 return length (s);
57 root 1.7 }
58    
59 root 1.15 // returns wether this shared string begins with the given prefix,
60     // used mainly for searched when users give only the start of a name.
61     bool begins_with (const char *prefix) const
62     {
63     int plen = strlen (prefix);
64     return !strncasecmp (s, prefix, plen) && length () >= plen;
65     }
66    
67 root 1.5 static const char *find (const char *s);
68     static const char *intern (const char *s);
69    
70     static void gc (); // garbage collect a few strings
71    
72 root 1.6 // this is used for informational messages and the like
73 root 1.8 const char *operator &() const { return s; }
74 root 1.5
75 root 1.6 const char &operator [](int i) const { return s[i]; }
76 root 1.8 operator const char *() const { return s == null ? 0 : s; }
77 root 1.5
78     shstr ()
79 root 1.8 : s (null)
80 root 1.5 {
81     }
82    
83 root 1.6 shstr (const shstr &sh)
84 root 1.5 : s (sh.s)
85     {
86 root 1.8 ++refcnt ();
87 root 1.5 }
88    
89     explicit shstr (const char *s)
90     : s (intern (s))
91     {
92     }
93    
94     ~shstr ()
95     {
96 root 1.8 --refcnt ();
97 root 1.5 }
98    
99     const shstr &operator =(const shstr &sh)
100     {
101 root 1.8 --refcnt ();
102 root 1.5 s = sh.s;
103 root 1.8 ++refcnt ();
104 root 1.5
105     return *this;
106     }
107    
108     const shstr &operator =(const char *str)
109     {
110 root 1.8 --refcnt ();
111    
112     // this optimises the important case of str == constant 0
113     if (is_constant (str))
114     s = str ? intern (str) : null;
115     else
116     s = intern (str);
117 root 1.1
118 root 1.5 return *this;
119     }
120 root 1.10
121     bool operator !=(const shstr &b)
122     {
123     return !(*this == b);
124     }
125 root 1.5 };
126 root 1.1
127 root 1.23 inline bool operator ==(const shstr &a, const shstr &b)
128     {
129     return a.s == b.s;
130     }
131    
132 root 1.5 inline int strlen (const shstr &sh)
133     {
134     return sh.length ();
135     }
136 root 1.2
137 root 1.12 inline int strcmp (const shstr &a, const shstr &b)
138     {
139     // TODO: use this to find all the occurences of people using strcmp
140     // all uses should be bogus, as we should be never interested in
141     // comparing shstr's alphabetically
142     #if 0
143     extern void do_not_use_strcmp_to_compare_shstr_values ();
144     do_not_use_strcmp_to_compare_shstr_values ();
145     #endif
146     return a != b;
147     }
148    
149 root 1.14 static std::ostream &operator <<(std::ostream &o, const shstr &sh)
150 root 1.13 {
151     o.write (sh.s, sh.length ());
152     return o;
153     }
154    
155 root 1.10 // only good for mass comparisons to shstr objects
156     struct shstr_cmp
157     {
158     const char *s;
159    
160     explicit shstr_cmp (const char *s)
161     : s (shstr::find (s))
162     {
163     }
164    
165 root 1.11 shstr_cmp (const shstr_cmp &sh)
166     : s (sh.s)
167     {
168     }
169    
170 root 1.23 shstr_cmp (const shstr &sh)
171     : s (sh.s)
172     {
173     }
174    
175     // this is used for informational messages and the like
176     const char *operator &() const { return s; }
177    
178 root 1.11 shstr_cmp &operator =(const shstr_cmp sh) { s = sh.s; return *this; }
179 root 1.10 operator const char *() const { return s; }
180     };
181    
182     inline bool operator ==(const shstr_cmp &a, const shstr &b)
183 root 1.5 {
184     return a.s == b.s;
185     }
186 root 1.4
187 root 1.10 inline bool operator ==(const shstr &a, const shstr_cmp &b)
188 root 1.4 {
189 root 1.10 return b == a;
190 root 1.5 }
191 root 1.4
192 root 1.21 extern const shstr shstr_null;
193    
194 root 1.18 #define def(str) extern const shstr shstr_ ## str;
195     # include "shstrinc.h"
196     #undef def
197 root 1.9
198 root 1.2 #endif
199