OW_StringBuffer.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_StringBuffer.hpp"
00038 #include "OW_CIMDateTime.hpp"
00039 #include "OW_Char16.hpp"
00040 #include "OW_CIMObjectPath.hpp"
00041 #include "OW_CIMDateTime.hpp"
00042 
00043 #include <cstring>
00044 #include <cstdio>
00045 #include <cctype>
00046 #if defined(OW_HAVE_ISTREAM) && defined(OW_HAVE_OSTREAM)
00047 #include <istream>
00048 #include <ostream>
00049 #else
00050 #include <iostream>
00051 #endif
00052 #include <algorithm> // for std::swap
00053 #include <cfloat> // for DBL_MANT_DIG
00054 
00055 namespace OW_NAMESPACE
00056 {
00057 
00058 #if defined(OW_AIX)
00059 const size_t StringBuffer::OW_DEFAULT_ALLOCATION_UNIT = 128;
00060 #endif // OW_AIX
00061 
00062 StringBuffer::StringBuffer(size_t allocSize) :
00063    m_len(0),
00064    m_allocated(allocSize > 0 ? allocSize : OW_DEFAULT_ALLOCATION_UNIT),
00065    m_bfr(new char[m_allocated])
00066 {
00067    m_bfr[0] = 0;
00068 }
00070 StringBuffer::StringBuffer(const char* arg) :
00071    m_len(strlen(arg)),
00072    m_allocated(m_len + OW_DEFAULT_ALLOCATION_UNIT),
00073    m_bfr(new char[m_allocated])
00074 {
00075    ::strcpy(m_bfr, arg);
00076 }
00078 StringBuffer::StringBuffer(const String& arg) :
00079    m_len(arg.length()),
00080    m_allocated(m_len + OW_DEFAULT_ALLOCATION_UNIT),
00081    m_bfr(new char[m_allocated])
00082 {
00083    ::strcpy(m_bfr, arg.c_str());
00084 }
00086 StringBuffer::StringBuffer(const StringBuffer& arg) :
00087    m_len(arg.m_len), m_allocated(arg.m_allocated),
00088    m_bfr(new char[arg.m_allocated])
00089 {
00090    ::memmove(m_bfr, arg.m_bfr, arg.m_len + 1);
00091 }
00093 StringBuffer&
00094 StringBuffer::operator= (const String& arg)
00095 {
00096    StringBuffer(arg).swap(*this);
00097    return *this;
00098 }
00100 StringBuffer&
00101 StringBuffer::operator= (const char* str)
00102 {
00103    StringBuffer(str).swap(*this);
00104    return *this;
00105 }
00107 StringBuffer&
00108 StringBuffer::operator =(const StringBuffer& arg)
00109 {
00110    StringBuffer(arg).swap(*this);
00111    return *this;
00112 }
00114 void
00115 StringBuffer::swap(StringBuffer& x)
00116 {
00117    std::swap(m_len, x.m_len);
00118    std::swap(m_allocated, x.m_allocated);
00119    std::swap(m_bfr, x.m_bfr);
00120 }
00122 void
00123 StringBuffer::reset()
00124 {
00125    m_len = 0;
00126    m_bfr[0] = '\0';
00127 }
00128 
00130 void
00131 StringBuffer::truncate(size_t index)
00132 {
00133    if (index < m_len)
00134    {
00135       m_bfr[index] = '\0';
00136       m_len = index;
00137    }
00138 }
00139 
00141 char
00142 StringBuffer::operator[] (size_t ndx) const
00143 {
00144    return (ndx > m_len) ? 0 : m_bfr[ndx];
00145 }
00147 // This operator must write "TRUE"/"FALSE" to support the CIMValue toXML
00148 StringBuffer&
00149 StringBuffer::operator += (Bool v)
00150 {
00151    return append(v.toString());
00152 }
00154 StringBuffer&
00155 StringBuffer::operator += (const CIMDateTime& arg)
00156 {
00157    return append(arg.toString());
00158 }
00160 StringBuffer&
00161 StringBuffer::operator += (const CIMObjectPath& arg)
00162 {
00163    return append(arg.toString());
00164 }
00165 #if defined(OW_WIN32)
00166 #define snprintf _snprintf // stupid windoze...
00167 #endif
00168 
00169 StringBuffer&
00170 StringBuffer::operator += (UInt8 v)
00171 {
00172    char bfr[6];
00173    ::snprintf(bfr, sizeof(bfr), "%u", UInt32(v));
00174    return append(bfr);
00175 }
00177 StringBuffer&
00178 StringBuffer::operator += (Int8 v)
00179 {
00180    char bfr[6];
00181    ::snprintf(bfr, sizeof(bfr), "%d", Int32(v));
00182    return append(bfr);
00183 }
00185 StringBuffer&
00186 StringBuffer::operator += (UInt16 v)
00187 {
00188    char bfr[16];
00189    ::snprintf(bfr, sizeof(bfr), "%u", UInt32(v));
00190    return append(bfr);
00191 }
00193 StringBuffer&
00194 StringBuffer::operator += (Int16 v)
00195 {
00196    char bfr[16];
00197    ::snprintf(bfr, sizeof(bfr), "%d", Int32(v));
00198    return append(bfr);
00199 }
00201 StringBuffer&
00202 StringBuffer::operator += (UInt32 v)
00203 {
00204    char bfr[16];
00205    ::snprintf(bfr, sizeof(bfr), "%u", v);
00206    return append(bfr);
00207 }
00209 StringBuffer&
00210 StringBuffer::operator += (Int32 v)
00211 {
00212    char bfr[16];
00213    ::snprintf(bfr, sizeof(bfr), "%d", v);
00214    return append(bfr);
00215 }
00217 StringBuffer&
00218 StringBuffer::operator += (UInt64 v)
00219 {
00220    char bfr[28];
00221 #if OW_SIZEOF_LONG_INT == 8
00222    ::snprintf(bfr, sizeof(bfr), "%lu", v);
00223 #else
00224    ::snprintf(bfr, sizeof(bfr), "%llu", v);
00225 #endif
00226    return append(bfr);
00227 }
00229 StringBuffer&
00230 StringBuffer::operator += (Int64 v)
00231 {
00232    char bfr[28];
00233 #if OW_SIZEOF_LONG_INT == 8
00234    ::snprintf(bfr, sizeof(bfr), "%ld", v);
00235 #else
00236    ::snprintf(bfr, sizeof(bfr), "%lld", v);
00237 #endif
00238    return append(bfr);
00239 }
00241 // decimal digits = ceiling((bits)*ln(2)/ln(10))
00242 StringBuffer&
00243 StringBuffer::operator += (Real32 v)
00244 {
00245    char bfr[128];
00246 #if FLT_RADIX == 2
00247 #if defined(OW_REAL32_IS_FLOAT)
00248    ::snprintf(bfr, sizeof(bfr), "%.*g", FLT_MANT_DIG * 3 / 10 + 1, static_cast<double>(v));
00249 #elif defined(OW_REAL32_IS_DOUBLE)
00250    ::snprintf(bfr, sizeof(bfr), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, v);
00251 #endif
00252 #else
00253 #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))"
00254 #endif
00255    return append(bfr);
00256 }
00258 StringBuffer&
00259 StringBuffer::operator += (Real64 v)
00260 {
00261    char bfr[32];
00262 #if FLT_RADIX == 2
00263 #if defined(OW_REAL64_IS_DOUBLE)
00264    ::snprintf(bfr, sizeof(bfr), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, v);
00265 #elif defined(OW_REAL64_IS_LONG_DOUBLE)
00266    ::snprintf(bfr, sizeof(bfr), "%.*Lg", LDBL_MANT_DIG * 3 / 10 + 1, v);
00267 #endif
00268 #else
00269 #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))"
00270 #endif
00271    return append(bfr);
00272 }
00273 #if defined(OW_WIN32)
00274 #undef snprintf
00275 #endif
00276 
00277 StringBuffer&
00278 StringBuffer::append(const char* str, const size_t len)
00279 {
00280    checkAvail(len+1);
00281    ::strncpy(m_bfr+m_len, str, len);
00282    m_len += len;
00283    m_bfr[m_len] = '\0';
00284    return *this;
00285 }
00287 bool
00288 StringBuffer::equals(const char* arg) const
00289 {
00290    return ::strcmp(arg, m_bfr) == 0;
00291 }
00292 
00294 bool
00295 StringBuffer::equals(const StringBuffer& arg) const
00296 {
00297    return ::strcmp(arg.m_bfr, m_bfr) == 0;
00298 }
00299 
00301 bool
00302 StringBuffer::endsWith(char ch) const
00303 {
00304    return (m_len && m_bfr[m_len-1] == ch);
00305 }
00306 
00308 bool
00309 StringBuffer::startsWith(char ch) const
00310 {
00311    return (m_len && m_bfr[0] == ch);
00312 }
00313 
00315 void
00316 StringBuffer::chop()
00317 {
00318    if (m_len)
00319    {
00320       truncate(m_len-1);
00321    }
00322 }
00323 
00325 void
00326 StringBuffer::trim()
00327 {
00328    if (m_len)
00329    {
00330       while (m_len && isspace(m_bfr[m_len-1]))
00331       {
00332          m_bfr[--m_len] = 0;
00333       }
00334 
00335       if (m_len)
00336       {
00337          char *p = m_bfr;
00338          while (*p && isspace(*p))
00339          {
00340             ++p;
00341          }
00342 
00343          if (*p && p > m_bfr)
00344          {
00345             m_len -= (p - m_bfr);
00346             memmove(m_bfr, p, m_len+1);
00347          }
00348       }
00349    }
00350 }
00351       
00353 // Get one line from an input stream. This StringBuffer object will be
00354 // reset (cleared) before an attempt is made to retrieve the line.
00355 const char*
00356 StringBuffer::getLine(std::istream& is, bool resetBuffer)
00357 {
00358    if (resetBuffer)
00359    {
00360       reset();
00361    }
00362 
00363    if (is)
00364    {
00365       size_t count = 0;
00366       std::streambuf *sb = is.rdbuf();
00367       
00368       while (1)
00369       {
00370          int ch = sb->sbumpc();
00371          if (ch == EOF)
00372          {
00373             is.setstate(count == 0
00374                ? (std::ios::failbit | std::ios::eofbit) : std::ios::eofbit);
00375             break;
00376          }
00377          
00378          ++count;
00379          
00380          if (ch == '\n')
00381          {
00382             break;
00383          }
00384 
00385          append(static_cast<char>(ch));
00386       }
00387    }
00388 
00389    const char* p = ::strchr(m_bfr, '\r');
00390    if (p)
00391    {
00392       truncate(size_t(p-m_bfr));
00393    }
00394 
00395    return m_bfr;
00396 }
00397 
00399 std::ostream& operator<<(std::ostream& ostr, const StringBuffer& b)
00400 {
00401    ostr.write(b.c_str(), b.length());
00402    return ostr;
00403 }
00404 
00406 bool operator==(const StringBuffer& x, const StringBuffer& y)
00407 {
00408    return x.equals(y);
00409 }
00410 
00412 bool operator!=(const StringBuffer& x, const StringBuffer& y)
00413 {
00414    return !(x == y);
00415 }
00416 
00418 bool operator==(const StringBuffer& x, const String& y)
00419 {
00420    return x.equals(y.c_str());
00421 }
00422 
00424 bool operator!=(const StringBuffer& x, const String& y)
00425 {
00426    return !(x == y);
00427 }
00428 
00430 bool operator==(const String& x, const StringBuffer& y)
00431 {
00432    return x.equals(y.c_str());
00433 }
00434 
00436 bool operator!=(const String& x, const StringBuffer& y)
00437 {
00438    return !(x == y);
00439 }
00440 
00441 } // end namespace OW_NAMESPACE
00442 

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