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 integer = 0;
00959 int base = 10;
00960 int pos = 0;
00961 int sign = 1;
00962
00963 if (buffer[pos] == '-')
00964 sign = -1, pos++;
00965
00966 if (len > pos + 2 && buffer[pos] == '0' &&
00967 (buffer[pos+1] == 'x' || buffer[pos+1] == 'X'))
00968 base = 16, pos += 2;
00969
00970 for (; pos < len; pos++)
00971 {
00972 char digit = (char) toupper(buffer[pos]);
00973
00974 if (digit >= '0' && digit <= '9')
00975 integer = integer * base + digit - '0';
00976 else if (digit >= 'A' && digit <= 'F' && base == 16)
00977 integer = integer * base + digit - 'A' + 10;
00978 else
00979 return sign * integer;
00980 }
00981
00982 return sign * integer;
00983 }
00984
00985
00986
00987
00988 bool String::AsInteger(long& intValue) const
00989 {
00990 long integer = 0;
00991 int base = 10;
00992 int pos = 0;
00993 int sign = 1;
00994 bool isInt = true;
00995
00996 if (buffer[pos] == '-')
00997 {
00998 sign = -1, pos++;
00999 }
01000
01001 if ((len > pos + 2) && (buffer[pos] == '0') &&
01002 ((buffer[pos+1] == 'x') || (buffer[pos+1] == 'X')))
01003 {
01004 base = 16, pos += 2;
01005 }
01006
01007
01008 if (pos == len)
01009 {
01010 return(false);
01011 }
01012
01013 for (; pos < len; pos++)
01014 {
01015 char digit = (char) toupper(buffer[pos]);
01016
01017 if (digit >= '0' && digit <= '9')
01018 {
01019 integer = integer * base + digit - '0';
01020 }
01021 else if (digit >= 'A' && digit <= 'F' && base == 16)
01022 {
01023 integer = integer * base + digit - 'A' + 10;
01024 }
01025 else
01026 {
01027 isInt = false;
01028 }
01029 }
01030
01031 intValue = sign*integer;
01032
01033 return(isInt);
01034 }
01035
01036
01037 String & String::Invert()
01038 {
01039 for (int i = 0, j = len - 1; i < j; i++, j--)
01040 {
01041 char tmp = buffer[i];
01042 buffer[i] = buffer[j];
01043 buffer[j] = tmp;
01044 }
01045 return *this;
01046 }
01047
01048 String String::RightToLeft()
01049 {
01050 String result(*this);
01051 result.Invert();
01052 return result;
01053 }
01054
01055 String & String::Invert(const String & s)
01056 {
01057 Copy(s);
01058 return Invert();
01059 }
01060
01061 int String::CompareToStem(const String & stem) const
01062 {
01063 if (caseSensitive)
01064 return String::FastCompareToStem(stem);
01065 else
01066 return String::SlowCompareToStem(stem);
01067 }
01068
01069 int String::FastCompareToStem(const String & stem) const
01070 {
01071 for (int i = 0; i < stem.len; i++)
01072 if (buffer[i] - stem.buffer[i])
01073 {
01074 #ifdef NATURAL_ORDERING
01075 int d = i;
01076 while (isdigit(buffer[d]) && isdigit(stem.buffer[d]) && d < stem.len)
01077 d++;
01078 if (isdigit(buffer[d]) && d < stem.len)
01079 return 1;
01080 if (isdigit(stem.buffer[d]))
01081 return -1;
01082 #endif
01083 return buffer[i] - stem.buffer[i];
01084 }
01085 return 0;
01086 }
01087
01088 int String::SlowCompareToStem(const String & stem) const
01089 {
01090 for (int i = 0; i < stem.len; i++)
01091 if (toupper(buffer[i]) - toupper(stem.buffer[i]))
01092 {
01093 #ifdef NATURAL_ORDERING
01094 int d = i;
01095 while (isdigit(buffer[d]) && isdigit(stem.buffer[d]) && d < stem.len)
01096 d++;
01097 if (isdigit(buffer[d]) && d < stem.len)
01098 return 1;
01099 if (isdigit(stem.buffer[d]))
01100 return -1;
01101 #endif
01102 return toupper(buffer[i]) - toupper(stem.buffer[i]);
01103 }
01104 return 0;
01105 }
01106
01107 int String::CompareToStem(const char * stem) const
01108 {
01109 if (caseSensitive)
01110 return String::FastCompareToStem(stem);
01111 else
01112 return String::SlowCompareToStem(stem);
01113 }
01114
01115 int String::FastCompareToStem(const char * stem) const
01116 {
01117 for (int i = 0; stem[i] != 0; i++)
01118 if (buffer[i] - stem[i])
01119 return buffer[i] - stem[i];
01120 return 0;
01121 }
01122
01123 int String::SlowCompareToStem(const char * stem) const
01124 {
01125 for (int i = 0; stem[i] != 0; i++)
01126 if (toupper(buffer[i]) - toupper(stem[i]))
01127 return toupper(buffer[i]) - toupper(stem[i]);
01128 return 0;
01129 }
01130
01131 int String::MatchesBeginningOf(const String & stem) const
01132 {
01133 if (caseSensitive)
01134 return String::FastMatchesBeginningOf(stem);
01135 else
01136 return String::SlowMatchesBeginningOf(stem);
01137 }
01138
01139 int String::FastMatchesBeginningOf(const String & stem) const
01140 {
01141 for (int i = 0; i < len; i++)
01142 if (buffer[i] - stem.buffer[i])
01143 return buffer[i] - stem.buffer[i];
01144 return 0;
01145 }
01146
01147 int String::SlowMatchesBeginningOf(const String & stem) const
01148 {
01149 for (int i = 0; i < len; i++)
01150 if (toupper(buffer[i]) - toupper(stem.buffer[i]))
01151 return toupper(buffer[i]) - toupper(stem.buffer[i]);
01152 return 0;
01153 }
01154
01155 int String::MatchesBeginningOf(const char * stem) const
01156 {
01157 if (caseSensitive)
01158 return String::FastMatchesBeginningOf(stem);
01159 else
01160 return String::SlowMatchesBeginningOf(stem);
01161 }
01162
01163 int String::FastMatchesBeginningOf(const char * stem) const
01164 {
01165 for (int i = 0; i < len; i++)
01166 if (buffer[i] - stem[i])
01167 return buffer[i] - stem[i];
01168 return 0;
01169 }
01170
01171 int String::SlowMatchesBeginningOf(const char * stem) const
01172 {
01173 for (int i = 0; i < len; i++)
01174 if (toupper(buffer[i]) - toupper(stem[i]))
01175 return toupper(buffer[i]) - toupper(stem[i]);
01176 return 0;
01177 }
01178
01179 String & String::Trim(char character)
01180 {
01181 int first = 0;
01182 while (buffer[first] && buffer[first] == character)
01183 first++;
01184
01185 int last = len - 1;
01186 while (last >= 0 && buffer[last] == character)
01187 last--;
01188
01189 int out = 0;
01190 while (first <= last)
01191 buffer[out++] = buffer[first++];
01192
01193 buffer[len = out] = 0;
01194
01195 return *this;
01196 }
01197
01198 String & String::Trim()
01199 {
01200 int first = 0;
01201 while (buffer[first] && isspace(buffer[first]))
01202 first++;
01203
01204 int last = len - 1;
01205 while (last >= 0 && isspace(buffer[last]))
01206 last--;
01207
01208 int out = 0;
01209 while (first <= last)
01210 buffer[out++] = buffer[first++];
01211
01212 buffer[len = out] = 0;
01213
01214 return *this;
01215 }
01216
01217 vector<String> *String::Split(char splitChar)
01218 {
01219 vector<String> *result = new vector<String>;
01220 String word;
01221
01222 for (int i = 0; i<Length(); i++)
01223 {
01224 if ((*this)[i]==splitChar)
01225 {
01226 result->push_back(word);
01227 word.Clear();
01228 }
01229 else
01230 word.Add((*this)[i]);
01231 }
01232 if (word.Length()>0) result->push_back(word);
01233 return result;
01234 }
01235
01236
01237 #define VSNPRINTF_NOT_CHECKED 0
01238 #define VSNPRINTF_IS_OK 1
01239 #define VSNPRINTF_NOT_OK 2
01240
01241 int String::vsnprintfChecked = 0;
01242
01243 int String::printf(const char * format, ...)
01244 {
01245 va_list ap;
01246 va_start(ap, format);
01247
01248 vprintf(format, ap);
01249
01250 va_end(ap);
01251 return len;
01252 }
01253
01254 int String::catprintf(const char * format, ...)
01255 {
01256 va_list ap;
01257 va_start(ap, format);
01258
01259 vcatprintf(format, ap);
01260
01261 va_end(ap);
01262 return len;
01263 }
01264
01265 int String::vprintf(const char * format, va_list ap)
01266 {
01267 check_vsnprintf();
01268
01269 while (true)
01270 {
01271 int bytes_needed;
01272 #ifdef va_copy
01273 va_list arguments;
01274 va_copy(arguments, ap);
01275 #else
01276 va_list & arguments = ap;
01277 #endif
01278
01279 if (vsnprintfChecked == VSNPRINTF_IS_OK)
01280 bytes_needed = vsnprintf(buffer, size, format, arguments);
01281 else
01282 bytes_needed = my_vsnprintf(buffer, size, format, arguments);
01283
01284 #ifdef va_copy
01285 va_end(arguments);
01286 #endif
01287
01288 if (bytes_needed >= size)
01289 Grow(bytes_needed);
01290 else if (bytes_needed == -1)
01291 Grow(size * 2);
01292 else
01293 {
01294 return len = bytes_needed;
01295 }
01296 }
01297 }
01298
01299 void String::check_vsnprintf()
01300 {
01301 if (vsnprintfChecked == VSNPRINTF_NOT_CHECKED)
01302 {
01303 char temp[100];
01304
01305 memset(temp, 0, 100);
01306 int check = snprintf(temp, 5, "%5s", "VSNPRINTF");
01307
01308 if (temp[6] != 0 || temp[7] != 0 || (check != 9 && check != -1))
01309
01310
01311
01312
01313
01314
01315 vsnprintfChecked = VSNPRINTF_NOT_OK;
01316 else
01317 vsnprintfChecked = VSNPRINTF_IS_OK;
01318 }
01319 }
01320
01321 int String::vcatprintf(const char * format, va_list ap)
01322 {
01323 check_vsnprintf();
01324
01325 if (len == size)
01326 Grow(size * 2);
01327
01328 while (true)
01329 {
01330 int bytes_needed;
01331 #ifdef va_copy
01332 va_list arguments;
01333 va_copy(arguments, ap);
01334 #else
01335 va_list & arguments = ap;
01336 #endif
01337
01338 if (vsnprintfChecked == VSNPRINTF_IS_OK)
01339 bytes_needed = len + vsnprintf(buffer + len, size - len, format, arguments);
01340 else
01341 bytes_needed = len + my_vsnprintf(buffer + len, size - len, format, arguments);
01342
01343 #ifdef va_copy
01344 va_end(arguments);
01345 #endif
01346
01347 if (bytes_needed >= size)
01348 Grow(bytes_needed);
01349 else if (bytes_needed < len)
01350 Grow(size * 2);
01351 else
01352 {
01353 return len = bytes_needed;
01354 }
01355 }
01356 }
01357
01358 FILE * String::my_vsnprintf_file = NULL;
01359
01360 int String::my_vsnprintf(char * buffer, int bufsize, const char * format, va_list args)
01361 {
01362 if (my_vsnprintf_file == NULL)
01363 {
01364 my_vsnprintf_file = tmpfile();
01365 atexit(my_vsnprintf_close_file);
01366 }
01367
01368 rewind(my_vsnprintf_file);
01369
01370 int len = vfprintf(my_vsnprintf_file, format, args);
01371
01372 rewind(my_vsnprintf_file);
01373
01374 if (len < bufsize)
01375 buffer[bufsize = len] = 0;
01376 fread(buffer, 1, bufsize, my_vsnprintf_file);
01377
01378 return len;
01379 }
01380
01381 int String::my_snprintf(char * buffer, int bufsize, const char * format, ...)
01382 {
01383 va_list ap;
01384 va_start(ap, format);
01385
01386 int bytes = my_vsnprintf(buffer, bufsize, format, ap);
01387
01388 va_end(ap);
01389
01390 return bytes;
01391 }
01392
01393 void String::my_vsnprintf_close_file()
01394 {
01395 fclose(my_vsnprintf_file);
01396 }
01397
01398 bool String::IsNumber()
01399 {
01400 int pos = 0;
01401 bool digits = false;
01402
01403
01404 if (buffer[pos] == '-' || buffer[pos] == '+')
01405 pos++;
01406
01407
01408 while (buffer[pos] >= '0' && buffer[pos] <= '9')
01409 pos++, digits = true;
01410
01411
01412 if (buffer[pos] == '.')
01413 {
01414 pos++;
01415
01416
01417 while (buffer[pos] >= '0' && buffer[pos] <= '9')
01418 pos++, digits = true;
01419 }
01420
01421 if (!digits) return false;
01422
01423
01424 if (buffer[pos] == 'E' || buffer[pos] == 'e')
01425 {
01426 pos++;
01427
01428
01429 if (buffer[pos] == '-' || buffer[pos] == '+')
01430 pos++;
01431
01432 digits = false;
01433
01434
01435 while (buffer[pos] >= '0' && buffer[pos] <= '9')
01436 pos++, digits = true;
01437 }
01438
01439 return (pos == len) && digits;
01440 }
01441
01442 void String::Fill(char ch, int length)
01443 {
01444 if (length >= 0)
01445 SetLength(length);
01446
01447 for (int i = 0; i < len; i++)
01448 buffer[i] = ch;
01449 }
01450
01451 String & String::Reverse()
01452 {
01453 for (int i = 0, j = len - 1; i < j; i++, j--)
01454 {
01455 int tmp = buffer[i];
01456 buffer[i] = buffer[j];
01457 buffer[j] = tmp;
01458 }
01459
01460 return *this;
01461 }
01462
01463
01464
01465 String & String::LeftClip(int clipAmount)
01466 {
01467 if (clipAmount == 0)
01468 return *this;
01469
01470 if (clipAmount > Length())
01471 {
01472 len = 0;
01473 return *this;
01474 }
01475
01476
01477 memmove(buffer, buffer + clipAmount, len - clipAmount);
01478 buffer[len -= clipAmount] = 0;
01479
01480 return *this;
01481 }
01482
01483 String & String::RightClip(int clipAmount)
01484 {
01485 if (clipAmount == 0) return *this;
01486
01487 if (clipAmount > Length())
01488 {
01489 len = 0;
01490 return *this;
01491 }
01492
01493 len -= clipAmount;
01494 buffer[len] = 0;
01495
01496 return *this;
01497 }
01498
01499
01500
01501 #ifdef __GNUC__
01502 String::operator long double() const
01503 {
01504 return strtold(buffer, NULL);
01505 }
01506 #else
01507 #ifdef __BORLANDC__
01508 String::operator long double() const
01509 {
01510 return _strtold(buffer, NULL);
01511 }
01512 #else
01513 String::operator long double() const
01514 {
01515 return atof(buffer);
01516 }
01517 #endif
01518 #endif
01519
01520