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 | |
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 | } |