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