[project @ 2002-07-07 02:33:51 by unknown_lamer]
[clinton/bobotpp.git] / source / String.C
1 // String.C -*- C++ -*-
2 // Copyright (c) 1997, 1998 Etienne BERNARD
3
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // any later version.
8
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17
18 #include "String.H"
19
20 #include <cstring>
21 #include <cctype>
22 #include <sstream>
23
24 String::String()
25 {
26 p = new srep;
27 len = 0;
28 p->s = 0;
29 }
30
31 String::String(const char *s)
32 {
33 p = new srep;
34 len = strlen(s);
35 p->s = new char[len + 1];
36 std::strcpy(p->s, s);
37 }
38
39 String::String(const std::string & s)
40 {
41 p = new srep;
42 len = s.length ();
43 p->s = new char[len + 1];
44 std::strcpy (p->s, s.c_str ());
45 }
46
47 String::String(const String & s)
48 {
49 s.p->n++;
50 p = s.p;
51 len = s.len;
52 }
53
54 String::String(long i)
55 {
56 std::ostringstream temp;
57 temp << i;
58
59 p = new srep;
60 len = strlen(temp.str().c_str ());
61 p->s = new char[len + 1];
62 strcpy(p->s, temp.str().c_str ());
63 }
64
65 String::String(char c)
66 {
67 p = new srep;
68 p->s = new char[2];
69 p->s[0] = c;
70 p->s[1] = '\0';
71 len = 1;
72 }
73
74 String::~String()
75 {
76 if (--p->n == 0) {
77 delete[] p->s;
78 delete p;
79 }
80 }
81
82 String &
83 String::operator=(const char *s)
84 {
85 if (p->n > 1) {
86 p->n--;
87 p = new srep;
88 }
89 else
90 delete[] p->s;
91
92 len = strlen(s);
93 p->s = new char[len + 1];
94 strcpy(p->s, s);
95
96 return *this;
97 }
98
99 String &
100 String::operator=(const String & s)
101 {
102 s.p->n++; // protection contre st = st
103 if (--p->n == 0) {
104 delete[] p->s;
105 delete p;
106 }
107 p = s.p;
108 len = s.len;
109 return *this;
110 }
111
112 String &
113 String::operator=(const std::string & s)
114 {
115 if (p->n > 1) {
116 p->n--;
117 p = new srep;
118 }
119 else
120 delete[] p->s;
121
122 len = s.length ();
123 p->s = new char[len + 1];
124 strcpy(p->s, s.c_str ());
125
126 return *this;
127 }
128
129 int
130 String::length() const
131 {
132 return len;
133 }
134
135 int
136 String::find(char c)
137 {
138 if (!strchr(p->s, c))
139 return -1;
140
141 return (int)(strchr(p->s, c) - p->s);
142 }
143
144 void
145 String::fill(char c)
146 {
147 for (char * s = p->s; *s; s++)
148 *s = c;
149 }
150
151 String
152 String::pad(int n)
153 {
154 int l = len;
155
156 if (n <= l)
157 return subString(0, n-1);
158
159 char *temp = new char[n+1];
160 strcpy(temp, p->s);
161
162 for (int i = l; i < n; i++)
163 temp[i] = ' ';
164 temp[n] = '\0';
165
166 String res(temp);
167 delete temp;
168
169 return res;
170 }
171
172 String
173 String::subString(int debut, int fin)
174 {
175 if (fin < debut) return "";
176
177 char * temp = new char[fin-debut+2];
178 strncpy(temp, p->s + debut, fin - debut + 1);
179 temp[fin - debut + 1] = '\0';
180 String res(temp);
181 delete temp;
182 return res;
183 }
184
185 String
186 String::subString(int debut)
187 {
188 return subString(debut, len - 1);
189 }
190
191 String
192 String::toLower()
193 {
194 char *temp = new char[len + 1];
195
196 for (int i = 0; i < len + 1; i++)
197 if (isupper(p->s[i]))
198 temp[i] = tolower(p->s[i]);
199 else
200 temp[i] = p->s[i];
201
202 String res(temp);
203 delete temp;
204 return res;
205 }
206
207 String
208 String::toUpper()
209 {
210 char *temp = new char[len + 1];
211
212 for (int i = 0; i < len + 1; i++)
213 if (islower(p->s[i]))
214 temp[i] = toupper(p->s[i]);
215 else
216 temp[i] = p->s[i];
217
218 String res(temp);
219 delete temp;
220 return res;
221 }
222
223 String
224 String::trim()
225 {
226 int i = 0, j = len - 1;
227
228 while (i < j && (p->s[i] == ' ' || p->s[i] == '\t' || p->s[i] == '\r'))
229 i++;
230
231 while (j > 0 && (p->s[j] == ' ' || p->s[j] == '\t' || p->s[i] == '\r'))
232 j--;
233
234 return subString(i, j);
235 }
236
237 int
238 String::indexOf(char c)
239 {
240 char *s = std::strchr(p->s, c);
241 if (s)
242 return p->s - s;
243
244 return -1;
245 }
246
247 char &
248 String::operator[](int i)
249 {
250 if (i < 0 || len < i) {
251 std::cerr << "String index out of range\n";
252 std::exit(1);
253 }
254 return p->s[i];
255 }
256
257 const char &
258 String::operator[](int i) const
259 {
260 if (i < 0 || len < i) {
261 std::cerr << "String index out of range\n";
262 exit(1);
263 }
264 return p->s[i];
265 }
266
267 bool
268 String::operator==(const char *s) const
269 {
270 return std::strcmp(p->s, s) == 0;
271 }
272
273 bool
274 String::operator==(const String & s) const
275 {
276 return (p == s.p) || (std::strcmp(p->s, s.p->s) == 0);
277 }
278
279 bool
280 String::operator==(const std::string & s) const
281 {
282 return (p->s == s.c_str ()) || (std::strcmp (p->s, s.c_str()) == 0);
283 }
284
285 bool
286 String::operator!=(const char *s) const
287 {
288 return std::strcmp(p->s, s) != 0;
289 }
290
291 bool
292 String::operator!=(const String & s) const
293 {
294 return std::strcmp(p->s, s.p->s) != 0;
295 }
296
297 bool
298 String::operator!=(const std::string & s) const
299 {
300 return ! (*this == s);
301 }
302
303 bool
304 String::operator<(const String & s) const
305 {
306 return std::strcmp(p->s, s.p->s) < 0;
307 }
308
309 bool
310 String::operator<(const std::string & s) const
311 {
312 return std::strcmp(p->s, s.c_str ()) < 0;
313 }
314
315 bool
316 String::operator>(const String & s) const
317 {
318 return std::strcmp(p->s, s.p->s) > 0;
319 }
320
321 bool
322 String::operator<=(const String & s) const
323 {
324 return std::strcmp(p->s, s.p->s) <= 0;
325 }
326
327 bool
328 String::operator<=(const std::string & s) const
329 {
330 return (*this < s) || (*this == s);
331 }
332
333 bool
334 String::operator>=(const String & s) const
335 {
336 return std::strcmp(p->s, s.p->s) >= 0;
337 }
338
339 bool String::operator>=(const std::string & s) const
340 {
341 return ! (*this < s);
342 }
343
344 String
345 String::operator+(const char *s)
346 {
347 char *temp = new char[len + std::strlen(s) + 1];
348
349 std::strcpy(temp, p->s);
350 std::strcat(temp, s);
351
352 String res(temp);
353 delete temp;
354
355 return res;
356 }
357
358 String
359 String::operator+(const String & s)
360 {
361 char * temp = new char[len + s.len + 1];
362
363 std::strcpy(temp, p->s);
364 std::strcat(temp, s.p->s);
365
366 String res(temp);
367 delete temp;
368
369 return res;
370 }
371
372 String
373 String::operator+(const std::string & s)
374 {
375 char * temp = new char[len + s.length () + 1];
376 std::strcpy (temp, p->s);
377 std::strcat (temp, s.c_str ());
378
379 String res (temp);
380 delete temp;
381
382 return res;
383 }
384
385 String::operator const char *() const
386 {
387 return p->s;
388 }
389
390 String::operator std::string () const
391 {
392 return std::string (p->s);
393 }
394
395 std::ostream &
396 operator<<(std::ostream & s, const String & st)
397 {
398 return s << st.p->s;
399 }
400
401 std::istream &
402 operator>>(std::istream & s, String & st)
403 {
404 if (st.p->n > 1) {
405 st.p->n--;
406 st.p = new String::srep;
407 }
408 else
409 delete[] st.p->s;
410
411 char buf[2048];
412 char c;
413
414 s.getline (buf, 2048, '\n');
415 //s.get(c);
416
417 st.len = strlen(buf);
418 st.p->s = new char[st.len + 1];
419 strcpy(st.p->s, buf);
420
421 return s;
422 }
423
424 std::string operator+(const std::string & s, const String & p)
425 {
426 std::string temp = s;
427 temp += p.p->s;
428 return temp;
429 }
430
431 bool operator==(const std::string & s, const String & p)
432 {
433 return p == s;
434 }
435
436 bool operator!=(const std::string & s, const String & p)
437 {
438 return p != s;
439 }
440
441 bool operator>(const std::string & s, const String & p)
442 {
443 return p <= s;
444 }
445
446 bool operator<(const std::string & s, const String & p)
447 {
448 return p >= s;
449 }
450
451 bool operator<=(const std::string & s, const String & p)
452 {
453 return p > s;
454 }
455
456 bool operator>=(const std::string & s, const String & p)
457 {
458 return p < s;
459 }