Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cmt_string.cxx

Go to the documentation of this file.
00001 //-----------------------------------------------------------
00002 // Copyright Christian Arnault LAL-Orsay CNRS
00003 // arnault@lal.in2p3.fr
00004 // See the complete license in cmt_license.txt "http://www.cecill.info". 
00005 //-----------------------------------------------------------
00006 
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include "cmt_std.h"
00010 #include "cmt_string.h"
00011 
00012 cmt_string::cmt_string ()
00013 {
00014   _data = 0;
00015   _allocated = 0;
00016   _size = 0;
00017 }
00018 
00019 cmt_string::cmt_string (int n)
00020 {
00021   _data = 0;
00022   _allocated = 0;
00023   _size = 0;
00024   allocate (n + 1);
00025 }
00026 
00027 cmt_string::cmt_string (char c)
00028 {
00029   _data = 0;
00030   _allocated = 0;
00031   _size = 0;
00032 
00033   allocate (2);
00034 
00035   _data[0] = c;
00036   _data[1] = 0;
00037   _size = 1;
00038 }
00039 
00040 cmt_string::cmt_string (const char* text)
00041 {
00042   _data = 0;
00043   _allocated = 0;
00044   _size = 0;
00045 
00046   if (text != 0)
00047     {
00048       _size = strlen (text);
00049       allocate (_size + 1);
00050       strcpy (_data, text);
00051     }
00052 }
00053 
00054 cmt_string::cmt_string (const cmt_string& other)
00055 {
00056   const char* text = other._data;
00057 
00058   _data = 0;
00059   _allocated = 0;
00060   _size = 0;
00061 
00062   if (text != 0)
00063     {
00064       _size = strlen (text);
00065       allocate (_size + 1);
00066       strcpy (_data, text);
00067     }
00068 }
00069 
00070 cmt_string::~cmt_string ()
00071 {
00072   if (_data != 0)
00073     {
00074 #ifdef CMT_USE_NEW_DELETE
00075       delete[] _data;
00076 #else
00077       free (_data);
00078 #endif
00079     }
00080   _data = 0;
00081   _allocated = 0;
00082   _size = 0;
00083 }
00084 
00085   //
00086   // Operators
00087   //
00088 cmt_string& cmt_string::operator = (char c)
00089 {
00090   allocate (2);
00091 
00092   _data[0] = c;
00093   _data[1] = 0;
00094 
00095   _size = 1;
00096 
00097   return (*this);
00098 }
00099 
00100 cmt_string& cmt_string::operator = (const char* text)
00101 {
00102   if (text == _data) return (*this);
00103 
00104   if (text != 0)
00105     {
00106       _size = strlen (text);
00107       allocate (_size + 1);
00108       strcpy (_data, text);
00109     }
00110   else
00111     {
00112       _size = 0;
00113 
00114       if (_data != 0)
00115         {
00116           _data[0] = 0;
00117         }
00118     }
00119 
00120   return (*this);
00121 }
00122 
00123 cmt_string& cmt_string::operator = (const cmt_string& other)
00124 {
00125   const char* text = other._data;
00126   cmt_string& me = *this;
00127   me = text;
00128   return (me);
00129 }
00130 
00131 cmt_string::operator const char* () const
00132 {
00133   if (_data == 0) return ("");
00134   else return (_data);
00135 }
00136 
00137 const char* cmt_string::c_str () const
00138 {
00139   if (_data == 0) return ("");
00140   else return (_data);
00141 }
00142 
00143 /*
00144 char* cmt_string::c_str ()
00145 {
00146   return (_data);
00147 }
00148 */
00149 
00150 void cmt_string::operator += (char c)
00151 {
00152   extend (2);
00153 
00154   char temp[2] = { c, 0 };
00155 
00156   strcat (&_data[_size], temp);
00157   _size++;
00158 }
00159 
00160 void cmt_string::operator += (const char* text)
00161 {
00162   if (text == 0) return;
00163 
00164   int s = strlen (text);
00165   extend (s + 1);
00166 
00167   strcat (&_data[_size], text);
00168   _size += s;
00169 }
00170 
00171 void cmt_string::operator += (const cmt_string& other)
00172 {
00173   const char* text = other._data;
00174   cmt_string& me = *this;
00175 
00176   me += text;
00177 }
00178 
00179 cmt_string cmt_string::operator + (char c) const
00180 {
00181   cmt_string result (_data);
00182   result += c;
00183 
00184   return (result);
00185 }
00186 
00187 cmt_string cmt_string::operator + (const char* text) const
00188 {
00189   cmt_string result (_data);
00190   result += text;
00191 
00192   return (result);
00193 }
00194 
00195 cmt_string cmt_string::operator + (const cmt_string& other) const
00196 {
00197   cmt_string result (_data);
00198   result += other;
00199 
00200   return (result);
00201 }
00202 
00203 char cmt_string::operator [] (int index) const
00204 {
00205   if ((_data == 0) ||
00206       (index < 0) ||
00207       (index >= _size))
00208     {
00209       return (0);
00210     }
00211   else
00212     {
00213       return (_data[index]);
00214     }
00215 }
00216 
00217 char& cmt_string::operator [] (int index)
00218 {
00219   if ((_data == 0) ||
00220       (index < 0) ||
00221       (index >= _size))
00222     {
00223       static char temp;
00224       return (temp);
00225     }
00226   else
00227     {
00228       return (_data[index]);
00229     }
00230 }
00231 
00232 int cmt_string::size () const
00233 {
00234   if (_data == 0) return (0);
00235   return (_size);
00236 }
00237 
00238 int cmt_string::size ()
00239 {
00240   if (_data == 0) return (0);
00241   return (_size);
00242 }
00243 
00244 void cmt_string::resize (int n)
00245 {
00246   allocate (n + 1);
00247 }
00248 
00249 int cmt_string::find (char c) const
00250 {
00251   if (_data == 0) return (npos);
00252 
00253   char* p = strchr (_data, c);
00254   if (p == 0) return (npos);
00255   return (p - _data);
00256 }
00257 
00258 int cmt_string::find (const char* text) const
00259 {
00260   if (_data == 0) return (npos);
00261   if (text == 0) return (npos);
00262 
00263   char* p = strstr (_data, text);
00264   if (p == 0) return (npos);
00265   return (p - _data);
00266 }
00267 
00268 int cmt_string::find (const cmt_string& other) const
00269 {
00270   const char* text = other._data;
00271   return (find (text));
00272 }
00273 
00274 int cmt_string::find (int pos, char c) const
00275 {
00276   if (_data == 0) return (npos);
00277   if (pos < 0) return (npos);
00278   if (pos >= _size) return (npos);
00279 
00280   char* p = strchr (&_data[pos], c);
00281   if (p == 0) return (npos);
00282   return (p - _data);
00283 }
00284 
00285 int cmt_string::find (int pos, const char* text) const
00286 {
00287   if (_data == 0) return (npos);
00288   if (text == 0) return (npos);
00289   if (pos < 0) return (npos);
00290   if (pos >= _size) return (npos);
00291 
00292   char* p = strstr (&_data[pos], text);
00293   if (p == 0) return (npos);
00294   return (p - _data);
00295 }
00296 
00297 int cmt_string::find (int pos, const cmt_string& other) const
00298 {
00299   const char* text = other._data;
00300   return (find (pos, text));
00301 }
00302 
00303 int cmt_string::find_last_of (char c) const
00304 {
00305   if (_data == 0) return (npos);
00306 
00307   char* p = strrchr (_data, c);
00308   if (p == 0) return (npos);
00309   return (p - _data);
00310 }
00311 
00312 int cmt_string::find_last_of (const char* text) const
00313 {
00314   if (_data == 0) return (npos);
00315   if (text == 0) return (npos);
00316 
00317   char* ptr = _data;
00318   char* last = 0;
00319   char* p;
00320   while ((p = strstr (ptr, text)) != 0)
00321     {
00322       last = p;
00323       ptr = p + 1;
00324     }
00325   if (last == 0) return (npos);
00326   return (last - _data);
00327 }
00328 
00329 int cmt_string::find_last_of (const cmt_string& other) const
00330 {
00331   const char* text = other._data;
00332   return (find_last_of (text));
00333 }
00334 
00335 void cmt_string::erase (int pos)
00336 {
00337   if ((_data == 0) ||
00338       (pos < 0) ||
00339       (pos >= _size))
00340     {
00341       return;
00342     }
00343   else
00344     {
00345       _data[pos] = 0;
00346       _size = pos;
00347     }
00348 }
00349 
00350 void cmt_string::erase (int pos, int length)
00351 {
00352   if ((_data == 0) ||
00353       (pos < 0) ||
00354       (pos >= _size))
00355     {
00356       return;
00357     }
00358   else
00359     {
00360       if ((pos + length) >= _size)
00361         {
00362           _data[pos] = 0;
00363           _size = pos;
00364         }
00365       else if (length > 0)
00366         {
00367           char* d = &_data[pos];
00368           char* s = &_data[pos + length];
00369           for (;;)
00370             {
00371               *d = *s;
00372               if (*s == 0) break;
00373               d++;
00374               s++;
00375             }
00376           _size -= length;
00377         }
00378     }
00379 }
00380 
00381 
00382 void cmt_string::replace (const char* pattern, const char* replacement)
00383 {
00384   if (_data == 0) return;
00385   if (_size == 0) return;
00386   if (pattern == 0) return;
00387 
00388   if (replacement == 0) replacement = "";
00389 
00390   if (pattern[0] == 0) return;
00391 
00392   int pattern_length = strlen (pattern);
00393 
00394   int replacement_length = strlen (replacement);
00395   int delta = replacement_length - pattern_length;
00396 
00397   int pos;
00398 
00399   if ((pos = find (pattern)) != npos)
00400     {
00401       if (delta > 0)
00402         {
00403             // string will be enlarged
00404           extend (delta);
00405 
00406           char* src = &_data[_size];
00407           char* dest = src + delta;
00408           while (src > &_data[pos])
00409             {
00410               *dest = *src;
00411               src--;
00412               dest--;
00413             }
00414         }
00415       else if (delta < 0)
00416         {
00417             // string will be shortened
00418 
00419           char* src = &_data[pos + pattern_length];
00420           char* dest = src + delta;
00421           while (*src != 0)
00422             {
00423               *dest = *src;
00424               src++;
00425               dest++;
00426             }
00427           *dest = *src;
00428         }
00429 
00430       strncpy (&_data[pos], replacement, replacement_length);
00431 
00432       _size += delta;
00433     }
00434 }
00435 
00436 void cmt_string::replace (const cmt_string& pattern,
00437                           const cmt_string& replacement)
00438 {
00439   const char* p_text = pattern._data;
00440   const char* r_text = replacement._data;
00441   cmt_string& me = *this;
00442 
00443   me.replace (p_text, r_text);
00444 }
00445 
00446 void cmt_string::replace_all (const char* pattern, const char* replacement)
00447 {
00448   if (_data == 0) return;
00449   if (_size == 0) return;
00450   if (pattern == 0) return;
00451 
00452   if (replacement == 0) replacement = "";
00453 
00454   if (pattern[0] == 0) return;
00455 
00456   int pattern_length = strlen (pattern);
00457 
00458   int replacement_length = strlen (replacement);
00459   int delta = replacement_length - pattern_length;
00460 
00461   int pos = 0;
00462 
00463   while ((pos = find (pos, pattern)) != npos)
00464     {
00465       if (delta > 0)
00466         {
00467             // string will be enlarged
00468           extend (delta);
00469 
00470           char* src = &_data[_size];
00471           char* dest = src + delta;
00472           while (src > &_data[pos])
00473             {
00474               *dest = *src;
00475               src--;
00476               dest--;
00477             }
00478         }
00479       else if (delta < 0)
00480         {
00481             // string will be shortened
00482 
00483           char* src = &_data[pos + pattern_length];
00484           char* dest = src + delta;
00485           while (*src != 0)
00486             {
00487               *dest = *src;
00488               src++;
00489               dest++;
00490             }
00491           *dest = *src;
00492         }
00493 
00494       strncpy (&_data[pos], replacement, replacement_length);
00495       pos += replacement_length;
00496       _size += delta;
00497     }
00498 }
00499 
00500 void cmt_string::replace_all (const cmt_string& pattern,
00501                               const cmt_string& replacement)
00502 {
00503   const char* p_text = pattern._data;
00504   const char* r_text = replacement._data;
00505   cmt_string& me = *this;
00506 
00507   me.replace_all (p_text, r_text);
00508 }
00509 
00510 void cmt_string::trim ()
00511 {
00512   if (size () == 0) return;
00513 
00514   int i = 0;
00515 
00516   i = strspn (_data, " \t");
00517   if (i > 0) erase (0, i);
00518 
00519   for (i = _size - 1; i >= 0; i--)
00520     {
00521       char c = _data[i];
00522       if ((c == ' ') || (c == '\t')) continue;
00523       erase (i + 1);
00524       break;
00525     }
00526 }
00527 
00528 cmt_string cmt_string::substr (int pos) const
00529 {
00530   if ((_data == 0) ||
00531       (pos < 0) ||
00532       (pos >= _size))
00533     {
00534       return ((cmt_string) "");
00535     }
00536   else
00537     {
00538       return ((cmt_string) &_data[pos]);
00539     }
00540 }
00541 
00542 cmt_string cmt_string::substr (int pos, int length) const
00543 {
00544   if ((_data == 0) ||
00545       (pos < 0) ||
00546       (pos >= _size))
00547     {
00548       return ((cmt_string) "");
00549     }
00550   else
00551     {
00552       cmt_string result (&_data[pos]);
00553       result.erase (length);
00554       return (result);
00555     }
00556 }
00557 
00558 void cmt_string::substr (int pos, cmt_string& dest) const
00559 {
00560   if ((_data == 0) ||
00561       (pos < 0) ||
00562       (pos >= _size))
00563     {
00564       dest = "";
00565     }
00566   else
00567     {
00568       dest = (const char*) &_data[pos];
00569     }
00570 }
00571 
00572 void cmt_string::substr (int pos, int length, cmt_string& dest) const
00573 {
00574   if ((_data == 0) ||
00575       (pos < 0) ||
00576       (pos >= _size))
00577     {
00578       dest = "";
00579     }
00580   else
00581     {
00582       dest = (const char*) &_data[pos];
00583       dest.erase (length);
00584     }
00585 }
00586 
00587 bool cmt_string::operator < (const char* text) const
00588 {
00589   if (text == 0) return (false);
00590   if (_data == 0) return (false);
00591 
00592   if (strcmp (_data, text) < 0) return (true);
00593   return (false);
00594 }
00595 
00596 bool cmt_string::operator < (const cmt_string& other) const
00597 {
00598   const char* text = other._data;
00599   const cmt_string& me = *this;
00600 
00601   return (me < text);
00602 }
00603 
00604 bool cmt_string::operator == (const char* text) const
00605 {
00606   if (text == 0)
00607     {
00608       if (_data == 0) return (true);
00609       if (_size == 0) return (true);
00610       return (false);
00611     }
00612   if (_data == 0)
00613     {
00614       if (text == 0) return (true);
00615       if (text[0] == 0) return (true);
00616       return (false);
00617     }
00618 
00619   if (strcmp (_data, text) == 0) return (true);
00620   return (false);
00621 }
00622 
00623 bool cmt_string::operator == (const cmt_string& other) const
00624 {
00625   const char* text = other._data;
00626   const cmt_string& me = *this;
00627 
00628   return (me == text);
00629 }
00630 
00631 bool cmt_string::operator != (const char* text) const
00632 {
00633   const cmt_string& me = *this;
00634 
00635   if (!(me == text)) return (true);
00636   return (false);
00637 }
00638 
00639 bool cmt_string::operator != (const cmt_string& other) const
00640 {
00641   const char* text = other._data;
00642   const cmt_string& me = *this;
00643 
00644   return (me != text);
00645 }
00646 
00647 bool cmt_string::operator > (const char* text) const
00648 {
00649   if (text == 0) return (false);
00650   if (_data == 0) return (false);
00651 
00652   if (strcmp (_data, text) > 0) return (true);
00653   return (false);
00654 }
00655 
00656 bool cmt_string::operator > (const cmt_string& other) const
00657 {
00658   const char* text = other._data;
00659   const cmt_string& me = *this;
00660 
00661   return (me > text);
00662 }
00663 
00664 void cmt_string::extend (int n)
00665 {
00666   if (_data != 0) n += _size;
00667   allocate (n);
00668 }
00669 
00670 void cmt_string::allocate (int n)
00671 {
00672   if ((n + 1) > _allocated)
00673     {
00674       static const int quantum = 128;
00675       int frames = ((n + 1)/quantum) + 1;
00676       _allocated = frames * quantum;
00677 
00678 #ifdef CMT_USE_NEW_DELETE
00679       char* new_data = new char [_allocated + 1];
00680 #else
00681       char* new_data = (char*) malloc (_allocated + 1);
00682 #endif
00683 
00684 
00685       if (_data != 0)
00686         {
00687           strcpy (new_data, _data);
00688 
00689 #ifdef CMT_USE_NEW_DELETE
00690           delete[] _data;
00691 #else
00692           free (_data);
00693 #endif
00694 
00695           _data = new_data;
00696         }
00697       else
00698         {
00699           new_data[0] = 0;
00700         }
00701 
00702       _data = new_data;
00703     }
00704 }
00705 
00706 ostream& operator << (ostream& o, const cmt_string& s)
00707 {
00708   o << (const char*) s;
00709   return (o);
00710 }
00711 
00712 cmt_string operator + (const char* text, const cmt_string& s)
00713 {
00714   cmt_string result = text;
00715   result += s;
00716   return (result);
00717 }
00718 
00719 cmt_string operator + (char c, const cmt_string& s)
00720 {
00721   cmt_string result = c;
00722   result += s;
00723   return (result);
00724 }
00725 
00726 bool cmt_string::read (const cmt_string& file_name)
00727 {
00728   FILE* f = fopen (file_name.c_str (), "rb");
00729   if (f != NULL)
00730     {
00731       fseek (f, 0L, SEEK_END);
00732       int size = ftell (f);
00733       fseek (f, 0L, SEEK_SET);
00734 
00735       allocate (size + 1);
00736 
00737       fread (&_data[0], size, 1, f);
00738 
00739       _data[size] = 0;
00740       _size = size;
00741 
00742       fclose (f);
00743 
00744       return (true);
00745     }
00746   else
00747     {
00748       cmt_string& me = *this;
00749       me = "";
00750 
00751       return (false);
00752     }
00753 }
00754 
00755 bool cmt_string::write (const cmt_string& file_name) const
00756 {
00757   FILE* f = fopen (file_name.c_str (), "wb");
00758   if (f != NULL)
00759     {
00760       write (f);
00761       fclose (f);
00762       return (true);
00763     }
00764   else
00765     {
00766       return (false);
00767     }
00768 }
00769 
00770 void cmt_string::write (FILE* f) const
00771 {
00772   fwrite (&_data[0], size (), 1, f);
00773 }
00774 
00775 void cmt_string::write (ostream& output)
00776 {
00777   output.write (&_data[0], size ());
00778 }
00779 

Generated on Mon May 2 10:25:05 2005 for CMT by doxygen 1.3.5