source: CMT/v1r25/source/cmt_string.cxx

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

See C.L. 485

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