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

Last change on this file since 663 was 663, checked in by rybkin, 10 years ago

See C.L. 522

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