Split string class into a .h and .C component; strings can now
[dyninst.git] / pdutil / src / String.C
1 // String.C
2
3 #include <assert.h>
4 #include "util/h/String.h"
5
6 string string::quote="\"";
7
8 string::string()
9     : str_(0), len_(0), key_(0) {
10 }
11
12 string::string(const char* str)
13     : str_(STRDUP(str)), len_(STRLEN(str)), key_(hashs(str)) {
14 }
15
16 string::string(const string& s)
17     : str_(STRDUP(s.str_)), len_(s.len_), key_(s.key_) {
18 }
19
20 string::string(int i) {
21    char tempBuffer[40];
22    sprintf(tempBuffer, "%d", i);
23
24    str_ = STRDUP(tempBuffer);
25    len_ = STRLEN(tempBuffer);
26    key_ = hashs (tempBuffer);
27 }
28
29 string::string(unsigned u) {
30    char tempBuffer[40];
31    sprintf(tempBuffer, "%u", u);
32
33    str_ = STRDUP(tempBuffer);
34    len_ = STRLEN(tempBuffer);
35    key_ = hashs (tempBuffer);
36 }
37
38 string::string(float f) {
39    char tempBuffer[40];
40    sprintf(tempBuffer, "%f", f);
41
42    str_ = STRDUP(tempBuffer);
43    len_ = STRLEN(tempBuffer);
44    key_ = hashs (tempBuffer);
45 }
46
47 string::string(FILE *infile) {
48    assert(1 == fread(&len_, sizeof(len_), 1, infile));
49    char *temp = new char[len_ + 1]; assert(temp);
50    assert(len_ == fread(temp, 1, len_, infile));
51    temp[len_] = '\0';
52
53    str_ = STRDUP(temp);
54    key_ = hashs(temp);
55
56    delete [] temp;
57 }
58
59 string::~string() {
60     delete [] str_; str_ = 0;
61 }
62
63 int string::save(FILE *outfile) const {
64    if (1 != fwrite(&len_, sizeof(len_), 1, outfile))
65       return -1;
66
67    if (len_ != fwrite(str_, 1, len_, outfile))
68       return -1;
69
70    return 0; // success
71 }
72
73 string&
74 string::operator=(const char* str) {
75     if (str_ == str) {
76         return *this;
77     }
78
79     delete [] str_; str_ = 0;
80
81     str_ = STRDUP(str);
82     len_ = STRLEN(str);
83     key_ = hashs(str);
84
85     return *this;
86 }
87
88 string&
89 string::operator=(const string& s) {
90     if (this == &s) {
91         return *this;
92     }
93
94     delete [] str_; str_ = 0;
95
96     str_ = STRDUP(s.str_);
97     len_ = s.len_;
98     key_ = s.key_;
99
100     return *this;
101 }
102
103 string&
104 string::operator+=(const string& s) {
105     unsigned nlen = len_ + s.len_;
106     char*    ptr  = new char[nlen+1];
107
108     memcpy(ptr, str_, len_);
109     memcpy(&ptr[len_], s.str_, s.len_);
110     ptr[nlen] = '\0';
111
112     delete[] str_; str_ = 0;
113     str_ = ptr;
114     len_ = nlen;
115     key_ = hashs(str_);
116
117     return *this;
118 }
119
120 string
121 string::operator+(const string& s) const {
122     string ret = *this;
123     return ret += s;
124 }
125
126 bool
127 string::operator==(const string& s) const {
128     return ((&s == this)
129         || ((key_ == s.key_)
130         && (len_ == s.len_)
131         && STREQ(str_, s.str_)));
132 }
133
134 bool
135 string::operator!=(const string& s) const {
136     return ((!(&s == this)) && (len_ != s.len_)
137         || STRNE(str_, s.str_));
138 }
139
140 bool
141 string::operator<=(const string& s) const {
142     return ((&s == this) || STRLE(str_, s.str_));
143 }
144
145 bool
146 string::operator>=(const string& s) const {
147     return ((&s == this) || STRGE(str_, s.str_));
148 }
149
150 bool
151 string::prefix_of(const char* s, unsigned sl) const {
152     return ((len_ > sl) ? false : STREQN(str_, s, len_));
153 }
154
155 bool
156 string::prefix_of(const string& s) const {
157     return ((&s == this) || prefix_of(s.str_, s.len_));
158 }
159
160 bool
161 string::prefixed_by(const char* s, unsigned sl) const {
162     return ((sl > len_) ? false : STREQN(str_, s, sl));
163 }
164
165 bool
166 string::prefixed_by(const string& s) const {
167     return ((&s == this) || prefixed_by(s.str_, s.len_));
168 }
169
170 unsigned
171 string::hashs(const char* str) {
172     if (!str) {
173         return 0;
174     }
175
176     unsigned h = 5381;
177     while (*str) {
178         h = (h << 5) + h + (unsigned) (*str);
179         str++;
180     }
181     return h;
182 }
183
184 //#define P_strlen strlen
185 //#define P_memcpy memcpy
186
187 unsigned
188 string::STRLEN(const char* str) {
189     return ((str)?(P_strlen(str)):(0));
190 }
191
192 char*
193 string::STRDUP(const char* str) {
194     if (!str) {
195         return 0;
196     }
197
198     unsigned size = P_strlen(str)+1;
199     char*    p    = new char[size];
200
201     (void) P_memcpy(p, str, size);
202     return p;
203 }
204
205 //#define P_strcmp strcmp
206
207 bool
208 string::STREQ(const char* s1, const char* s2) {
209     return ((s1&&s2)?(P_strcmp(s1,s2)==0):(!(s1||s2)));
210 }
211
212 //#define P_strncmp strncmp
213
214 bool
215 string::STREQN(const char* s1, const char* s2, unsigned len) {
216     return ((s1&&s2)?(P_strncmp(s1,s2,len)==0):(!(s1||s2)));
217 }
218
219 bool
220 string::STRNE(const char* s1, const char* s2) {
221     return ((s1&&s2)?(P_strcmp(s1,s2)!=0):(false));
222 }
223
224 bool
225 string::STRLT(const char* s1, const char* s2) {
226     return ((s1&&s2)?(P_strcmp(s1,s2)<0):(false));
227 }
228
229 bool
230 string::STRLE(const char* s1, const char* s2) {
231     return ((s1&&s2)?(P_strcmp(s1,s2)<=0):(!(s1||s2)));
232 }
233
234 bool
235 string::STRGT(const char* s1, const char* s2) {
236     return ((s1&&s2)?(P_strcmp(s1,s2)>0):(false));
237 }
238
239 bool
240 string::STRGE(const char* s1, const char* s2) {
241     return ((s1&&s2)?(P_strcmp(s1,s2)>=0):(!(s1||s2)));
242 }
243
244 ostream& operator<< (ostream &os, const string &s) {
245    return os << s.str_;
246 }