OWBI1_String.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #include "OWBI1_config.h"
00037 #include "OWBI1_String.hpp"
00038 #include "OWBI1_Array.hpp"
00039 #include "OW_StringStream.hpp"
00040 #include "OW_Format.hpp"
00041 #include "OW_BinarySerialization.hpp"
00042 #include "OW_Assertion.hpp"
00043 #include "OWBI1_AutoPtr.hpp"
00044 #include "OWBI1_Bool.hpp"
00045 #include "OW_UTF8Utils.hpp"
00046 #include "OW_ExceptionIds.hpp"
00047 #include "OWBI1_COWIntrusiveCountableBase.hpp"
00048 
00049 #include <cstdio>
00050 #include <cstdlib>
00051 #include <cstring>
00052 #include <cctype>
00053 #include <cstdarg>
00054 #include <cerrno>
00055 #if defined(OWBI1_HAVE_ISTREAM) && defined(OWBI1_HAVE_OSTREAM)
00056 #include <istream>
00057 #include <ostream>
00058 #else
00059 #include <iostream>
00060 #endif
00061 #include <cmath> // for HUGE_VAL
00062 #include <cfloat> // for DBL_MANT_DIG
00063 
00064 #ifdef OWBI1_WIN32
00065 #define SNPRINTF _snprintf
00066 #else
00067 #define SNPRINTF snprintf
00068 #endif
00069 
00070 namespace OWBI1
00071 {
00072 using namespace OpenWBEM;
00073 using std::istream;
00074 using std::ostream;
00075 
00076 namespace ExceptionIds = ::OpenWBEM::ExceptionIds;
00077 OWBI1_DEFINE_EXCEPTION_WITH_ID(StringConversion);
00078 
00080 // TODO: Move these 2 functions into UTF8Utils
00081 // TODO: I18N: These don't work right!
00083 static inline int
00084 strncmpi(const char* s1, const char* s2, size_t n)
00085 {
00086    using namespace UTF8Utils;
00087    while (n > 0)
00088    {
00089       char c1 = *s1++;
00090       char c2 = *s2++;
00091       // short-curcuit evaluation will keep us from calling tolower
00092       // unnecessarily
00093       if (c1 != 0 && (c1 == c2 || tolower(c1) == tolower(c2)))
00094       {
00095          --n;
00096          continue;
00097       }
00098       return static_cast<int>(c1) - static_cast<int>(c2);
00099    }
00100    return 0;
00101 #if 0
00102    String ls1(s1, n);
00103    String ls2(s2, n);
00104    ls1.toUpperCase();
00105    ls2.toUpperCase();
00106    return ls1.compareTo(ls2);
00107 #endif
00108 }
00109 
00110 // class invariant: m_buf points to a null-terminated sequence of characters. m_buf is m_len+1 bytes long.
00111 class String::ByteBuf : public COWIntrusiveCountableBase
00112 {
00113 public:
00114    ByteBuf(const char* s) :
00115       m_len(::strlen(s)), m_buf(new char[m_len+1])
00116    {
00117       strcpy(m_buf, s);
00118    }
00119 
00120    ByteBuf(const ByteBuf& arg)
00121       : COWIntrusiveCountableBase(arg)
00122       , m_len(arg.m_len)
00123       , m_buf(new char[m_len+1])
00124    {
00125       strcpy(m_buf, arg.m_buf);
00126    }
00127    
00128    ByteBuf(AutoPtrVec<char>& s, size_t len)
00129       : m_len(len), m_buf(s.release())
00130    {
00131    }
00132    
00133    ~ByteBuf() { delete [] m_buf; }
00134    
00135    ByteBuf& operator= (const ByteBuf& arg)
00136    {
00137       char* buf = new char[arg.m_len+1];
00138       strcpy(buf, arg.m_buf);
00139       delete [] m_buf;
00140       m_buf = buf;
00141       m_len = arg.m_len;
00142       return *this;
00143    }
00144    
00145    size_t length() const { return m_len; }
00146    char* data() const { return m_buf; }
00147    ByteBuf* clone() const { return new ByteBuf(*this); }
00148 private:
00149    size_t m_len;
00150    char* m_buf;
00151 };
00153 #if defined(OWBI1_AIX)
00154 const size_t String::npos = ~0;
00155 #endif
00156 
00157 String::String() :
00158    m_buf(0)
00159 {
00160 }
00161 #if defined(OWBI1_WIN32)
00162 #define snprintf _snprintf // stupid windoze...
00163 #endif
00164 
00165 String::String(Int32 val) :
00166    m_buf(NULL)
00167 {
00168    char tmpbuf[32];
00169    int len = snprintf(tmpbuf, sizeof(tmpbuf), "%d", val);
00170    AutoPtrVec<char> bfr(new char[len+1]);
00171    ::snprintf(bfr.get(), len+1, "%d", val);
00172    m_buf = new ByteBuf(bfr, len);
00173 }
00175 String::String(UInt32 val) :
00176    m_buf(NULL)
00177 {
00178    char tmpbuf[32];
00179    int len = ::snprintf(tmpbuf, sizeof(tmpbuf), "%u", val);
00180    AutoPtrVec<char> bfr(new char[len+1]);
00181    ::snprintf(bfr.get(), len+1, "%u", val);
00182    m_buf = new ByteBuf(bfr, len);
00183 }
00184 #if defined(OWBI1_INT32_IS_INT) && defined(OWBI1_INT64_IS_LONG_LONG)
00185 
00186 String::String(long val) :
00187    m_buf(NULL)
00188 {
00189    char tmpbuf[32];
00190    int len = snprintf(tmpbuf, sizeof(tmpbuf), "%ld", val);
00191    AutoPtrVec<char> bfr(new char[len+1]);
00192    ::snprintf(bfr.get(), len+1, "%ld", val);
00193    m_buf = new ByteBuf(bfr, len);
00194 }
00196 String::String(unsigned long val) :
00197    m_buf(NULL)
00198 {
00199    char tmpbuf[32];
00200    int len = ::snprintf(tmpbuf, sizeof(tmpbuf), "%lu", val);
00201    AutoPtrVec<char> bfr(new char[len+1]);
00202    ::snprintf(bfr.get(), len+1, "%lu", val);
00203    m_buf = new ByteBuf(bfr, len);
00204 }
00205 #endif
00206 #if defined(OWBI1_WIN32)
00207 #undef snprintf
00208 #endif
00209 
00210 String::String(Int64 val) :
00211    m_buf(NULL)
00212 {
00213    OStringStream ss(33);
00214    ss << val;
00215    m_buf = new ByteBuf(ss.c_str());
00216 }
00218 String::String(UInt64 val) :
00219    m_buf(NULL)
00220 {
00221 #if defined(OWBI1_INT64_IS_LONG)
00222    char tmpbuf[32];
00223    ::snprintf(tmpbuf, sizeof(tmpbuf), "%lu", val);
00224    m_buf = new ByteBuf(tmpbuf);
00225 #elif defined(OWBI1_INT64_IS_LONG_LONG)
00226    // unfortunately not all C libraries support long long with snprintf().
00227    // but the C++ iostream library handles it.
00228    OStringStream ss;
00229    ss << val;
00230    m_buf = new ByteBuf(ss.c_str());
00231 #endif
00232 }
00234 // decimal digits = ceiling((bits)*ln(2)/ln(10))
00235 String::String(Real32 val) :
00236    m_buf(NULL)
00237 {
00238    char tmpbuf[128];
00239 #if FLT_RADIX == 2
00240 #if defined(OWBI1_REAL32_IS_FLOAT)
00241 	::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*g", FLT_MANT_DIG * 3 / 10 + 1, static_cast<double>(val));
00242 #elif defined(OWBI1_REAL32_IS_DOUBLE)
00243 	::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, val);
00244 #endif
00245 #else
00246 #error "The formula for computing the number of digits of precision for a floating point needs to be implmented. It's ceiling(bits * log(FLT_RADIX) / log(10))"
00247 #endif
00248    m_buf = new ByteBuf(tmpbuf);
00249 }
00251 String::String(Real64 val) :
00252    m_buf(NULL)
00253 {
00254    char tmpbuf[128];
00255 #if FLT_RADIX == 2
00256 #if defined(OWBI1_REAL64_IS_DOUBLE)
00257 	::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, val);
00258 #elif defined(OWBI1_REAL64_IS_LONG_DOUBLE)
00259 	::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*Lg", LDBL_MANT_DIG * 3 / 10 + 1, val);
00260 #endif
00261 #else
00262 #error "The formula for computing the number of digits of precision for a floating point needs to be implmented. It's ceiling(bits * log(FLT_RADIX) / log(10))"
00263 #endif
00264    m_buf = new ByteBuf(tmpbuf);
00265 }
00267 String::String(const char* str) :
00268    m_buf(NULL)
00269 {
00270    m_buf = (NULL == str) ? 0 : new ByteBuf(str);
00271 }
00273 String::String(ETakeOwnershipFlag, char* allocatedMemory, size_t len) :
00274    m_buf(NULL)
00275 {
00276    OW_ASSERT(allocatedMemory != 0);
00277    AutoPtrVec<char> p(allocatedMemory);
00278    m_buf = new ByteBuf(p, len);
00279 }
00281 String::String(const char* str, size_t len) :
00282    m_buf(NULL)
00283 {
00284    if (NULL == str)
00285    {
00286       m_buf = 0;
00287    }
00288    else
00289    {
00290       AutoPtrVec<char> bfr(new char[len+1]);
00291       ::memcpy(bfr.get(), str, len);
00292       bfr[len] = '\0';
00293       m_buf = new ByteBuf(bfr, len);
00294    }
00295 }
00297 String::String(const String& arg) :
00298    m_buf(arg.m_buf)
00299 {
00300 }
00302 String::String(char c) :
00303    m_buf(NULL)
00304 {
00305    if (c != '\0')
00306    {
00307       char bfr[2];
00308       bfr[0] = c;
00309       bfr[1] = '\0';
00310       m_buf = new ByteBuf(bfr);
00311    }
00312    else
00313    {
00314       m_buf = 0;
00315    }
00316 }
00318 String::~String() 
00319 {
00320 }
00322 void
00323 String::swap(String& x)
00324 {
00325    m_buf.swap(x.m_buf);
00326 }
00328 char*
00329 String::allocateCString() const
00330 {
00331    size_t len = length() + 1;
00332    char* str = static_cast<char*>(malloc(len));
00333    ::strcpy(str, c_str());
00334    return str;
00335 }
00337 size_t
00338 String::length() const
00339 {
00340    return (m_buf) ? m_buf->length() : 0;
00341 }
00343 size_t
00344 String::UTF8Length() const
00345 {
00346    return UTF8Utils::charCount(c_str());
00347 }
00349 #ifdef OWBI1_WIN32
00350 #define vsnprintf _vsnprintf // stupid windoze
00351 #endif
00352 int
00353 String::format(const char* fmt, ...)
00354 {
00355    int n, size = 64;
00356    AutoPtrVec<char> p(new char[size]);
00357    
00358    va_list ap;
00359    
00360    // Try to print in the allocated space
00361    while (true)
00362    {
00363       va_start(ap, fmt);
00364       n = vsnprintf(p.get(), size, fmt, ap);
00365       va_end(ap);                // If that worked, return the string.
00366       if (n > -1 && n < size)
00367       {
00368          m_buf = new ByteBuf(p, n);
00369          return static_cast<int>(length());
00370       }
00371       if (n > -1)    // glibc 2.1
00372          size = n+1; // precisely what is needed
00373       else           // glibc 2.0
00374          size *= 2;  // twice the old size
00375       p = new char[size];
00376    }
00377 }
00378 #ifdef OWBI1_WIN32
00379 #undef vsnprintf // stupid windoze
00380 #endif
00381 
00382 char
00383 String::charAt(size_t ndx) const
00384 {
00385    return (m_buf) ? m_buf->data()[ndx] : '\0';
00386 }
00388 int
00389 String::compareTo(const char* arg) const
00390 {
00391    const char* lhs = "";
00392    if (m_buf)
00393    {
00394       lhs = m_buf->data();
00395    }
00396    return ::strcmp(lhs, arg);
00397 }
00399 int
00400 String::compareTo(const String& arg) const
00401 {
00402    return compareTo(arg.c_str());
00403 }
00405 int
00406 String::compareToIgnoreCase(const char* arg) const
00407 {
00408    const char* lhs = "";
00409    if (m_buf)
00410    {
00411       lhs = m_buf->data();
00412    }
00413    return UTF8Utils::compareToIgnoreCase(lhs, arg);
00414 }
00416 int
00417 String::compareToIgnoreCase(const String& arg) const
00418 {
00419    return compareToIgnoreCase(arg.c_str());
00420 }
00421 
00423 String&
00424 String::concat(const char* arg)
00425 {
00426    if (arg && *arg)
00427    {
00428       size_t len = length() + ::strlen(arg);
00429       AutoPtrVec<char> bfr(new char[len+1]);
00430       bfr[0] = 0;
00431       if (m_buf)
00432       {
00433          ::strcpy(bfr.get(), m_buf->data());
00434       }
00435       ::strcat(bfr.get(), arg);
00436       m_buf = new ByteBuf(bfr, len);
00437    }
00438    return *this;
00439 }
00440 
00442 String&
00443 String::concat(char arg)
00444 {
00445    size_t newlen = length() + 1;
00446    AutoPtrVec<char> bfr(new char[newlen+1]);
00447    bfr[0] = 0;
00448    if (m_buf)
00449    {
00450       ::strcpy(bfr.get(), m_buf->data());
00451    }
00452    *(bfr.get()+length()) = arg;
00453    *(bfr.get()+newlen) = 0;
00454    m_buf = new ByteBuf(bfr, newlen);
00455    return *this;
00456 }
00457 
00459 bool
00460 String::endsWith(char arg) const
00461 {
00462    return (m_buf
00463          && m_buf->length()
00464          && m_buf->data()[m_buf->length()-1] == arg);
00465 }
00466 
00468 bool
00469 String::endsWith(const char* arg, EIgnoreCaseFlag ignoreCase) const
00470 {
00471    if (!arg || !*arg)
00472    {
00473       return (length() == 0);
00474    }
00475 
00476    if (!m_buf)
00477    {
00478       return false;
00479    }
00480 
00481    int ndx = static_cast<int>(length() - ::strlen(arg));
00482    if (ndx < 0)
00483    {
00484       return false;
00485    }
00486 
00487    return (ignoreCase)
00488       ? (UTF8Utils::compareToIgnoreCase(m_buf->data()+ndx, arg) == 0)
00489       : (::strcmp(m_buf->data()+ndx, arg) == 0);
00490 }
00492 bool
00493 String::equals(const char* arg) const
00494 {
00495    return(compareTo(arg) == 0);
00496 }
00498 bool
00499 String::equals(const String& arg) const
00500 {
00501    return equals(arg.c_str());
00502 }
00504 bool
00505 String::equalsIgnoreCase(const char* arg) const
00506 {
00507    return(compareToIgnoreCase(arg) == 0);
00508 }
00510 bool
00511 String::equalsIgnoreCase(const String& arg) const
00512 {
00513    return equalsIgnoreCase(arg.c_str());
00514 }
00516 UInt32
00517 String::hashCode() const
00518 {
00519    UInt32 hash = 0;
00520    size_t len = length();
00521    for (size_t i = 0; i < len; i++)
00522    {
00523       // Don't need to check if m_buf is null, because if it is, len == 0,
00524       // and this loop won't be executed.
00525       const char temp = m_buf->data()[i];
00526       hash = (hash << 4) + (temp * 13);
00527       UInt32 g = hash & 0xf0000000;
00528       if (g)
00529       {
00530          hash ^= (g >> 24);
00531          hash ^= g;
00532       }
00533    }
00534    return hash;
00535 }
00537 size_t
00538 String::indexOf(char ch, size_t fromIndex) const
00539 {
00540    //if (fromIndex < 0)
00541    //{
00542    // fromIndex = 0;
00543    //}
00544    size_t cc = npos;
00545    if (fromIndex < length())
00546    {
00547       // Don't need to check m_buf for NULL, because if length() == 0,
00548       // this code won't be executed.
00549       const char* p = String::strchr(m_buf->data()+fromIndex, ch);
00550       if (p)
00551       {
00552          cc = p - m_buf->data();
00553       }
00554    }
00555    return cc;
00556 }
00558 size_t
00559 String::indexOf(const char* arg, size_t fromIndex) const
00560 {
00561    int cc = npos;
00562    if (fromIndex < length())
00563    {
00564       // Don't need to check m_buf for NULL, because if length() == 0,
00565       // this code won't be executed, but we do need to check arg.m_buf
00566       char* p(0);
00567       if (arg && *arg)
00568       {
00569          p = ::strstr(m_buf->data()+fromIndex, arg);
00570       }
00571       else
00572       {
00573          p = m_buf->data()+fromIndex;
00574       }
00575 
00576       if (p != NULL)
00577       {
00578          cc = static_cast<int>(p - m_buf->data());
00579       }
00580    }
00581    return cc;
00582 }
00584 size_t
00585 String::lastIndexOf(char ch, size_t fromIndex) const
00586 {
00587    if (fromIndex == npos)
00588    {
00589       if ((fromIndex = length()-1) == npos)
00590       {
00591          return npos;
00592       }
00593    }
00594    size_t cc = npos;
00595    if (fromIndex < length())
00596    {
00597       for (size_t i = fromIndex; i != npos; i--)
00598       {
00599          // Don't need to check m_buf for NULL, because if length() == 0,
00600          // this code won't be executed.
00601          if (m_buf->data()[i] == ch)
00602          {
00603             cc = i;
00604             break;
00605          }
00606       }
00607    }
00608    return cc;
00609 }
00611 size_t
00612 String::lastIndexOf(const char* arg, size_t fromIndex) const
00613 {
00614    if (fromIndex == npos || fromIndex >= length())
00615    {
00616       if (static_cast<int>(fromIndex = length()-1) < 0)
00617       {
00618          return npos;
00619       }
00620    }
00621 
00622    int arglen = (arg) ? ::strlen(arg) : 0;
00623    if (static_cast<int>(fromIndex -= arglen - 1) < 0)
00624    {
00625       return npos;
00626    }
00627    if (!arg)
00628    {
00629       return length() - 1;
00630    }
00631    while (fromIndex != npos)
00632    {
00633       // Don't need to check m_buf for NULL, because if length() == 0,
00634       // this code won't be executed.
00635       if (::strncmp(m_buf->data()+fromIndex, arg, arglen) == 0)
00636       {
00637          break;
00638       }
00639       fromIndex--;
00640    }
00641    return fromIndex;
00642 }
00644 bool
00645 String::startsWith(char arg) const
00646 {
00647    return (m_buf
00648          && m_buf->length()
00649          && m_buf->data()[0] == arg);
00650 }
00651 
00653 bool
00654 String::startsWith(const char* arg, EIgnoreCaseFlag ignoreCase) const
00655 {
00656    bool cc = false;
00657    if (!arg && !m_buf)
00658    {
00659       return true;
00660    }
00661    if (!*arg)
00662    {
00663       return (length() == 0);
00664    }
00665 
00666    size_t arglen = ::strlen(arg);
00667    if (arglen <= length())
00668    {
00669       // Don't need to check m_buf for NULL, because if length() == 0,
00670       // this code won't be executed.
00671       if (ignoreCase)
00672       {
00673          cc = (strncmpi(m_buf->data(), arg, arglen) == 0);
00674       }
00675       else
00676       {
00677          cc = (::strncmp(m_buf->data(), arg, arglen) == 0);
00678       }
00679    }
00680    return cc;
00681 }
00683 String
00684 String::substring(size_t beginIndex, size_t len) const
00685 {
00686    String nil;
00687    size_t count = len;
00688    size_t l = length();
00689    if (0 == l)
00690    {
00691       return nil;
00692    }
00693    if (beginIndex >= l)
00694    {
00695       return nil;
00696    }
00697    else if (0 == len)
00698    {
00699       return nil;
00700    }
00701    else if (len == npos)
00702    {
00703       count = l - beginIndex;
00704    }
00705    if (count + beginIndex > l)
00706    {
00707       count = l - beginIndex;
00708    }
00709    // Don't need to check m_buf for NULL, because if length() == 0,
00710    // this code won't be executed.
00711    return String(static_cast<const char*>(m_buf->data()+beginIndex), count);
00712 }
00714 bool
00715 String::isSpaces() const
00716 {
00717    if (!m_buf)
00718    {
00719       return true;
00720    }
00721    char* p = m_buf->data();
00722    while (isspace(*p) && *p != '\0')
00723    {
00724       p++;
00725    }
00726    return (*p == '\0');
00727 }
00729 String&
00730 String::ltrim()
00731 {
00732    if (!m_buf)
00733    {
00734       return *this;
00735    }
00736    char* s1 = m_buf->data();
00737    while (isspace(*s1) && *s1 != '\0')
00738    {
00739       s1++;
00740    }
00741    if (s1 == m_buf->data())
00742    {
00743       return *this;
00744    }
00745    *this = String(s1);
00746    return *this;
00747 }
00749 String&
00750 String::rtrim()
00751 {
00752    if (length() == 0)
00753    {
00754       return *this;
00755    }
00756    char* s1 = m_buf->data() + (length()-1);
00757    while (isspace(*s1) && s1 >= m_buf->data())
00758    {
00759       s1--;
00760    }
00761    if (s1 == (m_buf->data() + (length()-1)))
00762    {
00763       return *this;
00764    }
00765    if (s1 < m_buf->data())
00766    {
00767       *this = String();
00768       return *this;
00769    }
00770    size_t len = (s1 - m_buf->data()) + 1;
00771    *this = String(m_buf->data(), len);
00772    return *this;
00773 }
00775 String&
00776 String::trim()
00777 {
00778    if (length() == 0)
00779    {
00780       return *this;
00781    }
00782    char* s1 = m_buf->data();
00783    while (isspace(*s1) && *s1 != '\0')
00784    {
00785       s1++;
00786    }
00787    if (*s1 == '\0')
00788    {
00789       // String is all spaces
00790       *this = String();
00791       return *this;
00792    }
00793    const char* p2 = String::strchr(s1, '\0');
00794    const char* s2 = p2 - 1;
00795    while (isspace(*s2))
00796    {
00797       s2--;
00798    }
00799    if (s1 == m_buf->data() && s2 == p2)
00800    {
00801       // String has no leading or trailing spaces
00802       return *this;
00803    }
00804    size_t len = (s2 - s1) + 1;
00805    *this = String(s1, len);
00806    return *this;
00807 }
00809 String&
00810 String::erase()
00811 {
00812    m_buf = 0;
00813    return *this;
00814 }
00816 String&
00817 String::erase(size_t idx, size_t len)
00818 {
00819    if ( idx >= length() )
00820    {
00821       return *this;
00822    }
00823    if (len == npos)
00824    {
00825       *this = substring(0, idx);
00826    }
00827    else
00828    {
00829       *this = substring(0, idx) + substring(idx + len);
00830    }
00831    return *this;
00832 }
00834 // ATTN: UTF8 ?
00835 // TODO: FIXME this is broken wrt i18n
00836 String&
00837 String::toLowerCase()
00838 {
00839    size_t len = length();
00840    for (size_t i = 0; i < len; i++)
00841    {
00842       // Don't need to check m_buf for NULL, because if length() == 0,
00843       // this code won't be executed.
00844       m_buf->data()[i] = tolower(m_buf->data()[i]);
00845    }
00846    return *this;
00847 }
00849 // ATTN: UTF8 ?
00850 // TODO: FIXME this is broken wrt i18n
00851 String&
00852 String::toUpperCase()
00853 {
00854    size_t len = length();
00855    for (size_t i = 0; i < len; i++)
00856    {
00857       // Don't need to check m_buf for NULL, because if length() == 0,
00858       // this code won't be executed.
00859       m_buf->data()[i] = toupper(m_buf->data()[i]);
00860    }
00861    return *this;
00862 }
00864 void
00865 String::readObject(istream& istrm)
00866 {
00867    UInt32 len;
00868    BinarySerialization::readLen(istrm, len);
00869    AutoPtrVec<char> bfr(new char[len+1]);
00870    BinarySerialization::read(istrm, bfr.get(), len);
00871    bfr[len] = '\0';
00872    m_buf = new ByteBuf(bfr, len);
00873 }
00875 void
00876 String::writeObject(ostream& ostrm) const
00877 {
00878    UInt32 len = static_cast<UInt32>(length());
00879    BinarySerialization::writeLen(ostrm, len);
00880    if (len)
00881    {
00882       BinarySerialization::write(ostrm, m_buf->data(), len);
00883    }
00884 }
00886 String&
00887 String::operator= (const String& arg)
00888 {
00889    m_buf = arg.m_buf;
00890    return *this;
00891 }
00893 const char*
00894 String::c_str() const
00895 {
00896    if (m_buf)
00897    {
00898       return m_buf->data();
00899    }
00900    else
00901    {
00902       return "";
00903    }
00904 }
00906 static const char cnullChar = '\0';
00907 const char&
00908 String::operator[] (size_t ndx) const
00909 {
00910 #ifdef OWBI1_DEBUG
00911    OW_ASSERT(ndx <= length());
00912 #endif
00913    // Don't need to check m_buf for NULL, because if length() == 0,
00914    // m_buf->data() won't be executed.
00915    //return (ndx <= length()) ? *(m_buf->data() + ndx) : cnullChar;
00916    if (ndx <= length())
00917    {
00918       return *(m_buf->data() + ndx);
00919    }
00920    else
00921    {
00922       return cnullChar;
00923    }
00924 }
00926 static char nullChar = '\0';
00927 char&
00928 String::operator[] (size_t ndx)
00929 {
00930 #ifdef OWBI1_DEBUG
00931    OW_ASSERT(ndx <= length());
00932 #endif
00933    // Don't need to check m_buf for NULL, because if length() == 0,
00934    // m_buf->data() won't be executed.
00935    return (ndx <= length()) ? m_buf->data()[ndx] : nullChar;
00936 }
00938 String
00939 String::toString() const
00940 {
00941    return *this;
00942 }
00944 static inline void
00945 throwStringConversion(const String::buf_t& m_buf, const char* type)
00946 {
00947    OWBI1_THROW(StringConversionException, Format("Unable to convert \"%1\" into %2", m_buf->data(), type).c_str());
00948 }
00950 static inline void
00951 throwStringConversion(const char* str, const char* type)
00952 {
00953    OWBI1_THROW(StringConversionException, Format("Unable to convert \"%1\" into %2", str, type).c_str());
00954 }
00956 template <typename T, typename FP>
00957 static inline
00958 T convertToRealType(const String::buf_t& m_buf, const char* type, FP fp)
00959 {
00960    if (m_buf)
00961    {
00962       char* endptr(0);
00963       errno = 0;     // errno is thread local
00964       T rv = fp(m_buf->data(), &endptr);
00965       if (*endptr != '\0' || errno == ERANGE || rv == HUGE_VAL || rv == -HUGE_VAL)
00966       {
00967          throwStringConversion(m_buf, type);
00968       }
00969       return rv;
00970    }
00971    else
00972    {
00973       throwStringConversion("", type);
00974    }
00975    return T(); // to make compiler happy
00976 }
00978 Real32
00979 String::toReal32() const
00980 {
00981 #if defined(OWBI1_REAL32_IS_FLOAT) && defined(OWBI1_HAVE_STRTOF)
00982    return convertToRealType<Real32>(m_buf, "Real32", &strtof);
00983 #elif defined(OWBI1_REAL32_IS_DOUBLE) || (defined(OWBI1_REAL32_IS_FLOAT) && !defined(OWBI1_HAVE_STRTOF))
00984    return convertToRealType<Real32>(m_buf, "Real32", &strtod);
00985 #endif
00986 }
00988 Real64
00989 String::toReal64() const
00990 {
00991 #if defined(OWBI1_REAL64_IS_DOUBLE)
00992    return convertToRealType<Real64>(m_buf, "Real64", &strtod);
00993 #elif defined(OWBI1_REAL64_IS_LONG_DOUBLE)
00994    return convertToRealType<Real64>(m_buf, "Real64", &strtold);
00995 #endif
00996 }
00998 bool
00999 String::toBool() const
01000 {
01001    if (equalsIgnoreCase("true"))
01002    {
01003       return true;
01004    }
01005    else if (equalsIgnoreCase("false"))
01006    {
01007       return false;
01008    }
01009    else
01010    {
01011       throwStringConversion(c_str(), "bool");
01012    }
01013    return false; // to make compiler happy
01014 }
01015 template <typename T, typename FP, typename FPRT>
01016 static inline
01017 T doConvertToIntType(const String::buf_t& m_buf, const char* type, FP fp, int base)
01018 {
01019    if (m_buf)
01020    {
01021       char* endptr(0);
01022       errno = 0;     // errno is thread local
01023       FPRT v = fp(m_buf->data(), &endptr, base);
01024       T rv = static_cast<T>(v);
01025       if (*endptr != '\0' || errno == ERANGE || FPRT(rv) != v)
01026       {
01027          throwStringConversion(m_buf, type);
01028       }
01029       return rv;
01030    }
01031    else
01032    {
01033       throwStringConversion("", type);
01034    }
01035    return T(); // to make compiler happy
01036 }
01037 typedef unsigned long int (*strtoulfp_t)(const char *, char **,int);
01038 typedef long int (*strtolfp_t)(const char *, char **,int);
01039 typedef unsigned long long int (*strtoullfp_t)(const char *, char **,int);
01040 typedef long long int (*strtollfp_t)(const char *, char **,int);
01041 template <typename T>
01042 static inline
01043 T convertToUIntType(const String::buf_t& m_buf, const char* msg, int base)
01044 {
01045    return doConvertToIntType<T, strtoulfp_t, unsigned long int>(m_buf, msg, &strtoul, base);
01046 }
01047 template <typename T>
01048 static inline
01049 T convertToIntType(const String::buf_t& m_buf, const char* msg, int base)
01050 {
01051    return doConvertToIntType<T, strtolfp_t, long int>(m_buf, msg, &strtol, base);
01052 }
01053 template <typename T>
01054 static inline
01055 T convertToUInt64Type(const String::buf_t& m_buf, const char* msg, int base)
01056 {
01057    return doConvertToIntType<T, strtoullfp_t, unsigned long long int>(m_buf, msg, &String::strtoull, base);
01058 }
01059 template <typename T>
01060 static inline
01061 T convertToInt64Type(const String::buf_t& m_buf, const char* msg, int base)
01062 {
01063    return doConvertToIntType<T, strtollfp_t, long long int>(m_buf, msg, &String::strtoll, base);
01064 }
01066 UInt8
01067 String::toUInt8(int base) const
01068 {
01069    return convertToUIntType<UInt8>(m_buf, "UInt8", base);
01070 }
01072 Int8
01073 String::toInt8(int base) const
01074 {
01075    return convertToIntType<Int8>(m_buf, "Int8", base);
01076 }
01078 UInt16
01079 String::toUInt16(int base) const
01080 {
01081    return convertToUIntType<UInt16>(m_buf, "UInt16", base);
01082 }
01084 Int16
01085 String::toInt16(int base) const
01086 {
01087    return convertToIntType<Int16>(m_buf, "Int16", base);
01088 }
01090 UInt32
01091 String::toUInt32(int base) const
01092 {
01093    return convertToUIntType<UInt32>(m_buf, "UInt32", base);
01094 }
01096 Int32
01097 String::toInt32(int base) const
01098 {
01099    return convertToIntType<Int32>(m_buf, "Int32", base);
01100 }
01102 UInt64
01103 String::toUInt64(int base) const
01104 {
01105    return convertToUInt64Type<UInt64>(m_buf, "UInt64", base);
01106 }
01108 Int64
01109 String::toInt64(int base) const
01110 {
01111    return convertToInt64Type<Int64>(m_buf, "Int64", base);
01112 }
01114 unsigned int
01115 String::toUnsignedInt(int base) const
01116 {
01117    return convertToUIntType<unsigned int>(m_buf, "unsigned int", base);
01118 }
01120 int
01121 String::toInt(int base) const
01122 {
01123    return convertToIntType<int>(m_buf, "int", base);
01124 }
01126 StringArray
01127 String::tokenize(const char* delims, EReturnDelimitersFlag returnDelimitersAsTokens, EEmptyTokenReturnFlag returnEmptyTokens) const
01128 {
01129    StringArray ra;
01130    if (empty())
01131    {
01132       return ra;
01133    }
01134    if (delims == 0)
01135    {
01136       ra.append(*this);
01137       return ra;
01138    }
01139    // Don't need to check m_buf for NULL, because if length() == 0,
01140    // this code won't be executed.
01141    char* pstr = m_buf->data();
01142    AutoPtrVec<char> data(new char[m_buf->length()+1]);
01143    data[0] = 0;
01144    int i = 0;
01145    bool last_was_delim = false;
01146    while (*pstr)
01147    {
01148       if (String::strchr(delims, *pstr))
01149       {
01150          if (data[0] != 0)
01151          {
01152             ra.append(String(data.get()));
01153             data[0] = 0;
01154          }
01155          if ( (returnEmptyTokens == E_RETURN_EMPTY_TOKENS) && last_was_delim )
01156          {
01157             ra.append(String());
01158          }
01159          if ( returnDelimitersAsTokens == E_RETURN_DELIMITERS )
01160          {
01161             ra.append(String(*pstr));
01162          }        
01163          i = 0;
01164          last_was_delim = true;
01165       }
01166       else
01167       {
01168          last_was_delim = false;
01169          data[i++] = *pstr;
01170          data[i] = 0;
01171       }
01172       pstr++;
01173    }
01174    if (data[0] != 0)
01175    {
01176       ra.append(String(data.get()));
01177    }
01178    return ra;
01179 }
01180 
01182 #ifdef OWBI1_HAVE_STRTOLL
01183 long long int
01184 String::strtoll(const char* nptr, char** endptr, int base)
01185 {
01186    return ::strtoll(nptr, endptr, base);
01187 }
01188 #else
01189 #ifndef LLONG_MAX
01190 #if OWBI1_SIZEOF_LONG_LONG_INT == 8
01191 #define LLONG_MAX 9223372036854775807LL
01192 #else
01193 #define LLONG_MAX 2147483647LL
01194 #endif
01195 #define LLONG_MIN (-LLONG_MAX - 1LL)
01196 #endif
01197 long long int
01198 String::strtoll(const char* nptr, char** endptr, int base)
01199 {
01200    const char *s;
01201    long long acc, cutoff;
01202    int c;
01203    int neg, any, cutlim;
01204    // Skip white space and pick up leading +/- sign if any.
01205    // If base is 0, allow 0x for hex and 0 for octal, else
01206    // assume decimal; if base is already 16, allow 0x.
01207    s = nptr;
01208    do
01209    {
01210       c = (unsigned char) *s++;
01211    } while (isspace(c));
01212    if (c == '-')
01213    {
01214       neg = 1;
01215       c = *s++;
01216    }
01217    else
01218    {
01219       neg = 0;
01220       if (c == '+')
01221       {
01222          c = *s++;
01223       }
01224    }
01225    if ((base == 0 || base == 16)
01226       && c == '0'
01227       && (*s == 'x' || *s == 'X'))
01228    {
01229       c = s[1];
01230       s += 2;
01231       base = 16;
01232    }
01233    if (base == 0)
01234    {
01235       base = c == '0' ? 8 : 10;
01236    }
01237    // Compute the cutoff value between legal numbers and illegal
01238    // numbers.  That is the largest legal value, divided by the
01239    // base.  An input number that is greater than this value, if
01240    // followed by a legal input character, is too big.  One that
01241    // is equal to this value may be valid or not; the limit
01242    // between valid and invalid numbers is then based on the last
01243    // digit.  For instance, if the range for longs is
01244    // [-2147483648..2147483647] and the input base is 10,
01245    // cutoff will be set to 214748364 and cutlim to either
01246    // 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
01247    // a value > 214748364, or equal but the next digit is > 7 (or 8),
01248    // the number is too big, and we will return a range error.
01249    //
01250    // Set any if any `digits' consumed; make it negative to indicate
01251    // overflow.
01252    cutoff = neg ? LLONG_MIN : LLONG_MAX;
01253    cutlim = static_cast<int>(cutoff % base);
01254    cutoff /= base;
01255    if (neg)
01256    {
01257       if (cutlim > 0)
01258       {
01259          cutlim -= base;
01260          cutoff += 1;
01261       }
01262       cutlim = -cutlim;
01263    }
01264    for (acc = 0, any = 0;; c = (unsigned char) *s++)
01265    {
01266       if (isdigit(c))
01267       {
01268          c -= '0';
01269       }
01270       else if (isalpha(c))
01271       {
01272          c -= isupper(c) ? 'A' - 10 : 'a' - 10;
01273       }
01274       else
01275       {
01276          break;
01277       }
01278       if (c >= base)
01279       {
01280          break;
01281       }
01282       if (any < 0)
01283       {
01284          continue;
01285       }
01286       if (neg)
01287       {
01288          if (acc < cutoff || acc == cutoff && c > cutlim)
01289          {
01290             any = -1;
01291             acc = LLONG_MIN;
01292             errno = ERANGE;
01293          }
01294          else
01295          {
01296             any = 1;
01297             acc *= base;
01298             acc -= c;
01299          }
01300       }
01301       else
01302       {
01303          if (acc > cutoff || acc == cutoff && c > cutlim)
01304          {
01305             any = -1;
01306             acc = LLONG_MAX;
01307             errno = ERANGE;
01308          }
01309          else
01310          {
01311             any = 1;
01312             acc *= base;
01313             acc += c;
01314          }
01315       }
01316    }
01317    if (endptr != 0)
01318    {
01319       *endptr = (char *) (any ? s - 1 : nptr);
01320    }
01321    return(acc);
01322 }
01323 #endif   // #ifdef OWBI1_HAVE_STRTOLL
01324 
01326 #ifdef OWBI1_HAVE_STRTOULL
01327 unsigned long long int
01328 String::strtoull(const char* nptr, char** endptr, int base)
01329 {
01330    return ::strtoull(nptr, endptr, base);
01331 }
01332 #else
01333 #ifndef ULLONG_MAX
01334 #if OWBI1_SIZEOF_LONG_LONG_INT == 8
01335 #define ULLONG_MAX 18446744073709551615ULL
01336 #else
01337 #define ULLONG_MAX 4294967295ULL
01338 #endif
01339 #endif
01340 unsigned long long int
01341 String::strtoull(const char* nptr, char** endptr, int base)
01342 {
01343    const char *s;
01344    unsigned long long acc, cutoff, cutlim;
01345    unsigned int c;
01346    int neg, any;
01347    s = nptr;
01348    do
01349    {
01350       c = (unsigned char) *s++;
01351    } while (isspace(c));
01352    if (c == '-')
01353    {
01354       neg = 1;
01355       c = *s++;
01356    }
01357    else
01358    {
01359       neg = 0;
01360       if (c == '+')
01361       {
01362          c = *s++;
01363       }
01364    }
01365    if ((base == 0 || base == 16)
01366       && c == '0'
01367       && (*s == 'x' || *s == 'X'))
01368    {
01369       c = s[1];
01370       s += 2;
01371       base = 16;
01372    }
01373    if (base == 0)
01374    {
01375       base = c == '0' ? 8 : 10;
01376    }
01377    cutoff = ULLONG_MAX / (unsigned long long)base;
01378    cutlim = ULLONG_MAX % (unsigned long long)base;
01379    for (acc = 0, any = 0;; c = (unsigned char) *s++)
01380    {
01381       if (isdigit(c))
01382       {
01383          c -= '0';
01384       }
01385       else if (isalpha(c))
01386       {
01387          c -= isupper(c) ? 'A' - 10 : 'a' - 10;
01388       }
01389       else
01390       {
01391          break;
01392       }
01393       if (c >= (unsigned int)base)
01394       {
01395          break;
01396       }
01397       if (any < 0)
01398       {
01399          continue;
01400       }
01401       if (acc > cutoff || acc == cutoff && c > cutlim)
01402       {
01403          any = -1;
01404          acc = ULLONG_MAX;
01405          errno = ERANGE;
01406       }
01407       else
01408       {
01409          any = 1;
01410          acc *= (unsigned long)base;
01411          acc += c;
01412       }
01413    }
01414    if (neg && any > 0)
01415    {
01416 #ifdef OWBI1_WIN32
01417 #pragma warning (push)
01418 #pragma warning (disable: 4146)
01419 #endif
01420 
01421       acc = -acc;
01422 
01423 #ifdef OWBI1_WIN32
01424 #pragma warning (pop)
01425 #endif
01426 
01427    }
01428    if (endptr != 0)
01429    {
01430       *endptr = (char *) (any ? s - 1 : nptr);
01431    }
01432    return(acc);
01433 }
01434 #endif   // #ifdef OWBI1_HAVE_STRTOULL
01435 
01436 String
01437 operator + (const String& s1, const String& s2)
01438 {
01439    String rstr(s1);
01440    rstr += s2;
01441    return rstr;
01442 }
01444 String
01445 operator + (const char* p, const String& s)
01446 {
01447    String rstr(p);
01448    rstr += s;
01449    return rstr;
01450 }
01452 String
01453 operator + (const String& s, const char* p)
01454 {
01455    String rstr(s);
01456    rstr += p;
01457    return rstr;
01458 }
01460 String
01461 operator + (char c, const String& s)
01462 {
01463    String rstr(c);
01464    rstr += s;
01465    return rstr;
01466 }
01468 String
01469 operator + (const String& s, char c)
01470 {
01471    String rstr(s);
01472    rstr += String(c);
01473    return rstr;
01474 }
01476 ostream&
01477 operator<< (ostream& ostr, const String& arg)
01478 {
01479    ostr.write(arg.c_str(), arg.length());
01480    return ostr;
01481 }
01483 // static
01484 String
01485 String::getLine(istream& is)
01486 {
01487    StringBuffer rv(80);
01488    rv.getLine(is);
01489    return String(rv.c_str());
01490 }
01492 // STATIC
01493 const char*
01494 String::strchr(const char* theStr, int c)
01495 {
01496    const char* tmpChar = theStr;
01497    for (; *tmpChar && *tmpChar != c; tmpChar++)
01498    {
01499       // empty
01500    }
01501    return ((*tmpChar) == c ? tmpChar : 0);
01502 }
01503 
01504 } // end namespace OWBI1
01505 

Generated on Thu Feb 9 08:48:29 2006 for openwbem by  doxygen 1.4.6