00001
00002
00003
00004
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
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
00145
00146
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
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
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
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
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