OWBI1_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 "OWBI1_config.h"
00037 #include "OWBI1_StringBuffer.hpp"
00038 #include "OWBI1_CIMDateTime.hpp"
00039 #include "OWBI1_Char16.hpp"
00040 #include "OWBI1_CIMObjectPath.hpp"
00041 #include "OWBI1_CIMDateTime.hpp"
00042 
00043 #include <cstring>
00044 #include <cstdio>
00045 #include <cctype>
00046 #if defined(OWBI1_HAVE_ISTREAM) && defined(OWBI1_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 OWBI1
00056 {
00057 
00058 #if defined(OWBI1_AIX)
00059 const size_t StringBuffer::OWBI1_DEFAULT_ALLOCATION_UNIT = 128;
00060 #endif // OWBI1_AIX
00061 
00062 StringBuffer::StringBuffer(size_t allocSize) :
00063    m_len(0),
00064    m_allocated(allocSize > 0 ? allocSize : OWBI1_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 + OWBI1_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 + OWBI1_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 }
00153 #if defined(OWBI1_WIN32)
00154 #define snprintf _snprintf // stupid windoze...
00155 #endif
00156 
00157 StringBuffer&
00158 StringBuffer::operator += (UInt8 v)
00159 {
00160    char bfr[6];
00161    ::snprintf(bfr, sizeof(bfr), "%u", UInt32(v));
00162    return append(bfr);
00163 }
00165 StringBuffer&
00166 StringBuffer::operator += (Int8 v)
00167 {
00168    char bfr[6];
00169    ::snprintf(bfr, sizeof(bfr), "%d", Int32(v));
00170    return append(bfr);
00171 }
00173 StringBuffer&
00174 StringBuffer::operator += (UInt16 v)
00175 {
00176    char bfr[16];
00177    ::snprintf(bfr, sizeof(bfr), "%u", UInt32(v));
00178    return append(bfr);
00179 }
00181 StringBuffer&
00182 StringBuffer::operator += (Int16 v)
00183 {
00184    char bfr[16];
00185    ::snprintf(bfr, sizeof(bfr), "%d", Int32(v));
00186    return append(bfr);
00187 }
00189 StringBuffer&
00190 StringBuffer::operator += (UInt32 v)
00191 {
00192    char bfr[16];
00193    ::snprintf(bfr, sizeof(bfr), "%u", v);
00194    return append(bfr);
00195 }
00197 StringBuffer&
00198 StringBuffer::operator += (Int32 v)
00199 {
00200    char bfr[16];
00201    ::snprintf(bfr, sizeof(bfr), "%d", v);
00202    return append(bfr);
00203 }
00205 StringBuffer&
00206 StringBuffer::operator += (UInt64 v)
00207 {
00208    char bfr[28];
00209 #if OWBI1_SIZEOF_LONG_INT == 8
00210    ::snprintf(bfr, sizeof(bfr), "%lu", v);
00211 #else
00212    ::snprintf(bfr, sizeof(bfr), "%llu", v);
00213 #endif
00214    return append(bfr);
00215 }
00217 StringBuffer&
00218 StringBuffer::operator += (Int64 v)
00219 {
00220    char bfr[28];
00221 #if OWBI1_SIZEOF_LONG_INT == 8
00222    ::snprintf(bfr, sizeof(bfr), "%ld", v);
00223 #else
00224    ::snprintf(bfr, sizeof(bfr), "%lld", v);
00225 #endif
00226    return append(bfr);
00227 }
00229 // decimal digits = ceiling((bits)*ln(2)/ln(10))
00230 StringBuffer&
00231 StringBuffer::operator += (Real32 v)
00232 {
00233    char bfr[128];
00234 #if FLT_RADIX == 2
00235 #if defined(OWBI1_REAL32_IS_FLOAT)
00236    ::snprintf(bfr, sizeof(bfr), "%.*g", FLT_MANT_DIG * 3 / 10 + 1, static_cast<double>(v));
00237 #elif defined(OWBI1_REAL32_IS_DOUBLE)
00238    ::snprintf(bfr, sizeof(bfr), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, v);
00239 #endif
00240 #else
00241 #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))"
00242 #endif
00243    return append(bfr);
00244 }
00246 StringBuffer&
00247 StringBuffer::operator += (Real64 v)
00248 {
00249    char bfr[32];
00250 #if FLT_RADIX == 2
00251 #if defined(OWBI1_REAL64_IS_DOUBLE)
00252    ::snprintf(bfr, sizeof(bfr), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, v);
00253 #elif defined(OWBI1_REAL64_IS_LONG_DOUBLE)
00254    ::snprintf(bfr, sizeof(bfr), "%.*Lg", LDBL_MANT_DIG * 3 / 10 + 1, v);
00255 #endif
00256 #else
00257 #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))"
00258 #endif
00259    return append(bfr);
00260 }
00261 #if defined(OWBI1_WIN32)
00262 #undef snprintf
00263 #endif
00264 
00265 StringBuffer&
00266 StringBuffer::append(const char* str, const size_t len)
00267 {
00268    checkAvail(len+1);
00269    ::strncpy(m_bfr+m_len, str, len);
00270    m_len += len;
00271    m_bfr[m_len] = '\0';
00272    return *this;
00273 }
00275 bool
00276 StringBuffer::equals(const char* arg) const
00277 {
00278    return ::strcmp(arg, m_bfr) == 0;
00279 }
00280 
00282 bool
00283 StringBuffer::equals(const StringBuffer& arg) const
00284 {
00285    return ::strcmp(arg.m_bfr, m_bfr) == 0;
00286 }
00287 
00289 bool
00290 StringBuffer::endsWith(char ch) const
00291 {
00292    return (m_len && m_bfr[m_len-1] == ch);
00293 }
00294 
00296 bool
00297 StringBuffer::startsWith(char ch) const
00298 {
00299    return (m_len && m_bfr[0] == ch);
00300 }
00301 
00303 void
00304 StringBuffer::chop()
00305 {
00306    if (m_len)
00307    {
00308       truncate(m_len-1);
00309    }
00310 }
00311 
00313 void
00314 StringBuffer::trim()
00315 {
00316    if (m_len)
00317    {
00318       while (m_len && isspace(m_bfr[m_len-1]))
00319       {
00320          m_bfr[--m_len] = 0;
00321       }
00322 
00323       if (m_len)
00324       {
00325          char *p = m_bfr;
00326          while (*p && isspace(*p))
00327          {
00328             ++p;
00329          }
00330 
00331          if (*p && p > m_bfr)
00332          {
00333             m_len -= (p - m_bfr);
00334             memmove(m_bfr, p, m_len+1);
00335          }
00336       }
00337    }
00338 }
00339       
00341 // Get one line from an input stream. This StringBuffer object will be
00342 // reset (cleared) before an attempt is made to retrieve the line.
00343 const char*
00344 StringBuffer::getLine(std::istream& is, bool resetBuffer)
00345 {
00346    if (resetBuffer)
00347    {
00348       reset();
00349    }
00350 
00351    if (is)
00352    {
00353       size_t count = 0;
00354       std::streambuf *sb = is.rdbuf();
00355       
00356       while (1)
00357       {
00358          int ch = sb->sbumpc();
00359          if (ch == EOF)
00360          {
00361             is.setstate(count == 0
00362                ? (std::ios::failbit | std::ios::eofbit) : std::ios::eofbit);
00363             break;
00364          }
00365          
00366          ++count;
00367          
00368          if (ch == '\n')
00369          {
00370             break;
00371          }
00372 
00373          append(static_cast<char>(ch));
00374       }
00375    }
00376 
00377    const char* p = ::strchr(m_bfr, '\r');
00378    if (p)
00379    {
00380       truncate(size_t(p-m_bfr));
00381    }
00382 
00383    return m_bfr;
00384 }
00385 
00387 std::ostream& operator<<(std::ostream& ostr, const StringBuffer& b)
00388 {
00389    ostr.write(b.c_str(), b.length());
00390    return ostr;
00391 }
00392 
00394 bool operator==(const StringBuffer& x, const StringBuffer& y)
00395 {
00396    return x.equals(y);
00397 }
00398 
00400 bool operator!=(const StringBuffer& x, const StringBuffer& y)
00401 {
00402    return !(x == y);
00403 }
00404 
00406 bool operator==(const StringBuffer& x, const String& y)
00407 {
00408    return x.equals(y.c_str());
00409 }
00410 
00412 bool operator!=(const StringBuffer& x, const String& y)
00413 {
00414    return !(x == y);
00415 }
00416 
00418 bool operator==(const String& x, const StringBuffer& y)
00419 {
00420    return x.equals(y.c_str());
00421 }
00422 
00424 bool operator!=(const String& x, const StringBuffer& y)
00425 {
00426    return !(x == y);
00427 }
00428 
00429 } // end namespace OWBI1
00430 

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