00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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>
00065 #include <cfloat>
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
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
00217
00218 OStringStream ss;
00219 ss << val;
00220 m_buf = new ByteBuf(ss.c_str());
00221 #endif
00222 }
00224
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
00384 while (true)
00385 {
00386 va_start(ap, fmt);
00387 n = vsnprintf(p.get(), size, fmt, ap);
00388 va_end(ap);
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)
00395 size = n+1;
00396 else
00397 size *= 2;
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
00547
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
00564
00565
00566
00567 size_t cc = npos;
00568 if (fromIndex < length())
00569 {
00570
00571
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
00588
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
00623
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
00657
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
00693
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
00733
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
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
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
00934
00935
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
00954
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;
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();
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;
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;
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();
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
01175
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
01240
01241
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
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
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
01519 String
01520 String::getLine(istream& is)
01521 {
01522 StringBuffer rv(80);
01523 rv.getLine(is);
01524 return rv.releaseString();
01525 }
01527
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
01535 }
01536 return ((*tmpChar) == c ? tmpChar : 0);
01537 }
01538
01539 }
01540