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
00031
00032
00038 #include "blocxx/BLOCXX_config.h"
00039 #include "blocxx/StringBuffer.hpp"
00040 #include "blocxx/Char16.hpp"
00041
00042 #include <cstring>
00043 #include <cstdio>
00044 #include <cctype>
00045 #if defined(BLOCXX_HAVE_ISTREAM) && defined(BLOCXX_HAVE_OSTREAM)
00046 #include <istream>
00047 #include <ostream>
00048 #else
00049 #include <iostream>
00050 #endif
00051 #include <algorithm>
00052 #include <cfloat>
00053
00054 namespace BLOCXX_NAMESPACE
00055 {
00056
00057 #if defined(BLOCXX_AIX)
00058 const size_t StringBuffer::BLOCXX_DEFAULT_ALLOCATION_UNIT = 128;
00059 #endif // BLOCXX_AIX
00060
00061 StringBuffer::StringBuffer(size_t allocSize) :
00062 m_len(0),
00063 m_allocated(allocSize > 0 ? allocSize : BLOCXX_DEFAULT_ALLOCATION_UNIT),
00064 m_bfr(new char[m_allocated])
00065 {
00066 m_bfr[0] = 0;
00067 }
00069 StringBuffer::StringBuffer(const char* arg) :
00070 m_len(strlen(arg)),
00071 m_allocated(m_len + BLOCXX_DEFAULT_ALLOCATION_UNIT),
00072 m_bfr(new char[m_allocated])
00073 {
00074 ::strcpy(m_bfr, arg);
00075 }
00077 StringBuffer::StringBuffer(const String& arg) :
00078 m_len(arg.length()),
00079 m_allocated(m_len + BLOCXX_DEFAULT_ALLOCATION_UNIT),
00080 m_bfr(new char[m_allocated])
00081 {
00082 ::strcpy(m_bfr, arg.c_str());
00083 }
00085 StringBuffer::StringBuffer(const StringBuffer& arg) :
00086 m_len(arg.m_len), m_allocated(arg.m_allocated),
00087 m_bfr(new char[arg.m_allocated])
00088 {
00089 ::memmove(m_bfr, arg.m_bfr, arg.m_len + 1);
00090 }
00092 StringBuffer&
00093 StringBuffer::operator= (const String& arg)
00094 {
00095 StringBuffer(arg).swap(*this);
00096 return *this;
00097 }
00099 StringBuffer&
00100 StringBuffer::operator= (const char* str)
00101 {
00102 StringBuffer(str).swap(*this);
00103 return *this;
00104 }
00106 StringBuffer&
00107 StringBuffer::operator =(const StringBuffer& arg)
00108 {
00109 StringBuffer(arg).swap(*this);
00110 return *this;
00111 }
00113 void
00114 StringBuffer::swap(StringBuffer& x)
00115 {
00116 std::swap(m_len, x.m_len);
00117 std::swap(m_allocated, x.m_allocated);
00118 std::swap(m_bfr, x.m_bfr);
00119 }
00121 void
00122 StringBuffer::reset()
00123 {
00124 m_len = 0;
00125 m_bfr[0] = '\0';
00126 }
00127
00129 void
00130 StringBuffer::truncate(size_t index)
00131 {
00132 if (index < m_len)
00133 {
00134 m_bfr[index] = '\0';
00135 m_len = index;
00136 }
00137 }
00138
00140 char
00141 StringBuffer::operator[] (size_t ndx) const
00142 {
00143 return (ndx > m_len) ? 0 : m_bfr[ndx];
00144 }
00146
00147 StringBuffer&
00148 StringBuffer::operator += (Bool v)
00149 {
00150 return append(v.toString());
00151 }
00153 #if defined(BLOCXX_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 BLOCXX_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 BLOCXX_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
00230 StringBuffer&
00231 StringBuffer::operator += (Real32 v)
00232 {
00233 char bfr[128];
00234 #if FLT_RADIX == 2
00235 #if defined(BLOCXX_REAL32_IS_FLOAT)
00236 ::snprintf(bfr, sizeof(bfr), "%.*g", FLT_MANT_DIG * 3 / 10 + 1, static_cast<double>(v));
00237 #elif defined(BLOCXX_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(BLOCXX_REAL64_IS_DOUBLE)
00252 ::snprintf(bfr, sizeof(bfr), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, v);
00253 #elif defined(BLOCXX_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(BLOCXX_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
00342
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 }
00430