StringBasics.cpp

00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 // If natural ordering is defined, comparisons will
00037 // order strings including numbers correctly
00038 // (eg, ... "8", "9", "10" ...) rather than using
00039 // ASCII ordering (... "10", "8", "9", ...)
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         // Avoid getting stuck on zero length lines (system specific!)
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             // Set return value to indicate error/EOF
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         // Indicate error/EOF if nothing was read.
00658         return -1;
00659     }
00660 
00661     // Return success.
00662     return 1;
00663 }
00664 
00665 
00666 #ifdef __ZLIB_AVAILABLE__
00667 // Read line using getc.
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         // Indicate error/EOF if nothing was read.
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 // TODO -- We should have a better string search algorithm
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         // This is not an integer, but nothing to do but return a value.
00962     }
00963     return(returnValue);
00964 }
00965 
00966 
00967 // Check that the string is an integer when converting it.
00968 // If the entire string is an integer, return true, if not, return false.
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     // If this is no value for this integer, return false.
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 // Check that the string is an integer when converting it.
01020 // If the entire string is an integer, return true, if not, return false.
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     // If this is no value for this integer, return false.
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             error("This program requires a working version of vsnprintf\n"
01345                   "However, vsnprintf in the current library seems buggy\n\n"
01346                   "Recompiling this program with the -D__REPLACE_SNPRINTF__ flag\n"
01347                   "may solve this problem.\n\n");
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     // Skip leading sign
01438     if (buffer[pos] == '-' || buffer[pos] == '+')
01439         pos++;
01440 
01441     // Check integer portion
01442     while (buffer[pos] >= '0' && buffer[pos] <= '9')
01443         pos++, digits = true;
01444 
01445     // Skip decimal point
01446     if (buffer[pos] == '.')
01447     {
01448         pos++;
01449 
01450         // Check fractional portion
01451         while (buffer[pos] >= '0' && buffer[pos] <= '9')
01452             pos++, digits = true;
01453     }
01454 
01455     if (!digits) return false;
01456 
01457     // Check exponent
01458     if (buffer[pos] == 'E' || buffer[pos] == 'e')
01459     {
01460         pos++;
01461 
01462         // Skip leading sign
01463         if (buffer[pos] == '-' || buffer[pos] == '+')
01464             pos++;
01465 
01466         digits = false;
01467 
01468         // Check exponent digits
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 // String::LeftClip() trims the string so only characters after clipPoint remain
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     // Use memory move, because the two blocks can overlap
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 // Implementation of long double convertors is in flux across different platforms
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 
Generated on Tue Sep 6 17:52:01 2011 for libStatGen Software by  doxygen 1.6.3