OW_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 "OW_config.h"
00037 #include "OW_String.hpp"
00038 #include "OW_Char16.hpp"
00039 #include "OW_CIMDateTime.hpp"
00040 #include "OW_CIMObjectPath.hpp"
00041 #include "OW_Array.hpp"
00042 #include "OW_StringStream.hpp"
00043 #include "OW_Format.hpp"
00044 #include "OW_BinarySerialization.hpp"
00045 #include "OW_Assertion.hpp"
00046 #include "OW_AutoPtr.hpp"
00047 #include "OW_Bool.hpp"
00048 #include "OW_UTF8Utils.hpp"
00049 #include "OW_ExceptionIds.hpp"
00050 #include "OW_COWIntrusiveCountableBase.hpp"
00051 
00052 #include <cstdio>
00053 #include <cstdlib>
00054 #include <cstring>
00055 #include <cctype>
00056 #include <cstdarg>
00057 #include <cerrno>
00058 #if defined(OW_HAVE_ISTREAM) && defined(OW_HAVE_OSTREAM)
00059 #include <istream>
00060 #include <ostream>
00061 #else
00062 #include <iostream>
00063 #endif
00064 #include <cmath> // for HUGE_VAL
00065 #include <cfloat> // for DBL_MANT_DIG
00066 
00067 #ifdef OW_WIN32
00068 #define SNPRINTF _snprintf
00069 #else
00070 #define SNPRINTF snprintf
00071 #endif
00072 
00073 namespace OW_NAMESPACE
00074 {
00075 
00076 using std::istream;
00077 using std::ostream;
00078 
00079 OW_DEFINE_EXCEPTION_WITH_ID(StringConversion);
00080 
00082 static inline int
00083 strncmpi(const char* s1, const char* s2, size_t n)
00084 {
00085    String ls1(s1, n);
00086    String ls2(s2, n);
00087    return ls1.compareToIgnoreCase(ls2);
00088 }
00089 
00090 // class invariant: m_buf points to a null-terminated sequence of characters. m_buf is m_len+1 bytes long.
00091 class String::ByteBuf : public COWIntrusiveCountableBase
00092 {
00093 public:
00094    ByteBuf(const char* s) :
00095       m_len(::strlen(s)), m_buf(new char[m_len+1])
00096    {
00097       strcpy(m_buf, s);
00098    }
00099 
00100    ByteBuf(const ByteBuf& arg)
00101       : COWIntrusiveCountableBase(arg)
00102       , m_len(arg.m_len)
00103       , m_buf(new char[m_len+1])
00104    {
00105       strcpy(m_buf, arg.m_buf);
00106    }
00107    
00108    ByteBuf(AutoPtrVec<char>& s, size_t len)
00109       : m_len(len), m_buf(s.release())
00110    {
00111    }
00112    
00113    ~ByteBuf() { delete [] m_buf; }
00114    
00115    ByteBuf& operator= (const ByteBuf& arg)
00116    {
00117       char* buf = new char[arg.m_len+1];
00118       strcpy(buf, arg.m_buf);
00119       delete [] m_buf;
00120       m_buf = buf;
00121       m_len = arg.m_len;
00122       return *this;
00123    }
00124    
00125    size_t length() const { return m_len; }
00126    char* data() const { return m_buf; }
00127    ByteBuf* clone() const { return new ByteBuf(*this); }
00128 private:
00129    size_t m_len;
00130    char* m_buf;
00131 };
00133 #if defined(OW_AIX)
00134 const size_t String::npos = ~0;
00135 #endif
00136 
00137 String::String() :
00138    m_buf(0)
00139 {
00140 }
00142 String::String(Bool parm) :
00143    m_buf(parm.toString().m_buf)
00144 {
00145 }
00147 String::String(const Char16& parm) :
00148    m_buf(parm.toString().m_buf)
00149 {
00150 }
00151 #if defined(OW_WIN32)
00152 #define snprintf _snprintf // stupid windoze...
00153 #endif
00154 
00155 String::String(Int32 val) :
00156    m_buf(NULL)
00157 {
00158    char tmpbuf[32];
00159    int len = snprintf(tmpbuf, sizeof(tmpbuf), "%d", val);
00160    AutoPtrVec<char> bfr(new char[len+1]);
00161    ::snprintf(bfr.get(), len+1, "%d", val);
00162    m_buf = new ByteBuf(bfr, len);
00163 }
00165 String::String(UInt32 val) :
00166    m_buf(NULL)
00167 {
00168    char tmpbuf[32];
00169    int len = ::snprintf(tmpbuf, sizeof(tmpbuf), "%u", val);
00170    AutoPtrVec<char> bfr(new char[len+1]);
00171    ::snprintf(bfr.get(), len+1, "%u", val);
00172    m_buf = new ByteBuf(bfr, len);
00173 }
00174 #if defined(OW_INT32_IS_INT) && defined(OW_INT64_IS_LONG_LONG)
00175 
00176 String::String(long val) :
00177    m_buf(NULL)
00178 {
00179    char tmpbuf[32];
00180    int len = snprintf(tmpbuf, sizeof(tmpbuf), "%ld", val);
00181    AutoPtrVec<char> bfr(new char[len+1]);
00182    ::snprintf(bfr.get(), len+1, "%ld", val);
00183    m_buf = new ByteBuf(bfr, len);
00184 }
00186 String::String(unsigned long val) :
00187    m_buf(NULL)
00188 {
00189    char tmpbuf[32];
00190    int len = ::snprintf(tmpbuf, sizeof(tmpbuf), "%lu", val);
00191    AutoPtrVec<char> bfr(new char[len+1]);
00192    ::snprintf(bfr.get(), len+1, "%lu", val);
00193    m_buf = new ByteBuf(bfr, len);
00194 }
00195 #endif
00196 #if defined(OW_WIN32)
00197 #undef snprintf
00198 #endif
00199 
00200 String::String(Int64 val) :
00201    m_buf(NULL)
00202 {
00203    OStringStream ss(33);
00204    ss << val;
00205    m_buf = new ByteBuf(ss.c_str());
00206 }
00208 String::String(UInt64 val) :
00209    m_buf(NULL)
00210 {
00211 #if defined(OW_INT64_IS_LONG)
00212    char tmpbuf[32];
00213    ::snprintf(tmpbuf, sizeof(tmpbuf), "%lu", val);
00214    m_buf = new ByteBuf(tmpbuf);
00215 #elif defined(OW_INT64_IS_LONG_LONG)
00216    // unfortunately not all C libraries support long long with snprintf().
00217    // but the C++ iostream library handles it.
00218    OStringStream ss;
00219    ss << val;
00220    m_buf = new ByteBuf(ss.c_str());
00221 #endif
00222 }
00224 // decimal digits = ceiling((bits)*ln(2)/ln(10))
00225 String::String(Real32 val) :
00226    m_buf(NULL)
00227 {
00228    char tmpbuf[128];
00229 #if FLT_RADIX == 2
00230 #if defined(OW_REAL32_IS_FLOAT)
00231 	::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*g", FLT_MANT_DIG * 3 / 10 + 1, static_cast<double>(val));
00232 #elif defined(OW_REAL32_IS_DOUBLE)
00233 	::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, val);
00234 #endif
00235 #else
00236 #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))"
00237 #endif
00238    m_buf = new ByteBuf(tmpbuf);
00239 }
00241 String::String(Real64 val) :
00242    m_buf(NULL)
00243 {
00244    char tmpbuf[128];
00245 #if FLT_RADIX == 2
00246 #if defined(OW_REAL64_IS_DOUBLE)
00247 	::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, val);
00248 #elif defined(OW_REAL64_IS_LONG_DOUBLE)
00249 	::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*Lg", LDBL_MANT_DIG * 3 / 10 + 1, val);
00250 #endif
00251 #else
00252 #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))"
00253 #endif
00254    m_buf = new ByteBuf(tmpbuf);
00255 }
00257 String::String(const char* str) :
00258    m_buf(NULL)
00259 {
00260    m_buf = (NULL == str) ? 0 : new ByteBuf(str);
00261 }
00263 String::String(ETakeOwnershipFlag, char* allocatedMemory, size_t len) :
00264    m_buf(NULL)
00265 {
00266    OW_ASSERT(allocatedMemory != 0);
00267    AutoPtrVec<char> p(allocatedMemory);
00268    m_buf = new ByteBuf(p, len);
00269 }
00271 String::String(const char* str, size_t len) :
00272    m_buf(NULL)
00273 {
00274    if (NULL == str)
00275    {
00276       m_buf = 0;
00277    }
00278    else
00279    {
00280       AutoPtrVec<char> bfr(new char[len+1]);
00281       ::memcpy(bfr.get(), str, len);
00282       bfr[len] = '\0';
00283       m_buf = new ByteBuf(bfr, len);
00284    }
00285 }
00287 String::String(const String& arg) :
00288    m_buf(arg.m_buf)
00289 {
00290 }
00292 String::String(const CIMDateTime& parm) :
00293    m_buf(NULL)
00294 {
00295    String s = parm.toString();
00296    m_buf = s.m_buf;
00297 }
00299 String::String(const CIMObjectPath& parm) :
00300    m_buf(NULL)
00301 {
00302    String s = parm.toString();
00303    m_buf = s.m_buf;
00304 }
00306 String::String(const Char16Array& ra) :
00307    m_buf(NULL)
00308 {
00309    size_t sz = ra.size();
00310    if (sz > 0)
00311    {
00312       StringBuffer buf(sz * 2);
00313       for (size_t i = 0; i < sz; i++)
00314       {
00315          buf += ra[i].toString();
00316       }
00317       m_buf = buf.releaseString().m_buf;
00318    }
00319    else
00320    {
00321       m_buf = 0;
00322    }
00323 }
00325 String::String(char c) :
00326    m_buf(NULL)
00327 {
00328    if (c != '\0')
00329    {
00330       char bfr[2];
00331       bfr[0] = c;
00332       bfr[1] = '\0';
00333       m_buf = new ByteBuf(bfr);
00334    }
00335    else
00336    {
00337       m_buf = 0;
00338    }
00339 }
00341 String::~String() 
00342 {
00343 }
00345 void
00346 String::swap(String& x)
00347 {
00348    m_buf.swap(x.m_buf);
00349 }
00351 char*
00352 String::allocateCString() const
00353 {
00354    size_t len = length() + 1;
00355    char* str = static_cast<char*>(malloc(len));
00356    ::strcpy(str, c_str());
00357    return str;
00358 }
00360 size_t
00361 String::length() const
00362 {
00363    return (m_buf) ? m_buf->length() : 0;
00364 }
00366 size_t
00367 String::UTF8Length() const
00368 {
00369    return UTF8Utils::charCount(c_str());
00370 }
00372 #ifdef OW_WIN32
00373 #define vsnprintf _vsnprintf // stupid windoze
00374 #endif
00375 int
00376 String::format(const char* fmt, ...)
00377 {
00378    int n, size = 64;
00379    AutoPtrVec<char> p(new char[size]);
00380    
00381    va_list ap;
00382    
00383    // Try to print in the allocated space
00384    while (true)
00385    {
00386       va_start(ap, fmt);
00387       n = vsnprintf(p.get(), size, fmt, ap);
00388       va_end(ap);                // If that worked, return the string.
00389       if (n > -1 && n < size)
00390       {
00391          m_buf = new ByteBuf(p, n);
00392          return static_cast<int>(length());
00393       }
00394       if (n > -1)    // glibc 2.1
00395          size = n+1; // precisely what is needed
00396       else           // glibc 2.0
00397          size *= 2;  // twice the old size
00398       p = new char[size];
00399    }
00400 }
00401 #ifdef OW_WIN32
00402 #undef vsnprintf // stupid windoze
00403 #endif
00404 
00405 char
00406 String::charAt(size_t ndx) const
00407 {
00408    return (m_buf) ? m_buf->data()[ndx] : '\0';
00409 }
00411 int
00412 String::compareTo(const char* arg) const
00413 {
00414    const char* lhs = "";
00415    if (m_buf)
00416    {
00417       lhs = m_buf->data();
00418    }
00419    return ::strcmp(lhs, arg);
00420 }
00422 int
00423 String::compareTo(const String& arg) const
00424 {
00425    return compareTo(arg.c_str());
00426 }
00428 int
00429 String::compareToIgnoreCase(const char* arg) const
00430 {
00431    const char* lhs = "";
00432    if (m_buf)
00433    {
00434       lhs = m_buf->data();
00435    }
00436    return UTF8Utils::compareToIgnoreCase(lhs, arg);
00437 }
00439 int
00440 String::compareToIgnoreCase(const String& arg) const
00441 {
00442    return compareToIgnoreCase(arg.c_str());
00443 }
00444 
00446 String&
00447 String::concat(const char* arg)
00448 {
00449    if (arg && *arg)
00450    {
00451       size_t len = length() + ::strlen(arg);
00452       AutoPtrVec<char> bfr(new char[len+1]);
00453       bfr[0] = 0;
00454       if (m_buf)
00455       {
00456          ::strcpy(bfr.get(), m_buf->data());
00457       }
00458       ::strcat(bfr.get(), arg);
00459       m_buf = new ByteBuf(bfr, len);
00460    }
00461    return *this;
00462 }
00463 
00465 String&
00466 String::concat(char arg)
00467 {
00468    size_t newlen = length() + 1;
00469    AutoPtrVec<char> bfr(new char[newlen+1]);
00470    bfr[0] = 0;
00471    if (m_buf)
00472    {
00473       ::strcpy(bfr.get(), m_buf->data());
00474    }
00475    *(bfr.get()+length()) = arg;
00476    *(bfr.get()+newlen) = 0;
00477    m_buf = new ByteBuf(bfr, newlen);
00478    return *this;
00479 }
00480 
00482 bool
00483 String::endsWith(char arg) const
00484 {
00485    return (m_buf
00486          && m_buf->length()
00487          && m_buf->data()[m_buf->length()-1] == arg);
00488 }
00489 
00491 bool
00492 String::endsWith(const char* arg, EIgnoreCaseFlag ignoreCase) const
00493 {
00494    if (!arg || !*arg)
00495    {
00496       return (length() == 0);
00497    }
00498 
00499    if (!m_buf)
00500    {
00501       return false;
00502    }
00503 
00504    int ndx = static_cast<int>(length() - ::strlen(arg));
00505    if (ndx < 0)
00506    {
00507       return false;
00508    }
00509 
00510    return (ignoreCase)
00511       ? (UTF8Utils::compareToIgnoreCase(m_buf->data()+ndx, arg) == 0)
00512       : (::strcmp(m_buf->data()+ndx, arg) == 0);
00513 }
00515 bool
00516 String::equals(const char* arg) const
00517 {
00518    return(compareTo(arg) == 0);
00519 }
00521 bool
00522 String::equals(const String& arg) const
00523 {
00524    return equals(arg.c_str());
00525 }
00527 bool
00528 String::equalsIgnoreCase(const char* arg) const
00529 {
00530    return(compareToIgnoreCase(arg) == 0);
00531 }
00533 bool
00534 String::equalsIgnoreCase(const String& arg) const
00535 {
00536    return equalsIgnoreCase(arg.c_str());
00537 }
00539 UInt32
00540 String::hashCode() const
00541 {
00542    UInt32 hash = 0;
00543    size_t len = length();
00544    for (size_t i = 0; i < len; i++)
00545    {
00546       // Don't need to check if m_buf is null, because if it is, len == 0,
00547       // and this loop won't be executed.
00548       const char temp = m_buf->data()[i];
00549       hash = (hash << 4) + (temp * 13);
00550       UInt32 g = hash & 0xf0000000;
00551       if (g)
00552       {
00553          hash ^= (g >> 24);
00554          hash ^= g;
00555       }
00556    }
00557    return hash;
00558 }
00560 size_t
00561 String::indexOf(char ch, size_t fromIndex) const
00562 {
00563    //if (fromIndex < 0)
00564    //{
00565    // fromIndex = 0;
00566    //}
00567    size_t cc = npos;
00568    if (fromIndex < length())
00569    {
00570       // Don't need to check m_buf for NULL, because if length() == 0,
00571       // this code won't be executed.
00572       const char* p = String::strchr(m_buf->data()+fromIndex, ch);
00573       if (p)
00574       {
00575          cc = p - m_buf->data();
00576       }
00577    }
00578    return cc;
00579 }
00581 size_t
00582 String::indexOf(const char* arg, size_t fromIndex) const
00583 {
00584    int cc = npos;
00585    if (fromIndex < length())
00586    {
00587       // Don't need to check m_buf for NULL, because if length() == 0,
00588       // this code won't be executed, but we do need to check arg.m_buf
00589       char* p(0);
00590       if (arg && *arg)
00591       {
00592          p = ::strstr(m_buf->data()+fromIndex, arg);
00593       }
00594       else
00595       {
00596          p = m_buf->data()+fromIndex;
00597       }
00598 
00599       if (p != NULL)
00600       {
00601          cc = static_cast<int>(p - m_buf->data());
00602       }
00603    }
00604    return cc;
00605 }
00607 size_t
00608 String::lastIndexOf(char ch, size_t fromIndex) const
00609 {
00610    if (fromIndex == npos)
00611    {
00612       if ((fromIndex = length()-1) == npos)
00613       {
00614          return npos;
00615       }
00616    }
00617    size_t cc = npos;
00618    if (fromIndex < length())
00619    {
00620       for (size_t i = fromIndex; i != npos; i--)
00621       {
00622          // Don't need to check m_buf for NULL, because if length() == 0,
00623          // this code won't be executed.
00624          if (m_buf->data()[i] == ch)
00625          {
00626             cc = i;
00627             break;
00628          }
00629       }
00630    }
00631    return cc;
00632 }
00634 size_t
00635 String::lastIndexOf(const char* arg, size_t fromIndex) const
00636 {
00637    if (fromIndex == npos || fromIndex >= length())
00638    {
00639       if (static_cast<int>(fromIndex = length()-1) < 0)
00640       {
00641          return npos;
00642       }
00643    }
00644 
00645    int arglen = (arg) ? ::strlen(arg) : 0;
00646    if (static_cast<int>(fromIndex -= arglen - 1) < 0)
00647    {
00648       return npos;
00649    }
00650    if (!arg)
00651    {
00652       return length() - 1;
00653    }
00654    while (fromIndex != npos)
00655    {
00656       // Don't need to check m_buf for NULL, because if length() == 0,
00657       // this code won't be executed.
00658       if (::strncmp(m_buf->data()+fromIndex, arg, arglen) == 0)
00659       {
00660          break;
00661       }
00662       fromIndex--;
00663    }
00664    return fromIndex;
00665 }
00667 bool
00668 String::startsWith(char arg) const
00669 {
00670    return (m_buf
00671          && m_buf->length()
00672          && m_buf->data()[0] == arg);
00673 }
00674 
00676 bool
00677 String::startsWith(const char* arg, EIgnoreCaseFlag ignoreCase) const
00678 {
00679    bool cc = false;
00680    if (!arg && !m_buf)
00681    {
00682       return true;
00683    }
00684    if (!*arg)
00685    {
00686       return (length() == 0);
00687    }
00688 
00689    size_t arglen = ::strlen(arg);
00690    if (arglen <= length())
00691    {
00692       // Don't need to check m_buf for NULL, because if length() == 0,
00693       // this code won't be executed.
00694       if (ignoreCase)
00695       {
00696          cc = (strncmpi(m_buf->data(), arg, arglen) == 0);
00697       }
00698       else
00699       {
00700          cc = (::strncmp(m_buf->data(), arg, arglen) == 0);
00701       }
00702    }
00703    return cc;
00704 }
00706 String
00707 String::substring(size_t beginIndex, size_t len) const
00708 {
00709    String nil;
00710    size_t count = len;
00711    size_t l = length();
00712    if (0 == l)
00713    {
00714       return nil;
00715    }
00716    if (beginIndex >= l)
00717    {
00718       return nil;
00719    }
00720    else if (0 == len)
00721    {
00722       return nil;
00723    }
00724    else if (len == npos)
00725    {
00726       count = l - beginIndex;
00727    }
00728    if (count + beginIndex > l)
00729    {
00730       count = l - beginIndex;
00731    }
00732    // Don't need to check m_buf for NULL, because if length() == 0,
00733    // this code won't be executed.
00734    return String(static_cast<const char*>(m_buf->data()+beginIndex), count);
00735 }
00737 bool
00738 String::isSpaces() const
00739 {
00740    if (!m_buf)
00741    {
00742       return true;
00743    }
00744    char* p = m_buf->data();
00745    while (isspace(*p) && *p != '\0')
00746    {
00747       p++;
00748    }
00749    return (*p == '\0');
00750 }
00752 String&
00753 String::ltrim()
00754 {
00755    if (!m_buf)
00756    {
00757       return *this;
00758    }
00759    char* s1 = m_buf->data();
00760    while (isspace(*s1) && *s1 != '\0')
00761    {
00762       s1++;
00763    }
00764    if (s1 == m_buf->data())
00765    {
00766       return *this;
00767    }
00768    *this = String(s1);
00769    return *this;
00770 }
00772 String&
00773 String::rtrim()
00774 {
00775    if (length() == 0)
00776    {
00777       return *this;
00778    }
00779    char* s1 = m_buf->data() + (length()-1);
00780    while (isspace(*s1) && s1 >= m_buf->data())
00781    {
00782       s1--;
00783    }
00784    if (s1 == (m_buf->data() + (length()-1)))
00785    {
00786       return *this;
00787    }
00788    if (s1 < m_buf->data())
00789    {
00790       *this = String();
00791       return *this;
00792    }
00793    size_t len = (s1 - m_buf->data()) + 1;
00794    *this = String(m_buf->data(), len);
00795    return *this;
00796 }
00798 String&
00799 String::trim()
00800 {
00801    if (length() == 0)
00802    {
00803       return *this;
00804    }
00805    char* s1 = m_buf->data();
00806    while (isspace(*s1) && *s1 != '\0')
00807    {
00808       s1++;
00809    }
00810    if (*s1 == '\0')
00811    {
00812       // String is all spaces
00813       *this = String();
00814       return *this;
00815    }
00816    const char* p2 = String::strchr(s1, '\0');
00817    const char* s2 = p2 - 1;
00818    while (isspace(*s2))
00819    {
00820       s2--;
00821    }
00822    if (s1 == m_buf->data() && s2 == p2)
00823    {
00824       // String has no leading or trailing spaces
00825       return *this;
00826    }
00827    size_t len = (s2 - s1) + 1;
00828    *this = String(s1, len);
00829    return *this;
00830 }
00832 String&
00833 String::erase()
00834 {
00835    m_buf = 0;
00836    return *this;
00837 }
00839 String&
00840 String::erase(size_t idx, size_t len)
00841 {
00842    if ( idx >= length() )
00843    {
00844       return *this;
00845    }
00846    if (len == npos)
00847    {
00848       *this = substring(0, idx);
00849    }
00850    else
00851    {
00852       *this = substring(0, idx) + substring(idx + len);
00853    }
00854    return *this;
00855 }
00857 String&
00858 String::toLowerCase()
00859 {
00860    if (m_buf)
00861    {
00862       if (!UTF8Utils::toLowerCaseInPlace(m_buf->data()))
00863       {
00864          *this = UTF8Utils::toLowerCase(m_buf->data());
00865       }
00866    }
00867    return *this;
00868 }
00869 
00871 String&
00872 String::toUpperCase()
00873 {
00874    if (m_buf)
00875    {
00876       if (!UTF8Utils::toUpperCaseInPlace(m_buf->data()))
00877       {
00878          *this = UTF8Utils::toUpperCase(m_buf->data());
00879       }
00880    }
00881    return *this;
00882 }
00884 void
00885 String::readObject(istream& istrm)
00886 {
00887    UInt32 len;
00888    BinarySerialization::readLen(istrm, len);
00889    AutoPtrVec<char> bfr(new char[len+1]);
00890    BinarySerialization::read(istrm, bfr.get(), len);
00891    bfr[len] = '\0';
00892    m_buf = new ByteBuf(bfr, len);
00893 }
00895 void
00896 String::writeObject(ostream& ostrm) const
00897 {
00898    UInt32 len = static_cast<UInt32>(length());
00899    BinarySerialization::writeLen(ostrm, len);
00900    if (len)
00901    {
00902       BinarySerialization::write(ostrm, m_buf->data(), len);
00903    }
00904 }
00906 String&
00907 String::operator= (const String& arg)
00908 {
00909    m_buf = arg.m_buf;
00910    return *this;
00911 }
00913 const char*
00914 String::c_str() const
00915 {
00916    if (m_buf)
00917    {
00918       return m_buf->data();
00919    }
00920    else
00921    {
00922       return "";
00923    }
00924 }
00926 static const char cnullChar = '\0';
00927 const char&
00928 String::operator[] (size_t ndx) const
00929 {
00930 #ifdef OW_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) : cnullChar;
00936    if (ndx <= length())
00937    {
00938       return *(m_buf->data() + ndx);
00939    }
00940    else
00941    {
00942       return cnullChar;
00943    }
00944 }
00946 static char nullChar = '\0';
00947 char&
00948 String::operator[] (size_t ndx)
00949 {
00950 #ifdef OW_DEBUG
00951    OW_ASSERT(ndx <= length());
00952 #endif
00953    // Don't need to check m_buf for NULL, because if length() == 0,
00954    // m_buf->data() won't be executed.
00955    return (ndx <= length()) ? m_buf->data()[ndx] : nullChar;
00956 }
00958 String
00959 String::toString() const
00960 {
00961    return *this;
00962 }
00964 static inline void
00965 throwStringConversion(const String::buf_t& m_buf, const char* type)
00966 {
00967    OW_THROW(StringConversionException, Format("Unable to convert \"%1\" into %2", m_buf->data(), type).c_str());
00968 }
00970 static inline void
00971 throwStringConversion(const char* str, const char* type)
00972 {
00973    OW_THROW(StringConversionException, Format("Unable to convert \"%1\" into %2", str, type).c_str());
00974 }
00976 Char16
00977 String::toChar16() const
00978 {
00979    if (UTF8Length() != 1)
00980    {
00981       throwStringConversion(c_str(), "Char16");
00982    }
00983    return Char16(*this);
00984 }
00985 template <typename T, typename FP>
00986 static inline
00987 T convertToRealType(const String::buf_t& m_buf, const char* type, FP fp)
00988 {
00989    if (m_buf)
00990    {
00991       char* endptr(0);
00992       errno = 0;     // errno is thread local
00993       T rv = fp(m_buf->data(), &endptr);
00994       if (*endptr != '\0' || errno == ERANGE || rv == HUGE_VAL || rv == -HUGE_VAL)
00995       {
00996          throwStringConversion(m_buf, type);
00997       }
00998       return rv;
00999    }
01000    else
01001    {
01002       throwStringConversion("", type);
01003    }
01004    return T(); // to make compiler happy
01005 }
01007 Real32
01008 String::toReal32() const
01009 {
01010 #if defined(OW_REAL32_IS_FLOAT) && defined(OW_HAVE_STRTOF)
01011    return convertToRealType<Real32>(m_buf, "Real32", &strtof);
01012 #elif defined(OW_REAL32_IS_DOUBLE) || (defined(OW_REAL32_IS_FLOAT) && !defined(OW_HAVE_STRTOF))
01013    return convertToRealType<Real32>(m_buf, "Real32", &strtod);
01014 #endif
01015 }
01017 Real64
01018 String::toReal64() const
01019 {
01020 #if defined(OW_REAL64_IS_DOUBLE)
01021    return convertToRealType<Real64>(m_buf, "Real64", &strtod);
01022 #elif defined(OW_REAL64_IS_LONG_DOUBLE)
01023    return convertToRealType<Real64>(m_buf, "Real64", &strtold);
01024 #endif
01025 }
01027 bool
01028 String::toBool() const
01029 {
01030    if (equalsIgnoreCase("true"))
01031    {
01032       return true;
01033    }
01034    else if (equalsIgnoreCase("false"))
01035    {
01036       return false;
01037    }
01038    else
01039    {
01040       throwStringConversion(c_str(), "bool");
01041    }
01042    return false; // to make compiler happy
01043 }
01044 template <typename T, typename FP, typename FPRT>
01045 static inline
01046 T doConvertToIntType(const String::buf_t& m_buf, const char* type, FP fp, int base)
01047 {
01048    if (m_buf)
01049    {
01050       char* endptr(0);
01051       errno = 0;     // errno is thread local
01052       FPRT v = fp(m_buf->data(), &endptr, base);
01053       T rv = static_cast<T>(v);
01054       if (*endptr != '\0' || errno == ERANGE || FPRT(rv) != v)
01055       {
01056          throwStringConversion(m_buf, type);
01057       }
01058       return rv;
01059    }
01060    else
01061    {
01062       throwStringConversion("", type);
01063    }
01064    return T(); // to make compiler happy
01065 }
01066 typedef unsigned long int (*strtoulfp_t)(const char *, char **,int);
01067 typedef long int (*strtolfp_t)(const char *, char **,int);
01068 typedef unsigned long long int (*strtoullfp_t)(const char *, char **,int);
01069 typedef long long int (*strtollfp_t)(const char *, char **,int);
01070 template <typename T>
01071 static inline
01072 T convertToUIntType(const String::buf_t& m_buf, const char* msg, int base)
01073 {
01074    return doConvertToIntType<T, strtoulfp_t, unsigned long int>(m_buf, msg, &strtoul, base);
01075 }
01076 template <typename T>
01077 static inline
01078 T convertToIntType(const String::buf_t& m_buf, const char* msg, int base)
01079 {
01080    return doConvertToIntType<T, strtolfp_t, long int>(m_buf, msg, &strtol, base);
01081 }
01082 template <typename T>
01083 static inline
01084 T convertToUInt64Type(const String::buf_t& m_buf, const char* msg, int base)
01085 {
01086    return doConvertToIntType<T, strtoullfp_t, unsigned long long int>(m_buf, msg, &String::strtoull, base);
01087 }
01088 template <typename T>
01089 static inline
01090 T convertToInt64Type(const String::buf_t& m_buf, const char* msg, int base)
01091 {
01092    return doConvertToIntType<T, strtollfp_t, long long int>(m_buf, msg, &String::strtoll, base);
01093 }
01095 UInt8
01096 String::toUInt8(int base) const
01097 {
01098    return convertToUIntType<UInt8>(m_buf, "UInt8", base);
01099 }
01101 Int8
01102 String::toInt8(int base) const
01103 {
01104    return convertToIntType<Int8>(m_buf, "Int8", base);
01105 }
01107 UInt16
01108 String::toUInt16(int base) const
01109 {
01110    return convertToUIntType<UInt16>(m_buf, "UInt16", base);
01111 }
01113 Int16
01114 String::toInt16(int base) const
01115 {
01116    return convertToIntType<Int16>(m_buf, "Int16", base);
01117 }
01119 UInt32
01120 String::toUInt32(int base) const
01121 {
01122    return convertToUIntType<UInt32>(m_buf, "UInt32", base);
01123 }
01125 Int32
01126 String::toInt32(int base) const
01127 {
01128    return convertToIntType<Int32>(m_buf, "Int32", base);
01129 }
01131 UInt64
01132 String::toUInt64(int base) const
01133 {
01134    return convertToUInt64Type<UInt64>(m_buf, "UInt64", base);
01135 }
01137 Int64
01138 String::toInt64(int base) const
01139 {
01140    return convertToInt64Type<Int64>(m_buf, "Int64", base);
01141 }
01143 unsigned int
01144 String::toUnsignedInt(int base) const
01145 {
01146    return convertToUIntType<unsigned int>(m_buf, "unsigned int", base);
01147 }
01149 int
01150 String::toInt(int base) const
01151 {
01152    return convertToIntType<int>(m_buf, "int", base);
01153 }
01155 CIMDateTime
01156 String::toDateTime() const
01157 {
01158    return CIMDateTime(*this);
01159 }
01161 StringArray
01162 String::tokenize(const char* delims, EReturnDelimitersFlag returnDelimitersAsTokens, EEmptyTokenReturnFlag returnEmptyTokens) const
01163 {
01164    StringArray ra;
01165    if (empty())
01166    {
01167       return ra;
01168    }
01169    if (delims == 0)
01170    {
01171       ra.append(*this);
01172       return ra;
01173    }
01174    // Don't need to check m_buf for NULL, because if length() == 0,
01175    // this code won't be executed.
01176    char* pstr = m_buf->data();
01177    AutoPtrVec<char> data(new char[m_buf->length()+1]);
01178    data[0] = 0;
01179    int i = 0;
01180    bool last_was_delim = false;
01181    while (*pstr)
01182    {
01183       if (String::strchr(delims, *pstr))
01184       {
01185          if (data[0] != 0)
01186          {
01187             ra.append(String(data.get()));
01188             data[0] = 0;
01189          }
01190          if ( (returnEmptyTokens == E_RETURN_EMPTY_TOKENS) && last_was_delim )
01191          {
01192             ra.append(String());
01193          }
01194          if ( returnDelimitersAsTokens == E_RETURN_DELIMITERS || returnDelimitersAsTokens == E_RETURN_TOKENS )
01195          {
01196             ra.append(String(*pstr));
01197          }        
01198          i = 0;
01199          last_was_delim = true;
01200       }
01201       else
01202       {
01203          last_was_delim = false;
01204          data[i++] = *pstr;
01205          data[i] = 0;
01206       }
01207       pstr++;
01208    }
01209    if (data[0] != 0)
01210    {
01211       ra.append(String(data.get()));
01212    }
01213    return ra;
01214 }
01215 
01217 #ifdef OW_HAVE_STRTOLL
01218 long long int
01219 String::strtoll(const char* nptr, char** endptr, int base)
01220 {
01221    return ::strtoll(nptr, endptr, base);
01222 }
01223 #else
01224 #ifndef LLONG_MAX
01225 #if OW_SIZEOF_LONG_LONG_INT == 8
01226 #define LLONG_MAX 9223372036854775807LL
01227 #else
01228 #define LLONG_MAX 2147483647LL
01229 #endif
01230 #define LLONG_MIN (-LLONG_MAX - 1LL)
01231 #endif
01232 long long int
01233 String::strtoll(const char* nptr, char** endptr, int base)
01234 {
01235    const char *s;
01236    long long acc, cutoff;
01237    int c;
01238    int neg, any, cutlim;
01239    // Skip white space and pick up leading +/- sign if any.
01240    // If base is 0, allow 0x for hex and 0 for octal, else
01241    // assume decimal; if base is already 16, allow 0x.
01242    s = nptr;
01243    do
01244    {
01245       c = (unsigned char) *s++;
01246    } while (isspace(c));
01247    if (c == '-')
01248    {
01249       neg = 1;
01250       c = *s++;
01251    }
01252    else
01253    {
01254       neg = 0;
01255       if (c == '+')
01256       {
01257          c = *s++;
01258       }
01259    }
01260    if ((base == 0 || base == 16)
01261       && c == '0'
01262       && (*s == 'x' || *s == 'X'))
01263    {
01264       c = s[1];
01265       s += 2;
01266       base = 16;
01267    }
01268    if (base == 0)
01269    {
01270       base = c == '0' ? 8 : 10;
01271    }
01272    // Compute the cutoff value between legal numbers and illegal
01273    // numbers.  That is the largest legal value, divided by the
01274    // base.  An input number that is greater than this value, if
01275    // followed by a legal input character, is too big.  One that
01276    // is equal to this value may be valid or not; the limit
01277    // between valid and invalid numbers is then based on the last
01278    // digit.  For instance, if the range for longs is
01279    // [-2147483648..2147483647] and the input base is 10,
01280    // cutoff will be set to 214748364 and cutlim to either
01281    // 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
01282    // a value > 214748364, or equal but the next digit is > 7 (or 8),
01283    // the number is too big, and we will return a range error.
01284    //
01285    // Set any if any `digits' consumed; make it negative to indicate
01286    // overflow.
01287    cutoff = neg ? LLONG_MIN : LLONG_MAX;
01288    cutlim = static_cast<int>(cutoff % base);
01289    cutoff /= base;
01290    if (neg)
01291    {
01292       if (cutlim > 0)
01293       {
01294          cutlim -= base;
01295          cutoff += 1;
01296       }
01297       cutlim = -cutlim;
01298    }
01299    for (acc = 0, any = 0;; c = (unsigned char) *s++)
01300    {
01301       if (isdigit(c))
01302       {
01303          c -= '0';
01304       }
01305       else if (isalpha(c))
01306       {
01307          c -= isupper(c) ? 'A' - 10 : 'a' - 10;
01308       }
01309       else
01310       {
01311          break;
01312       }
01313       if (c >= base)
01314       {
01315          break;
01316       }
01317       if (any < 0)
01318       {
01319          continue;
01320       }
01321       if (neg)
01322       {
01323          if (acc < cutoff || acc == cutoff && c > cutlim)
01324          {
01325             any = -1;
01326             acc = LLONG_MIN;
01327             errno = ERANGE;
01328          }
01329          else
01330          {
01331             any = 1;
01332             acc *= base;
01333             acc -= c;
01334          }
01335       }
01336       else
01337       {
01338          if (acc > cutoff || acc == cutoff && c > cutlim)
01339          {
01340             any = -1;
01341             acc = LLONG_MAX;
01342             errno = ERANGE;
01343          }
01344          else
01345          {
01346             any = 1;
01347             acc *= base;
01348             acc += c;
01349          }
01350       }
01351    }
01352    if (endptr != 0)
01353    {
01354       *endptr = (char *) (any ? s - 1 : nptr);
01355    }
01356    return(acc);
01357 }
01358 #endif   // #ifdef OW_HAVE_STRTOLL
01359 
01361 #ifdef OW_HAVE_STRTOULL
01362 unsigned long long int
01363 String::strtoull(const char* nptr, char** endptr, int base)
01364 {
01365    return ::strtoull(nptr, endptr, base);
01366 }
01367 #else
01368 #ifndef ULLONG_MAX
01369 #if OW_SIZEOF_LONG_LONG_INT == 8
01370 #define ULLONG_MAX 18446744073709551615ULL
01371 #else
01372 #define ULLONG_MAX 4294967295ULL
01373 #endif
01374 #endif
01375 unsigned long long int
01376 String::strtoull(const char* nptr, char** endptr, int base)
01377 {
01378    const char *s;
01379    unsigned long long acc, cutoff, cutlim;
01380    unsigned int c;
01381    int neg, any;
01382    s = nptr;
01383    do
01384    {
01385       c = (unsigned char) *s++;
01386    } while (isspace(c));
01387    if (c == '-')
01388    {
01389       neg = 1;
01390       c = *s++;
01391    }
01392    else
01393    {
01394       neg = 0;
01395       if (c == '+')
01396       {
01397          c = *s++;
01398       }
01399    }
01400    if ((base == 0 || base == 16)
01401       && c == '0'
01402       && (*s == 'x' || *s == 'X'))
01403    {
01404       c = s[1];
01405       s += 2;
01406       base = 16;
01407    }
01408    if (base == 0)
01409    {
01410       base = c == '0' ? 8 : 10;
01411    }
01412    cutoff = ULLONG_MAX / (unsigned long long)base;
01413    cutlim = ULLONG_MAX % (unsigned long long)base;
01414    for (acc = 0, any = 0;; c = (unsigned char) *s++)
01415    {
01416       if (isdigit(c))
01417       {
01418          c -= '0';
01419       }
01420       else if (isalpha(c))
01421       {
01422          c -= isupper(c) ? 'A' - 10 : 'a' - 10;
01423       }
01424       else
01425       {
01426          break;
01427       }
01428       if (c >= (unsigned int)base)
01429       {
01430          break;
01431       }
01432       if (any < 0)
01433       {
01434          continue;
01435       }
01436       if (acc > cutoff || acc == cutoff && c > cutlim)
01437       {
01438          any = -1;
01439          acc = ULLONG_MAX;
01440          errno = ERANGE;
01441       }
01442       else
01443       {
01444          any = 1;
01445          acc *= (unsigned long)base;
01446          acc += c;
01447       }
01448    }
01449    if (neg && any > 0)
01450    {
01451 #ifdef OW_WIN32
01452 #pragma warning (push)
01453 #pragma warning (disable: 4146)
01454 #endif
01455 
01456       acc = -acc;
01457 
01458 #ifdef OW_WIN32
01459 #pragma warning (pop)
01460 #endif
01461 
01462    }
01463    if (endptr != 0)
01464    {
01465       *endptr = (char *) (any ? s - 1 : nptr);
01466    }
01467    return(acc);
01468 }
01469 #endif   // #ifdef OW_HAVE_STRTOULL
01470 
01471 String
01472 operator + (const String& s1, const String& s2)
01473 {
01474    String rstr(s1);
01475    rstr += s2;
01476    return rstr;
01477 }
01479 String
01480 operator + (const char* p, const String& s)
01481 {
01482    String rstr(p);
01483    rstr += s;
01484    return rstr;
01485 }
01487 String
01488 operator + (const String& s, const char* p)
01489 {
01490    String rstr(s);
01491    rstr += p;
01492    return rstr;
01493 }
01495 String
01496 operator + (char c, const String& s)
01497 {
01498    String rstr(c);
01499    rstr += s;
01500    return rstr;
01501 }
01503 String
01504 operator + (const String& s, char c)
01505 {
01506    String rstr(s);
01507    rstr += String(c);
01508    return rstr;
01509 }
01511 ostream&
01512 operator<< (ostream& ostr, const String& arg)
01513 {
01514    ostr.write(arg.c_str(), arg.length());
01515    return ostr;
01516 }
01518 // static
01519 String
01520 String::getLine(istream& is)
01521 {
01522    StringBuffer rv(80);
01523    rv.getLine(is);
01524    return rv.releaseString();
01525 }
01527 // STATIC
01528 const char*
01529 String::strchr(const char* theStr, int c)
01530 {
01531    const char* tmpChar = theStr;
01532    for (; *tmpChar && *tmpChar != c; tmpChar++)
01533    {
01534       // empty
01535    }
01536    return ((*tmpChar) == c ? tmpChar : 0);
01537 }
01538 
01539 } // end namespace OW_NAMESPACE
01540 

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