default ctor sped up
[dyninst.git] / pdutil / src / String.C
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // String.C
43
44 #include <assert.h>
45 #include "util/h/headers.h"
46 #include "util/h/String.h"
47
48 // Declare static member vrbles:
49 string *string::nilptr;
50 int string_counter::count;
51
52 string_ll::string_ll()
53     : str_(0), len_(0), key_(0) {
54 }
55
56 string_ll::string_ll(const char* str)
57     : str_(STRDUP(str)), len_(STRLEN(str)) {
58    key_ = 0; // lazy key define
59 }
60
61 string_ll::string_ll(const char *str, unsigned len) {
62    // same as above constructor, but copies less than the entire string.
63    // You specifiy the # of chars to copy.
64    if (len > strlen(str))
65       // just copy the whole string
66       len = strlen(str);
67
68    len_ = len;
69    str_ = new char[len+1];
70    (void) P_memcpy(str_, str, len);
71    str_[len] = '\0';
72
73    key_ = 0; // lazy key define
74 }
75
76 string_ll::string_ll(const string_ll& s)
77     : str_(STRDUP(s.str_)), len_(s.len_), key_(s.key_) {
78    // lazy key define iff "s" lazy key define (as it should be)
79 }
80
81 string_ll::string_ll(int i) {
82    char tempBuffer[40];
83    sprintf(tempBuffer, "%d", i);
84
85    str_ = STRDUP(tempBuffer);
86    len_ = STRLEN(tempBuffer);
87
88    key_ = 0; // lazy key define
89 }
90
91 string_ll::string_ll(long l) {
92    char tempBuffer[40];
93    sprintf(tempBuffer, "%ld", l);
94
95    str_ = STRDUP(tempBuffer);
96    len_ = STRLEN(tempBuffer);
97
98    key_ = 0; // lazy key define
99 }
100
101 string_ll::string_ll(unsigned u) {
102    char tempBuffer[40];
103    sprintf(tempBuffer, "%u", u);
104
105    str_ = STRDUP(tempBuffer);
106    len_ = STRLEN(tempBuffer);
107
108    key_ = 0; // lazy key define
109 }
110
111 string_ll::string_ll(unsigned long ul) {
112    char tempBuffer[40];
113    sprintf(tempBuffer, "%lu", ul);
114
115    str_ = STRDUP(tempBuffer);
116    len_ = STRLEN(tempBuffer);
117
118    key_ = 0; // lazy key define
119 }
120
121 string_ll::string_ll(float f) {
122    char tempBuffer[40];
123    sprintf(tempBuffer, "%f", f);
124
125    str_ = STRDUP(tempBuffer);
126    len_ = STRLEN(tempBuffer);
127
128    key_ = 0; // lazy key define
129 }
130
131 string_ll::string_ll(double d) {
132    char tempBuffer[40];
133    sprintf(tempBuffer, "%g", d);
134
135    str_ = STRDUP(tempBuffer);
136    len_ = STRLEN(tempBuffer);
137
138    key_ = 0; // lazy key define
139 }
140
141 string_ll::~string_ll() {
142     delete [] str_; str_ = 0;
143 }
144
145 string_ll&
146 string_ll::operator=(const char* str) {
147     if (str_ == str) {
148         return *this;
149     }
150
151     delete [] str_; str_ = 0;
152
153     str_ = STRDUP(str);
154     len_ = STRLEN(str);
155
156     key_ = 0; // lazy key define
157
158     return *this;
159 }
160
161 string_ll&
162 string_ll::operator=(const string_ll& s) {
163     if (this == &s) {
164         return *this;
165     }
166
167     delete [] str_; str_ = 0;
168
169     str_ = STRDUP(s.str_);
170     len_ = s.len_;
171     key_ = s.key_; // lazy key define iff "s" lazy key define, which is correct
172
173     return *this;
174 }
175
176 string_ll&
177 string_ll::operator+=(const string_ll& s) {
178     unsigned nlen = len_ + s.len_;
179     char*    ptr  = new char[nlen+1];
180     assert(ptr);
181
182     memcpy(ptr, str_, len_);
183     memcpy(&ptr[len_], s.str_, s.len_);
184     ptr[nlen] = '\0';
185
186     delete[] str_; str_ = 0;
187     str_ = ptr;
188     len_ = nlen;
189
190     key_ = 0;
191
192     return *this;
193 }
194
195 string_ll&
196 string_ll::operator+=(const char *ptr) {
197    // this routine exists as an optimization, sometimes avoiding the need to create
198    // a temporary string, which can be expensive.
199
200    const int ptr_len = P_strlen(ptr);
201    const unsigned nlen = len_ + ptr_len;
202    char *new_ptr = new char[nlen+1];
203    assert(new_ptr);
204
205    memcpy(new_ptr, str_, len_);
206    memcpy(&new_ptr[len_], ptr, ptr_len);
207    new_ptr[nlen] = '\0';
208   
209    delete [] str_;
210    str_ = new_ptr;
211    len_ = nlen;
212
213    key_ = 0; // lazy key define
214
215    return *this;
216 }
217
218
219 string_ll
220 string_ll::operator+(const string_ll& s) const {
221     string_ll ret = *this;
222     return (ret += s);
223 }
224
225 string_ll
226 string_ll::operator+(const char *ptr) const {
227    string_ll ret = *this;
228    return (ret += ptr);
229 }
230
231 bool
232 string_ll::operator==(const string_ll& s) const {
233    if (&s == this) return true;
234
235    updateKeyIfNeeded(); s.updateKeyIfNeeded();
236    if (key_ != s.key_) return false;
237    if (len_ != s.len_) return false;
238    return STREQ(str_, s.str_);
239 }
240
241 bool
242 string_ll::operator!=(const string_ll& s) const {
243    if (&s == this) return false;
244    if (len_ != s.len_) return true;
245    return STRNE(str_, s.str_);
246 }
247
248 bool
249 string_ll::operator<=(const string_ll& s) const {
250     return ((&s == this) || STRLE(str_, s.str_));
251 }
252
253 bool
254 string_ll::operator>=(const string_ll& s) const {
255     return ((&s == this) || STRGE(str_, s.str_));
256 }
257
258 bool
259 string_ll::prefix_of(const char* s, unsigned sl) const {
260     return ((len_ > sl) ? false : STREQN(str_, s, len_));
261 }
262
263 bool
264 string_ll::prefix_of(const string_ll& s) const {
265     return ((&s == this) || prefix_of(s.str_, s.len_));
266 }
267
268 bool
269 string_ll::prefixed_by(const char* s, unsigned sl) const {
270     return ((sl > len_) ? false : STREQN(str_, s, sl));
271 }
272
273 bool
274 string_ll::prefixed_by(const string_ll& s) const {
275     return ((&s == this) || prefixed_by(s.str_, s.len_));
276 }
277
278 unsigned
279 string_ll::hashs(const char* str) {
280     if (!str)
281        return 1; // 0 is reserved for unhashed key
282
283     unsigned h = 5381;
284     while (*str) {
285         h = (h << 5) + h + (unsigned) (*str);
286         str++;
287     }
288     return h==0 ? 1 : h; // 0 is reserved for unhashed key
289 }
290
291 unsigned
292 string_ll::STRLEN(const char* str) {
293     return ((str)?(P_strlen(str)):(0));
294 }
295
296 char*
297 string_ll::STRDUP(const char* str) {
298     if (!str) {
299         return 0;
300     }
301
302     unsigned size = P_strlen(str)+1;
303     char*    p    = new char[size];
304
305     (void) P_memcpy(p, str, size);
306     return p;
307 }
308
309 bool
310 string_ll::STREQ(const char* s1, const char* s2) {
311     return ((s1&&s2)?(P_strcmp(s1,s2)==0):(!(s1||s2)));
312 }
313
314 bool
315 string_ll::STREQN(const char* s1, const char* s2, unsigned len) {
316     return ((s1&&s2)?(P_strncmp(s1,s2,len)==0):(!(s1||s2)));
317 }
318
319 bool
320 string_ll::STRNE(const char* s1, const char* s2) {
321     return ((s1&&s2)?(P_strcmp(s1,s2)!=0):(false));
322 }
323
324 bool
325 string_ll::STRLT(const char* s1, const char* s2) {
326     return ((s1&&s2)?(P_strcmp(s1,s2)<0):(false));
327 }
328
329 bool
330 string_ll::STRLE(const char* s1, const char* s2) {
331     return ((s1&&s2)?(P_strcmp(s1,s2)<=0):(!(s1||s2)));
332 }
333
334 bool
335 string_ll::STRGT(const char* s1, const char* s2) {
336     return ((s1&&s2)?(P_strcmp(s1,s2)>0):(false));
337 }
338
339 bool
340 string_ll::STRGE(const char* s1, const char* s2) {
341     return ((s1&&s2)?(P_strcmp(s1,s2)>=0):(!(s1||s2)));
342 }
343
344 ostream& operator<< (ostream &os, const string_ll &s) {
345    return os << s.str_;
346 }
347
348 debug_ostream& operator<< (debug_ostream &os, const string_ll &s) {
349    return os << s.str_;
350 }
351
352 string operator+(const char *ptr, const string &str) {
353    // a syntactical convenience.
354    // This fn could probably be optimized quite a bit (pre-allocate exactly
355    // the # of bytes that are needed)
356    string result(ptr);
357    result += str;
358    return result;
359 }
360
361 void string::initialize_static_stuff() {
362    // should only get called once:
363    assert(nilptr == NULL);
364
365    nilptr = new string((char*)NULL);
366       // the typecast is essential, lest NULL be interpreted
367       // as the integer 0 instead of the pointer 0!
368 }
369
370 void string::free_static_stuff() {
371    delete nilptr;
372    nilptr = NULL;
373 }