source: CMT/HEAD/source/cmt_string.cxx @ 607

Last change on this file since 607 was 607, checked in by rybkin, 12 years ago

See C.L. 482

  • Property svn:eol-style set to native
File size: 14.5 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// See the complete license in cmt_license.txt "http://www.cecill.info".
5//-----------------------------------------------------------
6
7#include <stdio.h>
8#include <stdlib.h>
9#include "cmt_std.h"
10#include "cmt_string.h"
11
12cmt_string::cmt_string ()
13{
14  _data = 0;
15  _allocated = 0;
16  _size = 0;
17}
18
19cmt_string::cmt_string (int n)
20{
21  _data = 0;
22  _allocated = 0;
23  _size = 0;
24  allocate (n + 1);
25}
26
27cmt_string::cmt_string (char c)
28{
29  _data = 0;
30  _allocated = 0;
31  _size = 0;
32
33  allocate (2);
34
35  _data[0] = c;
36  _data[1] = 0;
37  _size = 1;
38}
39
40cmt_string::cmt_string (const char* text)
41{
42  _data = 0;
43  _allocated = 0;
44  _size = 0;
45
46  if (text != 0)
47    {
48      _size = strlen (text);
49      allocate (_size + 1);
50      strcpy (_data, text);
51    }
52}
53
54cmt_string::cmt_string (const cmt_string& other)
55{
56  const char* text = other._data;
57
58  _data = 0;
59  _allocated = 0;
60  _size = 0;
61
62  if (text != 0)
63    {
64      _size = strlen (text);
65      allocate (_size + 1);
66      strcpy (_data, text);
67    }
68}
69
70cmt_string::~cmt_string ()
71{
72  if (_data != 0)
73    {
74#ifdef CMT_USE_NEW_DELETE
75      delete[] _data;
76#else
77      free (_data);
78#endif
79    }
80  _data = 0;
81  _allocated = 0;
82  _size = 0;
83}
84
85  //
86  // Operators
87  //
88cmt_string& cmt_string::operator = (char c)
89{
90  allocate (2);
91
92  _data[0] = c;
93  _data[1] = 0;
94
95  _size = 1;
96
97  return (*this);
98}
99
100cmt_string& cmt_string::operator = (const char* text)
101{
102  if (text == _data) return (*this);
103
104  if (text != 0)
105    {
106      _size = strlen (text);
107      allocate (_size + 1);
108      strcpy (_data, text);
109    }
110  else
111    {
112      _size = 0;
113
114      if (_data != 0)
115        {
116          _data[0] = 0;
117        }
118    }
119
120  return (*this);
121}
122
123cmt_string& cmt_string::operator = (const cmt_string& other)
124{
125  const char* text = other._data;
126  cmt_string& me = *this;
127  me = text;
128  return (me);
129}
130
131cmt_string::operator const char* () const
132{
133  if (_data == 0) return ("");
134  else return (_data);
135}
136
137const char* cmt_string::c_str () const
138{
139  if (_data == 0) return ("");
140  else return (_data);
141}
142
143/*
144char* cmt_string::c_str ()
145{
146  return (_data);
147}
148*/
149
150void cmt_string::operator += (char c)
151{
152  extend (2);
153
154  char temp[2] = { c, 0 };
155
156  strcat (&_data[_size], temp);
157  _size++;
158}
159
160void cmt_string::operator += (const char* text)
161{
162  if (text == 0) return;
163
164  int s = strlen (text);
165  extend (s + 1);
166
167  strcat (&_data[_size], text);
168  _size += s;
169}
170
171void cmt_string::operator += (const cmt_string& other)
172{
173  const char* text = other._data;
174  cmt_string& me = *this;
175
176  me += text;
177}
178
179cmt_string cmt_string::operator + (char c) const
180{
181  cmt_string result (_data);
182  result += c;
183
184  return (result);
185}
186
187cmt_string cmt_string::operator + (const char* text) const
188{
189  cmt_string result (_data);
190  result += text;
191
192  return (result);
193}
194
195cmt_string cmt_string::operator + (const cmt_string& other) const
196{
197  cmt_string result (_data);
198  result += other;
199
200  return (result);
201}
202
203char cmt_string::operator [] (int index) const
204{
205  if ((_data == 0) ||
206      (index < 0) ||
207      (index >= _size))
208    {
209      return (0);
210    }
211  else
212    {
213      return (_data[index]);
214    }
215}
216
217char& cmt_string::operator [] (int index)
218{
219  if ((_data == 0) ||
220      (index < 0) ||
221      (index >= _size))
222    {
223      static char temp;
224      return (temp);
225    }
226  else
227    {
228      return (_data[index]);
229    }
230}
231
232int cmt_string::size () const
233{
234  if (_data == 0) return (0);
235  return (_size);
236}
237
238int cmt_string::size ()
239{
240  if (_data == 0) return (0);
241  return (_size);
242}
243
244void cmt_string::resize (int n)
245{
246  _size = n;
247  allocate (n + 1);
248  _data[n] = 0;
249}
250
251int cmt_string::find (char c) const
252{
253  if (_data == 0) return (npos);
254
255  char* p = strchr (_data, c);
256  if (p == 0) return (npos);
257  return (p - _data);
258}
259
260int cmt_string::find (const char* text) const
261{
262  if (_data == 0) return (npos);
263  if (text == 0) return (npos);
264
265  char* p = strstr (_data, text);
266  if (p == 0) return (npos);
267  return (p - _data);
268}
269
270int cmt_string::find (const cmt_string& other) const
271{
272  const char* text = other._data;
273  return (find (text));
274}
275
276int cmt_string::find (int pos, char c) const
277{
278  if (_data == 0) return (npos);
279  if (pos < 0) return (npos);
280  if (pos >= _size) return (npos);
281
282  char* p = strchr (&_data[pos], c);
283  if (p == 0) return (npos);
284  return (p - _data);
285}
286
287int cmt_string::find (int pos, const char* text) const
288{
289  if (_data == 0) return (npos);
290  if (text == 0) return (npos);
291  if (pos < 0) return (npos);
292  if (pos >= _size) return (npos);
293
294  char* p = strstr (&_data[pos], text);
295  if (p == 0) return (npos);
296  return (p - _data);
297}
298
299int cmt_string::find (int pos, const cmt_string& other) const
300{
301  const char* text = other._data;
302  return (find (pos, text));
303}
304
305int cmt_string::find_last_of (char c) const
306{
307  if (_data == 0) return (npos);
308
309  char* p = strrchr (_data, c);
310  if (p == 0) return (npos);
311  return (p - _data);
312}
313
314int cmt_string::find_last_of (const char* text) const
315{
316  if (_data == 0) return (npos);
317  if (text == 0) return (npos);
318
319  char* ptr = _data;
320  char* last = 0;
321  char* p;
322  while ((p = strstr (ptr, text)) != 0)
323    {
324      last = p;
325      ptr = p + 1;
326    }
327  if (last == 0) return (npos);
328  return (last - _data);
329}
330
331int cmt_string::find_last_of (const cmt_string& other) const
332{
333  const char* text = other._data;
334  return (find_last_of (text));
335}
336
337void cmt_string::erase (int pos)
338{
339  if ((_data == 0) ||
340      (pos < 0) ||
341      (pos >= _size))
342    {
343      return;
344    }
345  else
346    {
347      _data[pos] = 0;
348      _size = pos;
349    }
350}
351
352void cmt_string::erase (int pos, int length)
353{
354  if ((_data == 0) ||
355      (pos < 0) ||
356      (pos >= _size))
357    {
358      return;
359    }
360  else
361    {
362      if ((pos + length) >= _size)
363        {
364          _data[pos] = 0;
365          _size = pos;
366        }
367      else if (length > 0)
368        {
369          char* d = &_data[pos];
370          char* s = &_data[pos + length];
371          for (;;)
372            {
373              *d = *s;
374              if (*s == 0) break;
375              d++;
376              s++;
377            }
378          _size -= length;
379        }
380    }
381}
382
383
384void cmt_string::replace (const char* pattern, const char* replacement)
385{
386  if (_data == 0) return;
387  if (_size == 0) return;
388  if (pattern == 0) return;
389
390  if (replacement == 0) replacement = "";
391
392  if (pattern[0] == 0) return;
393
394  int pattern_length = strlen (pattern);
395
396  int replacement_length = strlen (replacement);
397  int delta = replacement_length - pattern_length;
398
399  int pos;
400
401  if ((pos = find (pattern)) != npos)
402    {
403      if (delta > 0)
404        {
405            // string will be enlarged
406          extend (delta);
407
408          char* src = &_data[_size];
409          char* dest = src + delta;
410          while (src > &_data[pos])
411            {
412              *dest = *src;
413              src--;
414              dest--;
415            }
416        }
417      else if (delta < 0)
418        {
419            // string will be shortened
420
421          char* src = &_data[pos + pattern_length];
422          char* dest = src + delta;
423          while (*src != 0)
424            {
425              *dest = *src;
426              src++;
427              dest++;
428            }
429          *dest = *src;
430        }
431
432      strncpy (&_data[pos], replacement, replacement_length);
433
434      _size += delta;
435    }
436}
437
438void cmt_string::replace (const cmt_string& pattern,
439                          const cmt_string& replacement)
440{
441  const char* p_text = pattern._data;
442  const char* r_text = replacement._data;
443  cmt_string& me = *this;
444
445  me.replace (p_text, r_text);
446}
447
448void cmt_string::replace_all (const char* pattern, const char* replacement)
449{
450  if (_data == 0) return;
451  if (_size == 0) return;
452  if (pattern == 0) return;
453
454  if (replacement == 0) replacement = "";
455
456  if (pattern[0] == 0) return;
457
458  int pattern_length = strlen (pattern);
459
460  int replacement_length = strlen (replacement);
461  int delta = replacement_length - pattern_length;
462
463  int pos = 0;
464
465  while ((pos = find (pos, pattern)) != npos)
466    {
467      if (delta > 0)
468        {
469            // string will be enlarged
470          extend (delta);
471
472          char* src = &_data[_size];
473          char* dest = src + delta;
474          while (src > &_data[pos])
475            {
476              *dest = *src;
477              src--;
478              dest--;
479            }
480        }
481      else if (delta < 0)
482        {
483            // string will be shortened
484
485          char* src = &_data[pos + pattern_length];
486          char* dest = src + delta;
487          while (*src != 0)
488            {
489              *dest = *src;
490              src++;
491              dest++;
492            }
493          *dest = *src;
494        }
495
496      strncpy (&_data[pos], replacement, replacement_length);
497      pos += replacement_length;
498      _size += delta;
499    }
500}
501
502void cmt_string::replace_all (const cmt_string& pattern,
503                              const cmt_string& replacement)
504{
505  const char* p_text = pattern._data;
506  const char* r_text = replacement._data;
507  cmt_string& me = *this;
508
509  me.replace_all (p_text, r_text);
510}
511
512void cmt_string::trim ()
513{
514  if (size () == 0) return;
515
516  int i = 0;
517
518  i = strspn (_data, " \t");
519  if (i > 0) erase (0, i);
520
521  for (i = _size - 1; i >= 0; i--)
522    {
523      char c = _data[i];
524      if ((c == ' ') || (c == '\t')) continue;
525      erase (i + 1);
526      break;
527    }
528}
529
530cmt_string cmt_string::substr (int pos) const
531{
532  if ((_data == 0) ||
533      (pos < 0) ||
534      (pos >= _size))
535    {
536      return ((cmt_string) "");
537    }
538  else
539    {
540      return ((cmt_string) &_data[pos]);
541    }
542}
543
544cmt_string cmt_string::substr (int pos, int length) const
545{
546  if ((_data == 0) ||
547      (pos < 0) ||
548      (pos >= _size) ||
549      length == 0)
550    {
551      return ((cmt_string) "");
552    }
553  else
554    {
555      //      cerr << "|cmt_string::substr>: `" << *this << "' pos: " << pos << " length: " << length;
556
557      if ((pos + length) >= _size ||
558          length < 0)
559        {
560          //      cmt_string result (&_data[pos]);
561          //cerr << " |---> `" << result << "'" << endl;
562          //      return (result);
563          return (&_data[pos]);
564        }
565      else
566        {
567          cmt_string result;
568          result.resize (length);
569          for (int i = 0; i < length; i++)
570            result[i] = _data[pos + i];
571          //cerr << " |---> `" << result << "'" << endl;
572          return (result);
573        }
574
575      /*
576      cmt_string result (&_data[pos]);
577      result.erase (length);
578      cerr << " |---> `" << result << "'" << endl;
579      return (result);
580      */
581    }
582}
583
584void cmt_string::substr (int pos, cmt_string& dest) const
585{
586  if ((_data == 0) ||
587      (pos < 0) ||
588      (pos >= _size))
589    {
590      dest = "";
591    }
592  else
593    {
594      dest = (const char*) &_data[pos];
595    }
596}
597
598void cmt_string::substr (int pos, int length, cmt_string& dest) const
599{
600  if ((_data == 0) ||
601      (pos < 0) ||
602      (pos >= _size) ||
603      length == 0)
604    {
605      dest = "";
606    }
607  else
608    {
609      //      cerr << "|void cmt_string::substr>: `" << *this << "' pos: " << pos << " length: " << length;
610
611      if ((pos + length) >= _size ||
612          length < 0)
613        {
614          dest = (const char*) &_data[pos];
615        }
616      else
617        {
618          dest.resize (length);
619          for (int i = 0; i < length; i++)
620            dest[i] = _data[pos + i];
621        }
622
623      /*
624      dest = (const char*) &_data[pos];
625      dest.erase (length);
626      */
627      //      cerr << " |---> `" << dest << "'" << endl;
628    }
629}
630
631bool cmt_string::operator < (const char* text) const
632{
633  if (text == 0) return (false);
634  if (_data == 0) return (false);
635
636  if (strcmp (_data, text) < 0) return (true);
637  return (false);
638}
639
640bool cmt_string::operator < (const cmt_string& other) const
641{
642  const char* text = other._data;
643  const cmt_string& me = *this;
644
645  return (me < text);
646}
647
648bool cmt_string::operator == (const char* text) const
649{
650  if (text == 0)
651    {
652      if (_data == 0) return (true);
653      if (_size == 0) return (true);
654      return (false);
655    }
656  if (_data == 0)
657    {
658      if (text == 0) return (true);
659      if (text[0] == 0) return (true);
660      return (false);
661    }
662
663  if (strcmp (_data, text) == 0) return (true);
664  return (false);
665}
666
667bool cmt_string::operator == (const cmt_string& other) const
668{
669  const char* text = other._data;
670  const cmt_string& me = *this;
671
672  return (me == text);
673}
674
675bool cmt_string::operator != (const char* text) const
676{
677  const cmt_string& me = *this;
678
679  if (!(me == text)) return (true);
680  return (false);
681}
682
683bool cmt_string::operator != (const cmt_string& other) const
684{
685  const char* text = other._data;
686  const cmt_string& me = *this;
687
688  return (me != text);
689}
690
691bool cmt_string::operator > (const char* text) const
692{
693  if (text == 0) return (false);
694  if (_data == 0) return (false);
695
696  if (strcmp (_data, text) > 0) return (true);
697  return (false);
698}
699
700bool cmt_string::operator > (const cmt_string& other) const
701{
702  const char* text = other._data;
703  const cmt_string& me = *this;
704
705  return (me > text);
706}
707
708void cmt_string::extend (int n)
709{
710  if (_data != 0) n += _size;
711  allocate (n);
712}
713
714void cmt_string::allocate (int n)
715{
716  if ((n + 1) > _allocated)
717    {
718      static const int quantum = 128;
719      int frames = ((n + 1)/quantum) + 1;
720      _allocated = frames * quantum;
721
722#ifdef CMT_USE_NEW_DELETE
723      char* new_data = new char [_allocated + 1];
724#else
725      char* new_data = (char*) malloc (_allocated + 1);
726#endif
727
728
729      if (_data != 0)
730        {
731          strcpy (new_data, _data);
732
733#ifdef CMT_USE_NEW_DELETE
734          delete[] _data;
735#else
736          free (_data);
737#endif
738
739          _data = new_data;
740        }
741      else
742        {
743          new_data[0] = 0;
744        }
745
746      _data = new_data;
747    }
748}
749
750ostream& operator << (ostream& o, const cmt_string& s)
751{
752  o << (const char*) s;
753  return (o);
754}
755
756cmt_string operator + (const char* text, const cmt_string& s)
757{
758  cmt_string result = text;
759  result += s;
760  return (result);
761}
762
763cmt_string operator + (char c, const cmt_string& s)
764{
765  cmt_string result = c;
766  result += s;
767  return (result);
768}
769
770bool cmt_string::read (const cmt_string& file_name)
771{
772  FILE* f = fopen (file_name.c_str (), "rb");
773  if (f != NULL)
774    {
775      fseek (f, 0L, SEEK_END);
776      int size = ftell (f);
777      fseek (f, 0L, SEEK_SET);
778
779      allocate (size + 1);
780
781      fread (&_data[0], size, 1, f);
782
783      _data[size] = 0;
784      _size = size;
785
786      fclose (f);
787
788      return (true);
789    }
790  else
791    {
792      cmt_string& me = *this;
793      me = "";
794
795      return (false);
796    }
797}
798
799bool cmt_string::write (const cmt_string& file_name) const
800{
801  FILE* f = fopen (file_name.c_str (), "wb");
802  if (f != NULL)
803    {
804      write (f);
805      if (ferror (f))
806        return (false);
807      if (fclose (f))
808        return (false);
809      return (true);
810    }
811  else
812    {
813      return (false);
814    }
815}
816
817void cmt_string::write (FILE* f) const
818{
819  fwrite (&_data[0], size (), 1, f);
820}
821
822void cmt_string::write (ostream& output)
823{
824  output.write (&_data[0], size ());
825}
826
Note: See TracBrowser for help on using the repository browser.