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