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