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 "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>
00062 #include <cfloat>
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
00081
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
00092
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
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
00227
00228 OStringStream ss;
00229 ss << val;
00230 m_buf = new ByteBuf(ss.c_str());
00231 #endif
00232 }
00234
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
00361 while (true)
00362 {
00363 va_start(ap, fmt);
00364 n = vsnprintf(p.get(), size, fmt, ap);
00365 va_end(ap);
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)
00372 size = n+1;
00373 else
00374 size *= 2;
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
00524
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
00541
00542
00543
00544 size_t cc = npos;
00545 if (fromIndex < length())
00546 {
00547
00548
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
00565
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
00600
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
00634
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
00670
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
00710
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
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
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
00835
00836 String&
00837 String::toLowerCase()
00838 {
00839 size_t len = length();
00840 for (size_t i = 0; i < len; i++)
00841 {
00842
00843
00844 m_buf->data()[i] = tolower(m_buf->data()[i]);
00845 }
00846 return *this;
00847 }
00849
00850
00851 String&
00852 String::toUpperCase()
00853 {
00854 size_t len = length();
00855 for (size_t i = 0; i < len; i++)
00856 {
00857
00858
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
00914
00915
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
00934
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;
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();
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;
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;
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();
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
01140
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
01205
01206
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
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
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
01484 String
01485 String::getLine(istream& is)
01486 {
01487 StringBuffer rv(80);
01488 rv.getLine(is);
01489 return String(rv.c_str());
01490 }
01492
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
01500 }
01501 return ((*tmpChar) == c ? tmpChar : 0);
01502 }
01503
01504 }
01505