00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "StringBasics.h"
00019 #include "Error.h"
00020 #include "Constant.h"
00021 #include "MathConstant.h"
00022
00023 #include <string.h>
00024 #include <ctype.h>
00025 #include <stdarg.h>
00026
00027 #define SWP(A,B) {int tmp=a; a=b; b=tmp;}
00028
00029 #ifdef _MSC_VER
00030 #ifndef snprintf
00031 #define vsnprintf _vsnprintf
00032 #define snprintf _snprintf
00033 #endif
00034 #endif
00035
00036
00037
00038
00039
00040 #define NATURAL_ORDERING 1
00041
00042 int String::alloc = 8;
00043 bool String::caseSensitive = true;
00044
00045 void String::NewString(int startsize)
00046 {
00047 len = 0;
00048 size = (startsize + alloc) / alloc * alloc;
00049 buffer = new char [size];
00050 buffer[0] = 0;
00051 }
00052
00053 String::String(const char * s)
00054 {
00055 int clen = s == NULL ? 0 : strlen(s);
00056 NewString(clen);
00057 if (clen)
00058 {
00059 len = clen;
00060 memcpy(buffer, s, len + 1);
00061 }
00062 }
00063
00064 String::String(char ch, int count)
00065 {
00066 NewString(count);
00067 memset(buffer, ch, count);
00068 buffer[count] = 0;
00069 len = count;
00070 }
00071
00072 String::String(const String & s)
00073 {
00074 len = s.len;
00075 size = (s.len + alloc) / alloc * alloc;;
00076 buffer = new char [size];
00077 memcpy(buffer, s.buffer, len + 1);
00078 }
00079
00080 void String::Grow(int newSize)
00081 {
00082 if (newSize >= size)
00083 {
00084 if ((newSize >> 1) >= size)
00085 size = (newSize + alloc) / alloc * alloc;
00086 else
00087 {
00088 size = alloc;
00089 while (size <= newSize)
00090 size *= 2;
00091 }
00092
00093 char * tmp = new char [size];
00094 memcpy(tmp, buffer, len + 1);
00095 delete [] buffer;
00096 buffer = tmp;
00097 }
00098 }
00099
00100 void String::Swap(String & s)
00101 {
00102 char * temp = s.buffer;
00103 s.buffer = buffer;
00104 buffer = temp;
00105
00106 int swap = s.size;
00107 s.size = size;
00108 size = swap;
00109
00110 swap = s.len;
00111 s.len = len;
00112 len = swap;
00113 }
00114
00115 String & String::Copy(const String & s)
00116 {
00117 Grow(s.len);
00118 len = s.len;
00119 memcpy(buffer, s.buffer, len + 1);
00120 return *this;
00121 }
00122
00123 String & String::Copy(const String & s, int start, int n)
00124 {
00125 if (s.len <= start) return Clear();
00126 if (s.len < start + n) n = s.len - start;
00127 Grow(n);
00128 memcpy(buffer, s.buffer + start, n);
00129 buffer[len = n] = 0;
00130 return *this;
00131 }
00132
00133 String & String::Copy(const char * s)
00134 {
00135 if (s == NULL)
00136 {
00137 len = 0;
00138 buffer[0] = 0;
00139 }
00140 else
00141 {
00142 int clen = strlen(s);
00143 Grow(clen);
00144 len = clen;
00145 memcpy(buffer, s, len + 1);
00146 }
00147 return *this;
00148 }
00149
00150 String & String::ToUpper()
00151 {
00152 for (int i = 0; i < len; i++)
00153 buffer[i] = (char) toupper(buffer[i]);
00154 return *this;
00155 }
00156
00157 String & String::ToLower()
00158 {
00159 for (int i = 0; i < len; i++)
00160 buffer[i] = (char) tolower(buffer[i]);
00161 return *this;
00162 }
00163
00164 String String::AsUpper()
00165 {
00166 String temp;
00167 temp = *this;
00168 return temp.ToUpper();
00169 }
00170
00171 String String::AsLower()
00172 {
00173 String temp;
00174 temp = *this;
00175 return temp.ToLower();
00176 }
00177
00178 String String::Capitalize()
00179 {
00180 String temp;
00181 temp = *this;
00182 temp.buffer[0] = (char) toupper(temp.buffer[0]);
00183 return temp;
00184 }
00185
00186 String & String::operator = (const String & rhs)
00187 {
00188 Copy(rhs);
00189 return *this;
00190 }
00191
00192 String & String::operator = (const char * rhs)
00193 {
00194 Copy(rhs);
00195 return * this;
00196 }
00197
00198 String & String::operator += (const String & rhs)
00199 {
00200 Grow(len + rhs.len);
00201 memcpy(buffer + len, rhs.buffer, rhs.len + 1);
00202 len += rhs.len;
00203 return *this;
00204 }
00205
00206 String & String::operator += (const char * rhs)
00207 {
00208 if (rhs != NULL)
00209 {
00210 int clen = strlen(rhs);
00211 Grow(len + clen);
00212 memcpy(buffer + len, rhs, clen + 1);
00213 len += clen;
00214 }
00215 return *this;
00216 }
00217
00218 String String::operator + (const String & rhs) const
00219 {
00220 String result(len + rhs.len);
00221 memcpy(result.buffer, buffer, len);
00222 memcpy(result.buffer + len, rhs.buffer, rhs.len + 1);
00223 result.len = len + rhs.len;
00224 return result;
00225 }
00226
00227 String String::operator + (const char * rhs) const
00228 {
00229 if (rhs != NULL)
00230 {
00231 int clen = strlen(rhs);
00232 String result(len + clen);
00233 memcpy(result.buffer, buffer, len);
00234 memcpy(result.buffer + len, rhs, clen + 1);
00235 result.len = len + clen;
00236 return result;
00237 }
00238 return *this;
00239 }
00240
00241 String & String::operator = (char ch)
00242 {
00243 if (ch)
00244 {
00245 Grow(1);
00246 buffer[0] = ch;
00247 buffer[1] = 0;
00248 len = 1;
00249 }
00250 else
00251 len = buffer[0] = 0;
00252 return *this;
00253 }
00254
00255 String & String::operator += (char ch)
00256 {
00257 if (ch)
00258 {
00259 Grow(len + 1);
00260 buffer[len] = ch;
00261 buffer[++len] = 0;
00262 }
00263 return *this;
00264 }
00265
00266 String String::operator + (char ch) const
00267 {
00268 String result(*this);
00269 result += ch;
00270 return result;
00271 }
00272
00273 String & String::operator = (int rhs)
00274 {
00275 Clear();
00276
00277 if (rhs < 0)
00278 {
00279 Add('-');
00280 *this += (unsigned int) -rhs;
00281 }
00282 else
00283 *this = (unsigned int) rhs;
00284 return *this;
00285 }
00286
00287 String & String::operator = (unsigned int rhs)
00288 {
00289 Clear();
00290
00291 unsigned long base = 10;
00292 int digits = 1;
00293
00294 while (rhs >= base)
00295 {
00296 base *= 10;
00297 digits++;
00298 }
00299
00300 Grow(digits);
00301
00302 while (base /= 10)
00303 {
00304 char ch = char(rhs / base);
00305 rhs = rhs - ch * base;
00306 buffer[len++] = char(ch + '0');
00307 }
00308 buffer[len] = 0;
00309 return *this;
00310 };
00311
00312 String String::operator + (int rhs) const
00313 {
00314 String result(*this);
00315 result += rhs;
00316 return result;
00317 };
00318
00319 String String::operator + (unsigned int rhs) const
00320 {
00321 String result(*this);
00322 result += rhs;
00323 return result;
00324 };
00325
00326 String & String::operator += (int rhs)
00327 {
00328 String temp;
00329 temp = rhs;
00330 return *this += temp;
00331 }
00332
00333 String & String::operator += (unsigned int rhs)
00334 {
00335 String temp;
00336 temp = rhs;
00337 return *this += temp;
00338 }
00339
00340 String & String::operator *= (unsigned int rhs)
00341 {
00342 if (rhs == 0)
00343 Clear();
00344 else
00345 {
00346 String original(*this);
00347
00348 Grow(len * rhs);
00349
00350 for (unsigned int i = 1; i < rhs; i++)
00351 *this += original;
00352 }
00353 return *this;
00354 }
00355
00356 String & String::operator = (double rhs)
00357 {
00358 LockBuffer(32);
00359 sprintf(buffer, "%.3f", rhs);
00360 UnlockBuffer();
00361 return *this;
00362 }
00363
00364 String String::operator + (double rhs) const
00365 {
00366 String result(*this);
00367 result += rhs;
00368 return result;
00369 }
00370
00371 String & String::operator += (double rhs)
00372 {
00373 String temp;
00374 temp = rhs;
00375 return *this += temp;
00376 }
00377
00378 char * String::LockBuffer(int min)
00379 {
00380 if (min > 0) Grow(min);
00381 return buffer;
00382 }
00383
00384 String & String::UnlockBuffer()
00385 {
00386 for (len = 0; len < size; len++)
00387 if (buffer[len] == 0)
00388 return *this;
00389 error("BasicString - direct access overflowed buffer");
00390 return *this;
00391 }
00392
00393 int String::Compare(const String & s) const
00394 {
00395 if (caseSensitive)
00396 return String::FastCompare(s);
00397 else
00398 return String::SlowCompare(s);
00399 }
00400
00401 int String::Compare(const char * s) const
00402 {
00403 return caseSensitive ? FastCompare(s) : SlowCompare(s);
00404 }
00405
00406 int String::FastCompare(const String & s) const
00407 {
00408 for (int i = 0; i <= len; i++)
00409 if (buffer[i] - s.buffer[i])
00410 {
00411 #ifdef NATURAL_ORDERING
00412 int d = i;
00413 while (isdigit(buffer[d]) && isdigit(s.buffer[d]))
00414 d++;
00415 if (isdigit(buffer[d]))
00416 return 1;
00417 if (isdigit(s.buffer[d]))
00418 return -1;
00419 #endif
00420 return buffer[i] - s.buffer[i];
00421 }
00422 return 0;
00423 }
00424
00425 int String::FastCompare(const char * s) const
00426 {
00427 if (s == NULL)
00428 return -len;
00429
00430 for (int i = 0; i <= len; i++)
00431 if (buffer[i] - s[i])
00432 {
00433 #ifdef NATURAL_ORDERING
00434 int d = i;
00435 while (isdigit(buffer[d]) && isdigit(s[d]))
00436 d++;
00437 if (isdigit(buffer[d]))
00438 return 1;
00439 if (isdigit(s[d]))
00440 return -1;
00441 #endif
00442 return buffer[i] - s[i];
00443 }
00444 return 0;
00445 }
00446
00447 int String::SlowCompare(const String & s) const
00448 {
00449 for (int i = 0; i <= len; i++)
00450 if (toupper(buffer[i]) - toupper(s.buffer[i]))
00451 {
00452 #ifdef NATURAL_ORDERING
00453 int d = i;
00454 while (isdigit(buffer[d]) && isdigit(s[d]))
00455 d++;
00456 if (isdigit(buffer[d]))
00457 return 1;
00458 if (isdigit(s.buffer[d]))
00459 return -1;
00460 #endif
00461 return toupper(buffer[i]) - toupper(s.buffer[i]);
00462 }
00463 return 0;
00464 }
00465
00466 int String::SlowCompare(const char * s) const
00467 {
00468 if (s == NULL)
00469 return -len;
00470
00471 for (int i = 0; i <= len; i++)
00472 if (toupper(buffer[i]) - toupper(s[i]))
00473 {
00474 #ifdef NATURAL_ORDERING
00475 int d = i;
00476 while (isdigit(buffer[d]) && isdigit(s[d]))
00477 d++;
00478 if (isdigit(buffer[d]))
00479 return 1;
00480 if (isdigit(s[d]))
00481 return -1;
00482 #endif
00483 return toupper(buffer[i]) - toupper(s[i]);
00484 }
00485 return 0;
00486 }
00487
00488 int String::ReadLine(FILE * f)
00489 {
00490 len = 0;
00491 buffer[len] = 0;
00492
00493 if (f == NULL) return -1;
00494
00495 int clen = 0;
00496 char check[2] = {0, 0};
00497
00498 int step = 128;
00499 String format("%128[^\n\r]%1[\n\r]");
00500
00501 int returnValue = 1;
00502
00503 while (check[0] != '\n' && check[0] != '\r')
00504 {
00505 if (clen)
00506 {
00507 step *= 2;
00508 format.printf("%%%d%s", step, "[^\n\r]%1[\n\r]");
00509 }
00510 clen += step;
00511
00512 int io = fscanf(f, format, LockBuffer(clen) + len, check);
00513 UnlockBuffer();
00514
00515 if (io == 0 && check[0] != '\n' && check[0] != '\r')
00516 fscanf(f, "%1[\n\r]", check);
00517 if (io == 0 || io == EOF)
00518 {
00519
00520 returnValue = -1;
00521 break;
00522 }
00523 }
00524
00525 if (check[0] == '\n') fscanf(f, "%*1[\r]");
00526 if (check[0] == '\r') fscanf(f, "%*1[\n]");
00527
00528 return returnValue;
00529 }
00530
00531
00532 String & String::Read(FILE * f)
00533 {
00534 len = 0;
00535 buffer[len] = 0;
00536
00537 if (f == NULL) return *this;
00538
00539 int clen = 0;
00540 char check[2] = {'G', 0};
00541
00542 while (strchr(WHITESPACE, check[0]) == NULL)
00543 {
00544 clen += READBUF;
00545 int io = fscanf(f, " %" READBUFSTR "[^" WHITESPACE "]"
00546 "%1[" WHITESPACE "]", LockBuffer(clen) + len, check);
00547 if (io == 0 || io == EOF) break;
00548 UnlockBuffer();
00549 }
00550
00551 return *this;
00552 }
00553
00554 String & String::Read()
00555 {
00556 return Read(stdin);
00557 }
00558
00559 #ifdef __ZLIB_AVAILABLE__
00560 String & String::Read(IFILE & f)
00561 {
00562 len = 0;
00563 buffer[len] = 0;
00564
00565 if (f == NULL) return *this;
00566
00567 bool leading = true;
00568
00569 while (true)
00570 {
00571 int ch = ifgetc(f);
00572
00573 if (ch == -1) break;
00574
00575 if (strchr(WHITESPACE, ch) != NULL)
00576 {
00577 if (leading)
00578 {
00579 continue;
00580 }
00581 else
00582 {
00583 break;
00584 }
00585 }
00586
00587 if (len + 1 == size)
00588 Grow(len + 1);
00589
00590 buffer[len++] = (char) ch;
00591 buffer[len] = 0;
00592
00593 leading = false;
00594 }
00595
00596 return *this;
00597 }
00598 #endif
00599
00600 int String::ReadLine()
00601 {
00602 static int last = 0;
00603 int ch;
00604
00605 len = 0;
00606 buffer[len] = 0;
00607
00608 while (true)
00609 {
00610 ch = getchar();
00611
00612 if (ch == EOF)
00613 {
00614 break;
00615 }
00616
00617 if (ch == 10)
00618 {
00619 if (last == 13)
00620 {
00621 last = 0;
00622 continue;
00623 }
00624 else
00625 {
00626 last = 10;
00627 break;
00628 }
00629 }
00630
00631 if (ch == 13)
00632 {
00633 if (last == 10)
00634 {
00635 last = 0;
00636 continue;
00637 }
00638 else
00639 {
00640 last = 13;
00641 break;
00642 }
00643 }
00644
00645 if (len + 1 == size)
00646 {
00647 Grow(len + 1);
00648 }
00649
00650 last = ch;
00651 buffer[len++] = (char) last;
00652 buffer[len] = 0;
00653 }
00654
00655 if ((ch == EOF) && (len == 0))
00656 {
00657
00658 return -1;
00659 }
00660
00661
00662 return 1;
00663 }
00664
00665
00666 #ifdef __ZLIB_AVAILABLE__
00667
00668 int String::ReadLine(IFILE & f)
00669 {
00670 static int last = 0;
00671 int ch;
00672
00673 len = 0;
00674 buffer[len] = 0;
00675
00676 while (true)
00677 {
00678 ch = ifgetc(f);
00679
00680 if (ch == EOF)
00681 {
00682 break;
00683 }
00684
00685 if (ch == 10)
00686 {
00687 if (last == 13)
00688 {
00689 last = 0;
00690 continue;
00691 }
00692 else
00693 {
00694 last = 10;
00695 break;
00696 }
00697 }
00698
00699 if (ch == 13)
00700 {
00701 if (last == 10)
00702 {
00703 last = 0;
00704 continue;
00705 }
00706 else
00707 {
00708 last = 13;
00709 break;
00710 }
00711 }
00712
00713 if (len + 1 == size)
00714 {
00715 Grow(len + 1);
00716 }
00717
00718 last = ch;
00719 buffer[len++] = (char) last;
00720 buffer[len] = 0;
00721 }
00722
00723 if ((ch == EOF) && (len == 0))
00724 {
00725
00726 return -1;
00727 }
00728 return 1;
00729 }
00730 #endif
00731
00732 void String::Write(FILE * f)
00733 {
00734 fprintf(f, "%s", buffer);
00735 }
00736
00737 void String::Write()
00738 {
00739 Write(stdout);
00740 }
00741
00742 void String::WriteLine()
00743 {
00744 WriteLine(stdout);
00745 }
00746
00747 void String::WriteLine(FILE * f)
00748 {
00749 if (f == NULL) return;
00750 fprintf(f, "%s\n", buffer);
00751 }
00752
00753 std::ostream& operator << (std::ostream& os, const String& s)
00754 {
00755 return os << s.c_str();
00756 }
00757
00758 String String::Left(int n) const
00759 {
00760 if (n < 0) n = 0;
00761 if (len < n) n = len;
00762 String result(n);
00763 memcpy(result.buffer, buffer, n);
00764 result.buffer[result.len = n] = 0;
00765 return result;
00766 }
00767
00768 String String::Right(int n) const
00769 {
00770 if (n < 0) n = 0;
00771 if (len < n) n = len;
00772 String result(n);
00773 memcpy(result.buffer, buffer + len - n, n);
00774 result.buffer[result.len = n] = 0;
00775 return result;
00776 }
00777
00778 String String::SubStr(int start, int n) const
00779 {
00780 if (start < 0)
00781 {
00782 n += start;
00783 start = 0;
00784 };
00785 n = min(len - start, n);
00786 n = max(n, 0);
00787 String result(n);
00788 if (start > len) return result;
00789 memcpy(result.buffer, buffer + start, n);
00790 result.buffer[result.len = n] = 0;
00791 return result;
00792 }
00793
00794 String String::SubStr(int start) const
00795 {
00796 return SubStr(start, len - start);
00797 }
00798
00799 String String::Mid(int start, int end) const
00800 {
00801 return SubStr(start, end - start + 1);
00802 }
00803
00804 int String::FindChar(char ch, int start) const
00805 {
00806 return caseSensitive ? FastFindChar(ch, start) : SlowFindChar(ch, start);
00807 }
00808
00809 int String::FastFindChar(char ch, int start) const
00810 {
00811 for (; start < len; start++)
00812 if (buffer[start] == ch)
00813 return start;
00814 return -1;
00815 }
00816
00817 int String::SlowFindChar(char ch, int start) const
00818 {
00819 ch = (char) toupper(ch);
00820 for (; start < len; start++)
00821 if (toupper(buffer[start]) == ch)
00822 return start;
00823 return -1;
00824 }
00825
00826 int String::FindLastChar(char ch) const
00827 {
00828 return caseSensitive ? FastFindLastChar(ch) : SlowFindLastChar(ch);
00829 }
00830
00831 int String::FastFindLastChar(char ch) const
00832 {
00833 for (int start = len-1; start >= 0; start--)
00834 if (buffer[start] == ch)
00835 return start;
00836 return -1;
00837 }
00838
00839 int String::SlowFindLastChar(char ch) const
00840 {
00841 ch = (char) toupper(ch);
00842 for (int start = len-1 ; start >= 0; start--)
00843 if (toupper(buffer[start]) == ch)
00844 return start;
00845 return -1;
00846 }
00847
00848 int String::Find(const String & pattern, int start) const
00849 {
00850 return caseSensitive ? FastFind(pattern, start) : SlowFind(pattern, start);
00851 }
00852
00853
00854
00855 int String::FastFind(const String & pattern, int start) const
00856 {
00857 for (int i ; start <= len - pattern.Length(); start++)
00858 if (buffer[start] == pattern[0])
00859 {
00860 for (i = 1; i < pattern.Length(); i++)
00861 if (pattern[i] != buffer[start + i])
00862 break;
00863 if (i == pattern.Length()) return start;
00864 }
00865 return -1;
00866 }
00867
00868 int String::SlowFind(const String & pattern, int start) const
00869 {
00870 int firstchar = toupper(pattern[0]);
00871
00872 for (int i ; start <= len - pattern.Length(); start++)
00873 if (toupper(buffer[start]) == firstchar)
00874 {
00875 for (i = 1; i < pattern.Length(); i++)
00876 if (toupper(pattern[i]) != toupper(buffer[start + i]))
00877 break;
00878 if (i == pattern.Length()) return start;
00879 }
00880 return -1;
00881 }
00882
00883 int String::SetLength(int newlen)
00884 {
00885 if (newlen > len)
00886 {
00887 Grow(newlen);
00888 memset(buffer + len, ' ', newlen - len);
00889 }
00890 buffer[newlen] = 0;
00891 return len = newlen;
00892 }
00893
00894 String & String::Filter(const String & s)
00895 {
00896 int to = 0;
00897 for (int from = 0; from < len; from++)
00898 if (s.FindChar(buffer[from]) != -1)
00899 buffer[to++] = buffer[from];
00900 buffer[len = to] = 0;
00901 return *this;
00902 }
00903
00904 String & String::Filter(const char * s)
00905 {
00906 String filter(s);
00907 return Filter(filter);
00908 }
00909
00910 String & String::ExcludeCharacters(const String & s)
00911 {
00912 int to = 0;
00913 for (int from = 0; from < len; from++)
00914 if (s.FindChar(buffer[from]) == -1)
00915 buffer[to++] = buffer[from];
00916 buffer[len = to] = 0;
00917 return *this;
00918 }
00919
00920 String & String::ExcludeCharacters(const char * s)
00921 {
00922 String excluded(s);
00923 return ExcludeCharacters(excluded);
00924 }
00925
00926 String operator + (const char * lhs, const String & rhs)
00927 {
00928 String result(lhs);
00929 result += rhs;
00930 return result;
00931 }
00932
00933 String operator + (char lhs, const String & rhs)
00934 {
00935 String result(lhs);
00936 result += rhs;
00937 return result;
00938 }
00939
00940 String operator + (int lhs, const String & rhs)
00941 {
00942 String result;
00943 result = lhs;
00944 result += rhs;
00945 return result;
00946 }
00947
00948 String operator + (unsigned int lhs, const String & rhs)
00949 {
00950 String result;
00951 result = lhs;
00952 result += rhs;
00953 return result;
00954 }
00955
00956 long String::AsInteger() const
00957 {
00958 long returnValue = 0;
00959 if(!AsInteger(returnValue))
00960 {
00961
00962 }
00963 return(returnValue);
00964 }
00965
00966
00967
00968
00969 bool String::AsInteger(long& intValue) const
00970 {
00971 long integer = 0;
00972 int base = 10;
00973 int pos = 0;
00974 int sign = 1;
00975 bool isInt = true;
00976
00977 if (buffer[pos] == '-')
00978 {
00979 sign = -1, pos++;
00980 }
00981
00982 if ((len > pos + 2) && (buffer[pos] == '0') &&
00983 ((buffer[pos+1] == 'x') || (buffer[pos+1] == 'X')))
00984 {
00985 base = 16, pos += 2;
00986 }
00987
00988
00989 if (pos == len)
00990 {
00991 return(false);
00992 }
00993
00994 for (; pos < len; pos++)
00995 {
00996 char digit = (char) toupper(buffer[pos]);
00997
00998 if (digit >= '0' && digit <= '9')
00999 {
01000 integer = integer * base + digit - '0';
01001 }
01002 else if (digit >= 'A' && digit <= 'F' && base == 16)
01003 {
01004 integer = integer * base + digit - 'A' + 10;
01005 }
01006 else
01007 {
01008 isInt = false;
01009 break;
01010 }
01011 }
01012
01013 intValue = sign*integer;
01014
01015 return(isInt);
01016 }
01017
01018
01019
01020
01021 bool String::AsInteger(int& intValue) const
01022 {
01023 int integer = 0;
01024 int base = 10;
01025 int pos = 0;
01026 int sign = 1;
01027 bool isInt = true;
01028
01029 if (buffer[pos] == '-')
01030 {
01031 sign = -1, pos++;
01032 }
01033
01034 if ((len > pos + 2) && (buffer[pos] == '0') &&
01035 ((buffer[pos+1] == 'x') || (buffer[pos+1] == 'X')))
01036 {
01037 base = 16, pos += 2;
01038 }
01039
01040
01041 if (pos == len)
01042 {
01043 return(false);
01044 }
01045
01046 for (; pos < len; pos++)
01047 {
01048 char digit = (char) toupper(buffer[pos]);
01049
01050 if (digit >= '0' && digit <= '9')
01051 {
01052 integer = integer * base + digit - '0';
01053 }
01054 else if (digit >= 'A' && digit <= 'F' && base == 16)
01055 {
01056 integer = integer * base + digit - 'A' + 10;
01057 }
01058 else
01059 {
01060 isInt = false;
01061 break;
01062 }
01063 }
01064
01065 intValue = sign*integer;
01066
01067 return(isInt);
01068 }
01069
01070
01071 String & String::Invert()
01072 {
01073 for (int i = 0, j = len - 1; i < j; i++, j--)
01074 {
01075 char tmp = buffer[i];
01076 buffer[i] = buffer[j];
01077 buffer[j] = tmp;
01078 }
01079 return *this;
01080 }
01081
01082 String String::RightToLeft()
01083 {
01084 String result(*this);
01085 result.Invert();
01086 return result;
01087 }
01088
01089 String & String::Invert(const String & s)
01090 {
01091 Copy(s);
01092 return Invert();
01093 }
01094
01095 int String::CompareToStem(const String & stem) const
01096 {
01097 if (caseSensitive)
01098 return String::FastCompareToStem(stem);
01099 else
01100 return String::SlowCompareToStem(stem);
01101 }
01102
01103 int String::FastCompareToStem(const String & stem) const
01104 {
01105 for (int i = 0; i < stem.len; i++)
01106 if (buffer[i] - stem.buffer[i])
01107 {
01108 #ifdef NATURAL_ORDERING
01109 int d = i;
01110 while (isdigit(buffer[d]) && isdigit(stem.buffer[d]) && d < stem.len)
01111 d++;
01112 if (isdigit(buffer[d]) && d < stem.len)
01113 return 1;
01114 if (isdigit(stem.buffer[d]))
01115 return -1;
01116 #endif
01117 return buffer[i] - stem.buffer[i];
01118 }
01119 return 0;
01120 }
01121
01122 int String::SlowCompareToStem(const String & stem) const
01123 {
01124 for (int i = 0; i < stem.len; i++)
01125 if (toupper(buffer[i]) - toupper(stem.buffer[i]))
01126 {
01127 #ifdef NATURAL_ORDERING
01128 int d = i;
01129 while (isdigit(buffer[d]) && isdigit(stem.buffer[d]) && d < stem.len)
01130 d++;
01131 if (isdigit(buffer[d]) && d < stem.len)
01132 return 1;
01133 if (isdigit(stem.buffer[d]))
01134 return -1;
01135 #endif
01136 return toupper(buffer[i]) - toupper(stem.buffer[i]);
01137 }
01138 return 0;
01139 }
01140
01141 int String::CompareToStem(const char * stem) const
01142 {
01143 if (caseSensitive)
01144 return String::FastCompareToStem(stem);
01145 else
01146 return String::SlowCompareToStem(stem);
01147 }
01148
01149 int String::FastCompareToStem(const char * stem) const
01150 {
01151 for (int i = 0; stem[i] != 0; i++)
01152 if (buffer[i] - stem[i])
01153 return buffer[i] - stem[i];
01154 return 0;
01155 }
01156
01157 int String::SlowCompareToStem(const char * stem) const
01158 {
01159 for (int i = 0; stem[i] != 0; i++)
01160 if (toupper(buffer[i]) - toupper(stem[i]))
01161 return toupper(buffer[i]) - toupper(stem[i]);
01162 return 0;
01163 }
01164
01165 int String::MatchesBeginningOf(const String & stem) const
01166 {
01167 if (caseSensitive)
01168 return String::FastMatchesBeginningOf(stem);
01169 else
01170 return String::SlowMatchesBeginningOf(stem);
01171 }
01172
01173 int String::FastMatchesBeginningOf(const String & stem) const
01174 {
01175 for (int i = 0; i < len; i++)
01176 if (buffer[i] - stem.buffer[i])
01177 return buffer[i] - stem.buffer[i];
01178 return 0;
01179 }
01180
01181 int String::SlowMatchesBeginningOf(const String & stem) const
01182 {
01183 for (int i = 0; i < len; i++)
01184 if (toupper(buffer[i]) - toupper(stem.buffer[i]))
01185 return toupper(buffer[i]) - toupper(stem.buffer[i]);
01186 return 0;
01187 }
01188
01189 int String::MatchesBeginningOf(const char * stem) const
01190 {
01191 if (caseSensitive)
01192 return String::FastMatchesBeginningOf(stem);
01193 else
01194 return String::SlowMatchesBeginningOf(stem);
01195 }
01196
01197 int String::FastMatchesBeginningOf(const char * stem) const
01198 {
01199 for (int i = 0; i < len; i++)
01200 if (buffer[i] - stem[i])
01201 return buffer[i] - stem[i];
01202 return 0;
01203 }
01204
01205 int String::SlowMatchesBeginningOf(const char * stem) const
01206 {
01207 for (int i = 0; i < len; i++)
01208 if (toupper(buffer[i]) - toupper(stem[i]))
01209 return toupper(buffer[i]) - toupper(stem[i]);
01210 return 0;
01211 }
01212
01213 String & String::Trim(char character)
01214 {
01215 int first = 0;
01216 while (buffer[first] && buffer[first] == character)
01217 first++;
01218
01219 int last = len - 1;
01220 while (last >= 0 && buffer[last] == character)
01221 last--;
01222
01223 int out = 0;
01224 while (first <= last)
01225 buffer[out++] = buffer[first++];
01226
01227 buffer[len = out] = 0;
01228
01229 return *this;
01230 }
01231
01232 String & String::Trim()
01233 {
01234 int first = 0;
01235 while (buffer[first] && isspace(buffer[first]))
01236 first++;
01237
01238 int last = len - 1;
01239 while (last >= 0 && isspace(buffer[last]))
01240 last--;
01241
01242 int out = 0;
01243 while (first <= last)
01244 buffer[out++] = buffer[first++];
01245
01246 buffer[len = out] = 0;
01247
01248 return *this;
01249 }
01250
01251 vector<String> *String::Split(char splitChar)
01252 {
01253 vector<String> *result = new vector<String>;
01254 String word;
01255
01256 for (int i = 0; i<Length(); i++)
01257 {
01258 if ((*this)[i]==splitChar)
01259 {
01260 result->push_back(word);
01261 word.Clear();
01262 }
01263 else
01264 word.Add((*this)[i]);
01265 }
01266 if (word.Length()>0) result->push_back(word);
01267 return result;
01268 }
01269
01270
01271 #define VSNPRINTF_NOT_CHECKED 0
01272 #define VSNPRINTF_IS_OK 1
01273 #define VSNPRINTF_NOT_OK 2
01274
01275 int String::vsnprintfChecked = 0;
01276
01277 int String::printf(const char * format, ...)
01278 {
01279 va_list ap;
01280 va_start(ap, format);
01281
01282 vprintf(format, ap);
01283
01284 va_end(ap);
01285 return len;
01286 }
01287
01288 int String::catprintf(const char * format, ...)
01289 {
01290 va_list ap;
01291 va_start(ap, format);
01292
01293 vcatprintf(format, ap);
01294
01295 va_end(ap);
01296 return len;
01297 }
01298
01299 int String::vprintf(const char * format, va_list ap)
01300 {
01301 check_vsnprintf();
01302
01303 while (true)
01304 {
01305 int bytes_needed;
01306 #ifdef va_copy
01307 va_list arguments;
01308 va_copy(arguments, ap);
01309 #else
01310 va_list & arguments = ap;
01311 #endif
01312
01313 if (vsnprintfChecked == VSNPRINTF_IS_OK)
01314 bytes_needed = vsnprintf(buffer, size, format, arguments);
01315 else
01316 bytes_needed = my_vsnprintf(buffer, size, format, arguments);
01317
01318 #ifdef va_copy
01319 va_end(arguments);
01320 #endif
01321
01322 if (bytes_needed >= size)
01323 Grow(bytes_needed);
01324 else if (bytes_needed == -1)
01325 Grow(size * 2);
01326 else
01327 {
01328 return len = bytes_needed;
01329 }
01330 }
01331 }
01332
01333 void String::check_vsnprintf()
01334 {
01335 if (vsnprintfChecked == VSNPRINTF_NOT_CHECKED)
01336 {
01337 char temp[100];
01338
01339 memset(temp, 0, 100);
01340 int check = snprintf(temp, 5, "%5s", "VSNPRINTF");
01341
01342 if (temp[6] != 0 || temp[7] != 0 || (check != 9 && check != -1))
01343
01344
01345
01346
01347
01348
01349 vsnprintfChecked = VSNPRINTF_NOT_OK;
01350 else
01351 vsnprintfChecked = VSNPRINTF_IS_OK;
01352 }
01353 }
01354
01355 int String::vcatprintf(const char * format, va_list ap)
01356 {
01357 check_vsnprintf();
01358
01359 if (len == size)
01360 Grow(size * 2);
01361
01362 while (true)
01363 {
01364 int bytes_needed;
01365 #ifdef va_copy
01366 va_list arguments;
01367 va_copy(arguments, ap);
01368 #else
01369 va_list & arguments = ap;
01370 #endif
01371
01372 if (vsnprintfChecked == VSNPRINTF_IS_OK)
01373 bytes_needed = len + vsnprintf(buffer + len, size - len, format, arguments);
01374 else
01375 bytes_needed = len + my_vsnprintf(buffer + len, size - len, format, arguments);
01376
01377 #ifdef va_copy
01378 va_end(arguments);
01379 #endif
01380
01381 if (bytes_needed >= size)
01382 Grow(bytes_needed);
01383 else if (bytes_needed < len)
01384 Grow(size * 2);
01385 else
01386 {
01387 return len = bytes_needed;
01388 }
01389 }
01390 }
01391
01392 FILE * String::my_vsnprintf_file = NULL;
01393
01394 int String::my_vsnprintf(char * buffer, int bufsize, const char * format, va_list args)
01395 {
01396 if (my_vsnprintf_file == NULL)
01397 {
01398 my_vsnprintf_file = tmpfile();
01399 atexit(my_vsnprintf_close_file);
01400 }
01401
01402 rewind(my_vsnprintf_file);
01403
01404 int len = vfprintf(my_vsnprintf_file, format, args);
01405
01406 rewind(my_vsnprintf_file);
01407
01408 if (len < bufsize)
01409 buffer[bufsize = len] = 0;
01410 fread(buffer, 1, bufsize, my_vsnprintf_file);
01411
01412 return len;
01413 }
01414
01415 int String::my_snprintf(char * buffer, int bufsize, const char * format, ...)
01416 {
01417 va_list ap;
01418 va_start(ap, format);
01419
01420 int bytes = my_vsnprintf(buffer, bufsize, format, ap);
01421
01422 va_end(ap);
01423
01424 return bytes;
01425 }
01426
01427 void String::my_vsnprintf_close_file()
01428 {
01429 fclose(my_vsnprintf_file);
01430 }
01431
01432 bool String::IsNumber()
01433 {
01434 int pos = 0;
01435 bool digits = false;
01436
01437
01438 if (buffer[pos] == '-' || buffer[pos] == '+')
01439 pos++;
01440
01441
01442 while (buffer[pos] >= '0' && buffer[pos] <= '9')
01443 pos++, digits = true;
01444
01445
01446 if (buffer[pos] == '.')
01447 {
01448 pos++;
01449
01450
01451 while (buffer[pos] >= '0' && buffer[pos] <= '9')
01452 pos++, digits = true;
01453 }
01454
01455 if (!digits) return false;
01456
01457
01458 if (buffer[pos] == 'E' || buffer[pos] == 'e')
01459 {
01460 pos++;
01461
01462
01463 if (buffer[pos] == '-' || buffer[pos] == '+')
01464 pos++;
01465
01466 digits = false;
01467
01468
01469 while (buffer[pos] >= '0' && buffer[pos] <= '9')
01470 pos++, digits = true;
01471 }
01472
01473 return (pos == len) && digits;
01474 }
01475
01476 void String::Fill(char ch, int length)
01477 {
01478 if (length >= 0)
01479 SetLength(length);
01480
01481 for (int i = 0; i < len; i++)
01482 buffer[i] = ch;
01483 }
01484
01485 String & String::Reverse()
01486 {
01487 for (int i = 0, j = len - 1; i < j; i++, j--)
01488 {
01489 int tmp = buffer[i];
01490 buffer[i] = buffer[j];
01491 buffer[j] = tmp;
01492 }
01493
01494 return *this;
01495 }
01496
01497
01498
01499 String & String::LeftClip(int clipAmount)
01500 {
01501 if (clipAmount == 0)
01502 return *this;
01503
01504 if (clipAmount > Length())
01505 {
01506 len = 0;
01507 return *this;
01508 }
01509
01510
01511 memmove(buffer, buffer + clipAmount, len - clipAmount);
01512 buffer[len -= clipAmount] = 0;
01513
01514 return *this;
01515 }
01516
01517 String & String::RightClip(int clipAmount)
01518 {
01519 if (clipAmount == 0) return *this;
01520
01521 if (clipAmount > Length())
01522 {
01523 len = 0;
01524 return *this;
01525 }
01526
01527 len -= clipAmount;
01528 buffer[len] = 0;
01529
01530 return *this;
01531 }
01532
01533
01534
01535 #ifdef __GNUC__
01536 String::operator long double() const
01537 {
01538 return strtold(buffer, NULL);
01539 }
01540 #else
01541 #ifdef __BORLANDC__
01542 String::operator long double() const
01543 {
01544 return _strtold(buffer, NULL);
01545 }
01546 #else
01547 String::operator long double() const
01548 {
01549 return atof(buffer);
01550 }
01551 #endif
01552 #endif
01553
01554