//----------------------------------------------------------- // Copyright Christian Arnault LAL-Orsay CNRS // arnault@lal.in2p3.fr // See the complete license in cmt_license.txt "http://www.cecill.info". //----------------------------------------------------------- #include #include #include "cmt_std.h" #include "cmt_string.h" cmt_string::cmt_string () { _data = 0; _allocated = 0; _size = 0; } cmt_string::cmt_string (int n) { _data = 0; _allocated = 0; _size = 0; allocate (n + 1); } cmt_string::cmt_string (char c) { _data = 0; _allocated = 0; _size = 0; allocate (2); _data[0] = c; _data[1] = 0; _size = 1; } cmt_string::cmt_string (const char* text) { _data = 0; _allocated = 0; _size = 0; if (text != 0) { _size = strlen (text); allocate (_size + 1); strcpy (_data, text); } } cmt_string::cmt_string (const cmt_string& other) { const char* text = other._data; _data = 0; _allocated = 0; _size = 0; if (text != 0) { _size = strlen (text); allocate (_size + 1); strcpy (_data, text); } } cmt_string::~cmt_string () { if (_data != 0) { #ifdef CMT_USE_NEW_DELETE delete[] _data; #else free (_data); #endif } _data = 0; _allocated = 0; _size = 0; } // // Operators // cmt_string& cmt_string::operator = (char c) { allocate (2); _data[0] = c; _data[1] = 0; _size = 1; return (*this); } cmt_string& cmt_string::operator = (const char* text) { if (text == _data) return (*this); if (text != 0) { _size = strlen (text); allocate (_size + 1); strcpy (_data, text); } else { _size = 0; if (_data != 0) { _data[0] = 0; } } return (*this); } cmt_string& cmt_string::operator = (const cmt_string& other) { const char* text = other._data; cmt_string& me = *this; me = text; return (me); } cmt_string::operator const char* () const { if (_data == 0) return (""); else return (_data); } const char* cmt_string::c_str () const { if (_data == 0) return (""); else return (_data); } /* char* cmt_string::c_str () { return (_data); } */ void cmt_string::operator += (char c) { extend (2); char temp[2] = { c, 0 }; strcat (&_data[_size], temp); _size++; } void cmt_string::operator += (const char* text) { if (text == 0) return; int s = strlen (text); extend (s + 1); strcat (&_data[_size], text); _size += s; } void cmt_string::operator += (const cmt_string& other) { const char* text = other._data; cmt_string& me = *this; me += text; } cmt_string cmt_string::operator + (char c) const { cmt_string result (_data); result += c; return (result); } cmt_string cmt_string::operator + (const char* text) const { cmt_string result (_data); result += text; return (result); } cmt_string cmt_string::operator + (const cmt_string& other) const { cmt_string result (_data); result += other; return (result); } char cmt_string::operator [] (int index) const { if ((_data == 0) || (index < 0) || (index >= _size)) { return (0); } else { return (_data[index]); } } char& cmt_string::operator [] (int index) { if ((_data == 0) || (index < 0) || (index >= _size)) { static char temp; return (temp); } else { return (_data[index]); } } int cmt_string::size () const { if (_data == 0) return (0); return (_size); } int cmt_string::size () { if (_data == 0) return (0); return (_size); } void cmt_string::resize (int n) { allocate (n + 1); } int cmt_string::find (char c) const { if (_data == 0) return (npos); char* p = strchr (_data, c); if (p == 0) return (npos); return (p - _data); } int cmt_string::find (const char* text) const { if (_data == 0) return (npos); if (text == 0) return (npos); char* p = strstr (_data, text); if (p == 0) return (npos); return (p - _data); } int cmt_string::find (const cmt_string& other) const { const char* text = other._data; return (find (text)); } int cmt_string::find (int pos, char c) const { if (_data == 0) return (npos); if (pos < 0) return (npos); if (pos >= _size) return (npos); char* p = strchr (&_data[pos], c); if (p == 0) return (npos); return (p - _data); } int cmt_string::find (int pos, const char* text) const { if (_data == 0) return (npos); if (text == 0) return (npos); if (pos < 0) return (npos); if (pos >= _size) return (npos); char* p = strstr (&_data[pos], text); if (p == 0) return (npos); return (p - _data); } int cmt_string::find (int pos, const cmt_string& other) const { const char* text = other._data; return (find (pos, text)); } int cmt_string::find_last_of (char c) const { if (_data == 0) return (npos); char* p = strrchr (_data, c); if (p == 0) return (npos); return (p - _data); } int cmt_string::find_last_of (const char* text) const { if (_data == 0) return (npos); if (text == 0) return (npos); char* ptr = _data; char* last = 0; char* p; while ((p = strstr (ptr, text)) != 0) { last = p; ptr = p + 1; } if (last == 0) return (npos); return (last - _data); } int cmt_string::find_last_of (const cmt_string& other) const { const char* text = other._data; return (find_last_of (text)); } void cmt_string::erase (int pos) { if ((_data == 0) || (pos < 0) || (pos >= _size)) { return; } else { _data[pos] = 0; _size = pos; } } void cmt_string::erase (int pos, int length) { if ((_data == 0) || (pos < 0) || (pos >= _size)) { return; } else { if ((pos + length) >= _size) { _data[pos] = 0; _size = pos; } else if (length > 0) { char* d = &_data[pos]; char* s = &_data[pos + length]; for (;;) { *d = *s; if (*s == 0) break; d++; s++; } _size -= length; } } } void cmt_string::replace (const char* pattern, const char* replacement) { if (_data == 0) return; if (_size == 0) return; if (pattern == 0) return; if (replacement == 0) replacement = ""; if (pattern[0] == 0) return; int pattern_length = strlen (pattern); int replacement_length = strlen (replacement); int delta = replacement_length - pattern_length; int pos; if ((pos = find (pattern)) != npos) { if (delta > 0) { // string will be enlarged extend (delta); char* src = &_data[_size]; char* dest = src + delta; while (src > &_data[pos]) { *dest = *src; src--; dest--; } } else if (delta < 0) { // string will be shortened char* src = &_data[pos + pattern_length]; char* dest = src + delta; while (*src != 0) { *dest = *src; src++; dest++; } *dest = *src; } strncpy (&_data[pos], replacement, replacement_length); _size += delta; } } void cmt_string::replace (const cmt_string& pattern, const cmt_string& replacement) { const char* p_text = pattern._data; const char* r_text = replacement._data; cmt_string& me = *this; me.replace (p_text, r_text); } void cmt_string::replace_all (const char* pattern, const char* replacement) { if (_data == 0) return; if (_size == 0) return; if (pattern == 0) return; if (replacement == 0) replacement = ""; if (pattern[0] == 0) return; int pattern_length = strlen (pattern); int replacement_length = strlen (replacement); int delta = replacement_length - pattern_length; int pos = 0; while ((pos = find (pos, pattern)) != npos) { if (delta > 0) { // string will be enlarged extend (delta); char* src = &_data[_size]; char* dest = src + delta; while (src > &_data[pos]) { *dest = *src; src--; dest--; } } else if (delta < 0) { // string will be shortened char* src = &_data[pos + pattern_length]; char* dest = src + delta; while (*src != 0) { *dest = *src; src++; dest++; } *dest = *src; } strncpy (&_data[pos], replacement, replacement_length); pos += replacement_length; _size += delta; } } void cmt_string::replace_all (const cmt_string& pattern, const cmt_string& replacement) { const char* p_text = pattern._data; const char* r_text = replacement._data; cmt_string& me = *this; me.replace_all (p_text, r_text); } void cmt_string::trim () { if (size () == 0) return; int i = 0; i = strspn (_data, " \t"); if (i > 0) erase (0, i); for (i = _size - 1; i >= 0; i--) { char c = _data[i]; if ((c == ' ') || (c == '\t')) continue; erase (i + 1); break; } } cmt_string cmt_string::substr (int pos) const { if ((_data == 0) || (pos < 0) || (pos >= _size)) { return ((cmt_string) ""); } else { return ((cmt_string) &_data[pos]); } } cmt_string cmt_string::substr (int pos, int length) const { if ((_data == 0) || (pos < 0) || (pos >= _size)) { return ((cmt_string) ""); } else { cmt_string result (&_data[pos]); result.erase (length); return (result); } } void cmt_string::substr (int pos, cmt_string& dest) const { if ((_data == 0) || (pos < 0) || (pos >= _size)) { dest = ""; } else { dest = (const char*) &_data[pos]; } } void cmt_string::substr (int pos, int length, cmt_string& dest) const { if ((_data == 0) || (pos < 0) || (pos >= _size)) { dest = ""; } else { dest = (const char*) &_data[pos]; dest.erase (length); } } bool cmt_string::operator < (const char* text) const { if (text == 0) return (false); if (_data == 0) return (false); if (strcmp (_data, text) < 0) return (true); return (false); } bool cmt_string::operator < (const cmt_string& other) const { const char* text = other._data; const cmt_string& me = *this; return (me < text); } bool cmt_string::operator == (const char* text) const { if (text == 0) { if (_data == 0) return (true); if (_size == 0) return (true); return (false); } if (_data == 0) { if (text == 0) return (true); if (text[0] == 0) return (true); return (false); } if (strcmp (_data, text) == 0) return (true); return (false); } bool cmt_string::operator == (const cmt_string& other) const { const char* text = other._data; const cmt_string& me = *this; return (me == text); } bool cmt_string::operator != (const char* text) const { const cmt_string& me = *this; if (!(me == text)) return (true); return (false); } bool cmt_string::operator != (const cmt_string& other) const { const char* text = other._data; const cmt_string& me = *this; return (me != text); } bool cmt_string::operator > (const char* text) const { if (text == 0) return (false); if (_data == 0) return (false); if (strcmp (_data, text) > 0) return (true); return (false); } bool cmt_string::operator > (const cmt_string& other) const { const char* text = other._data; const cmt_string& me = *this; return (me > text); } void cmt_string::extend (int n) { if (_data != 0) n += _size; allocate (n); } void cmt_string::allocate (int n) { if ((n + 1) > _allocated) { static const int quantum = 128; int frames = ((n + 1)/quantum) + 1; _allocated = frames * quantum; #ifdef CMT_USE_NEW_DELETE char* new_data = new char [_allocated + 1]; #else char* new_data = (char*) malloc (_allocated + 1); #endif if (_data != 0) { strcpy (new_data, _data); #ifdef CMT_USE_NEW_DELETE delete[] _data; #else free (_data); #endif _data = new_data; } else { new_data[0] = 0; } _data = new_data; } } ostream& operator << (ostream& o, const cmt_string& s) { o << (const char*) s; return (o); } cmt_string operator + (const char* text, const cmt_string& s) { cmt_string result = text; result += s; return (result); } cmt_string operator + (char c, const cmt_string& s) { cmt_string result = c; result += s; return (result); } bool cmt_string::read (const cmt_string& file_name) { FILE* f = fopen (file_name.c_str (), "rb"); if (f != NULL) { fseek (f, 0L, SEEK_END); int size = ftell (f); fseek (f, 0L, SEEK_SET); allocate (size + 1); fread (&_data[0], size, 1, f); _data[size] = 0; _size = size; fclose (f); return (true); } else { cmt_string& me = *this; me = ""; return (false); } } bool cmt_string::write (const cmt_string& file_name) const { FILE* f = fopen (file_name.c_str (), "wb"); if (f != NULL) { write (f); fclose (f); return (true); } else { return (false); } } void cmt_string::write (FILE* f) const { fwrite (&_data[0], size (), 1, f); } void cmt_string::write (ostream& output) { output.write (&_data[0], size ()); }