Added Object classes that provide os independent symbol tables.
[dyninst.git] / common / h / String.h
1 /************************************************************************
2  * String.h: a simple character string class.
3 ************************************************************************/
4
5
6 \f
7
8
9 #if !defined(_String_h_)
10 #define _String_h_
11
12
13 \f
14
15
16 /************************************************************************
17  * header files.
18 ************************************************************************/
19
20 #include <iostream.h>
21 #include "kludges.h"
22
23
24 \f
25
26
27 /************************************************************************
28  * class string
29 ************************************************************************/
30
31 class string {
32 public:
33      string ();
34      string (const char *);
35      string (const string &);
36     ~string ();
37
38     string&       operator= (const char *);
39     string&       operator= (const string &);
40     string&      operator+= (const string &);
41     string        operator+ (const string &)         const;
42
43     bool         operator== (const string &)         const;
44     bool         operator!= (const string &)         const;
45     bool          operator< (const string &)         const;
46     bool         operator<= (const string &)         const;
47     bool          operator> (const string &)         const;
48     bool         operator>= (const string &)         const;
49
50     bool          prefix_of (const char *, unsigned) const;
51     bool          prefix_of (const char *)           const;
52     bool          prefix_of (const string &)         const;
53
54     bool        prefixed_by (const char *, unsigned) const;
55     bool        prefixed_by (const char *)           const;
56     bool        prefixed_by (const string &)         const;
57
58     const char*   string_of ()                       const;
59     unsigned         length ()                       const;
60
61     friend ostream& operator<< (ostream &os, const string &s) {
62       return os << s.str_;
63     }
64
65     static unsigned       hash (const string &);
66
67 private:
68     static unsigned      hashs (const char *);
69
70     static unsigned     STRLEN (const char *);
71     static char*        STRDUP (const char *);
72
73     static bool          STREQ (const char *, const char *);
74     static bool         STREQN (const char *, const char *, unsigned);
75     static bool          STRNE (const char *, const char *);
76     static bool          STRLT (const char *, const char *);
77     static bool          STRLE (const char *, const char *);
78     static bool          STRGT (const char *, const char *);
79     static bool          STRGE (const char *, const char *);
80
81     char*    str_;
82     unsigned len_;
83     unsigned key_;
84 };
85
86 inline
87 string::string()
88     : str_(0), len_(0), key_(0) {
89 }
90
91 inline
92 string::string(const char* str)
93     : str_(STRDUP(str)), len_(STRLEN(str)), key_(hashs(str)) {
94 }
95
96 inline
97 string::string(const string& s)
98     : str_(STRDUP(s.str_)), len_(s.len_), key_(s.key_) {
99 }
100
101 inline
102 string::~string() {
103     delete str_; str_ = 0;
104 }
105
106 inline
107 string&
108 string::operator=(const char* str) {
109     if (str_ == str) {
110         return *this;
111     }
112
113     delete str_; str_ = 0;
114
115     str_ = STRDUP(str);
116     len_ = STRLEN(str);
117     key_ = hashs(str);
118
119     return *this;
120 }
121
122 inline
123 string&
124 string::operator=(const string& s) {
125     if (this == &s) {
126         return *this;
127     }
128
129     delete str_; str_ = 0;
130
131     str_ = STRDUP(s.str_);
132     len_ = s.len_;
133     key_ = s.key_;
134
135     return *this;
136 }
137
138 inline
139 string&
140 string::operator+=(const string& s) {
141     unsigned nlen = len_ + s.len_;
142     char*    ptr  = new char[nlen+1];
143
144     memcpy(ptr, str_, len_);
145     memcpy(&ptr[len_], s.str_, s.len_);
146     ptr[nlen] = '\0';
147
148     delete[] str_; str_ = 0;
149     str_ = ptr;
150     len_ = nlen;
151     key_ = hashs(str_);
152
153     return *this;
154 }
155
156 inline
157 string
158 string::operator+(const string& s) const {
159     string ret = *this;
160     return ret += s;
161 }
162
163 inline
164 bool
165 string::operator==(const string& s) const {
166     return ((&s == this)
167         || ((key_ == s.key_)
168         && (len_ == s.len_)
169         && STREQ(str_, s.str_)));
170 }
171
172 inline
173 bool
174 string::operator!=(const string& s) const {
175     return ((!(&s == this)) && (len_ != s.len_)
176         || STRNE(str_, s.str_));
177 }
178
179 inline
180 bool
181 string::operator<(const string& s) const {
182     return STRLT(str_, s.str_);
183 }
184
185 inline
186 bool
187 string::operator<=(const string& s) const {
188     return ((&s == this) || STRLE(str_, s.str_));
189 }
190
191 inline
192 bool
193 string::operator>(const string& s) const {
194     return STRGT(str_, s.str_);
195 }
196
197 inline
198 bool
199 string::operator>=(const string& s) const {
200     return ((&s == this) || STRGE(str_, s.str_));
201 }
202
203 inline
204 bool
205 string::prefix_of(const char* s, unsigned sl) const {
206     return ((len_ > sl) ? false : STREQN(str_, s, len_));
207 }
208
209 inline
210 bool
211 string::prefix_of(const char* s) const {
212     return prefix_of(s, STRLEN(s));
213 }
214
215 inline
216 bool
217 string::prefix_of(const string& s) const {
218     return ((&s == this) || prefix_of(s.str_, s.len_));
219 }
220
221 inline
222 bool
223 string::prefixed_by(const char* s, unsigned sl) const {
224     return ((sl > len_) ? false : STREQN(str_, s, sl));
225 }
226
227 inline
228 bool
229 string::prefixed_by(const char* s) const {
230     return prefixed_by(s, STRLEN(s));
231 }
232
233 inline
234 bool
235 string::prefixed_by(const string& s) const {
236     return ((&s == this) || prefixed_by(s.str_, s.len_));
237 }
238
239 inline
240 unsigned
241 string::length() const {
242     return len_;
243 }
244
245 inline
246 const char*
247 string::string_of() const {
248     return str_;
249 }
250
251 inline
252 unsigned
253 string::hash(const string& s) {
254     return s.key_;
255 }
256
257 inline
258 unsigned
259 string::hashs(const char* str) {
260     if (!str) {
261         return 0;
262     }
263
264     unsigned h = 5381;
265     while (*str) {
266         h = (h << 5) + h + (unsigned) (*str);
267         str++;
268     }
269     return h;
270 }
271
272 inline
273 unsigned
274 string::STRLEN(const char* str) {
275     return ((str)?(strlen(str)):(0));
276 }
277
278 inline
279 char*
280 string::STRDUP(const char* str) {
281     if (!str) {
282         return 0;
283     }
284
285     unsigned size = strlen(str)+1;
286     char*    p    = new char[size];
287
288     (void) memcpy(p, str, size);
289     return p;
290 }
291
292 inline
293 bool
294 string::STREQ(const char* s1, const char* s2) {
295     return ((s1&&s2)?(strcmp(s1,s2)==0):(!(s1||s2)));
296 }
297
298 inline
299 bool
300 string::STREQN(const char* s1, const char* s2, unsigned len) {
301     return ((s1&&s2)?(strncmp(s1,s2,len)==0):(!(s1||s2)));
302 }
303
304 inline
305 bool
306 string::STRNE(const char* s1, const char* s2) {
307     return ((s1&&s2)?(strcmp(s1,s2)!=0):(false));
308 }
309
310 inline
311 bool
312 string::STRLT(const char* s1, const char* s2) {
313     return ((s1&&s2)?(strcmp(s1,s2)<0):(false));
314 }
315
316 inline
317 bool
318 string::STRLE(const char* s1, const char* s2) {
319     return ((s1&&s2)?(strcmp(s1,s2)<=0):(!(s1||s2)));
320 }
321
322 inline
323 bool
324 string::STRGT(const char* s1, const char* s2) {
325     return ((s1&&s2)?(strcmp(s1,s2)>0):(false));
326 }
327
328 inline
329 bool
330 string::STRGE(const char* s1, const char* s2) {
331     return ((s1&&s2)?(strcmp(s1,s2)>=0):(!(s1||s2)));
332 }
333
334
335 \f
336
337
338 #endif /* !defined(_String_h_) */