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
00033
00039 #include "blocxx/BLOCXX_config.h"
00040 #include "blocxx/StringBuffer.hpp"
00041 #include "blocxx/Char16.hpp"
00042
00043 #include <cstring>
00044 #include <cstdio>
00045 #include <cctype>
00046 #if defined(BLOCXX_HAVE_ISTREAM) && defined(BLOCXX_HAVE_OSTREAM)
00047 #include <istream>
00048 #include <ostream>
00049 #else
00050 #include <iostream>
00051 #endif
00052 #include <algorithm>
00053 #include <cfloat>
00054
00055 namespace BLOCXX_NAMESPACE
00056 {
00057
00058 #if defined(BLOCXX_AIX)
00059 const size_t StringBuffer::BLOCXX_DEFAULT_ALLOCATION_UNIT = 128;
00060 #endif // BLOCXX_AIX
00061
00062 StringBuffer::StringBuffer(size_t allocSize) :
00063 m_len(0),
00064 m_allocated(allocSize > 0 ? allocSize : BLOCXX_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 + BLOCXX_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 + BLOCXX_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
00148 StringBuffer&
00149 StringBuffer::operator += (Bool v)
00150 {
00151 return append(v.toString());
00152 }
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 }
00204 #if defined(BLOCXX_INT32_IS_INT) && defined(BLOCXX_INT64_IS_LONG_LONG)
00205
00206 StringBuffer&
00207 StringBuffer::operator += (unsigned long v)
00208 {
00209 char bfr[28];
00210 ::snprintf(bfr, sizeof(bfr), "%lu", v);
00211 return append(bfr);
00212 }
00214 StringBuffer&
00215 StringBuffer::operator += (long v)
00216 {
00217 char bfr[28];
00218 ::snprintf(bfr, sizeof(bfr), "%ld", v);
00219 return append(bfr);
00220 }
00221 #endif
00222
00223 StringBuffer&
00224 StringBuffer::operator += (UInt64 v)
00225 {
00226 char bfr[28];
00227 #if BLOCXX_SIZEOF_LONG_INT == 8
00228 ::snprintf(bfr, sizeof(bfr), "%lu", v);
00229 #else
00230 ::snprintf(bfr, sizeof(bfr), "%llu", v);
00231 #endif
00232 return append(bfr);
00233 }
00235 StringBuffer&
00236 StringBuffer::operator += (Int64 v)
00237 {
00238 char bfr[28];
00239 #if BLOCXX_SIZEOF_LONG_INT == 8
00240 ::snprintf(bfr, sizeof(bfr), "%ld", v);
00241 #else
00242 ::snprintf(bfr, sizeof(bfr), "%lld", v);
00243 #endif
00244 return append(bfr);
00245 }
00247
00248 StringBuffer&
00249 StringBuffer::operator += (Real32 v)
00250 {
00251 char bfr[128];
00252 #if FLT_RADIX == 2
00253 #if defined(BLOCXX_REAL32_IS_FLOAT)
00254 ::snprintf(bfr, sizeof(bfr), "%.*g", FLT_MANT_DIG * 3 / 10 + 1, static_cast<double>(v));
00255 #elif defined(BLOCXX_REAL32_IS_DOUBLE)
00256 ::snprintf(bfr, sizeof(bfr), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, v);
00257 #endif
00258 #else
00259 #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))"
00260 #endif
00261 return append(bfr);
00262 }
00264 StringBuffer&
00265 StringBuffer::operator += (Real64 v)
00266 {
00267 char bfr[32];
00268 #if FLT_RADIX == 2
00269 #if defined(BLOCXX_REAL64_IS_DOUBLE)
00270 ::snprintf(bfr, sizeof(bfr), "%.*g", DBL_MANT_DIG * 3 / 10 + 1, v);
00271 #elif defined(BLOCXX_REAL64_IS_LONG_DOUBLE)
00272 ::snprintf(bfr, sizeof(bfr), "%.*Lg", LDBL_MANT_DIG * 3 / 10 + 1, v);
00273 #endif
00274 #else
00275 #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))"
00276 #endif
00277 return append(bfr);
00278 }
00279 #if defined(BLOCXX_WIN32)
00280 #undef snprintf
00281 #endif
00282
00283 StringBuffer&
00284 StringBuffer::append(const char* str, const size_t len)
00285 {
00286 checkAvail(len+1);
00287 ::strncpy(m_bfr+m_len, str, len);
00288 m_len += len;
00289 m_bfr[m_len] = '\0';
00290 return *this;
00291 }
00293 bool
00294 StringBuffer::equals(const char* arg) const
00295 {
00296 return ::strcmp(arg, m_bfr) == 0;
00297 }
00298
00300 bool
00301 StringBuffer::equals(const StringBuffer& arg) const
00302 {
00303 return ::strcmp(arg.m_bfr, m_bfr) == 0;
00304 }
00305
00307 bool
00308 StringBuffer::endsWith(char ch) const
00309 {
00310 return (m_len && m_bfr[m_len-1] == ch);
00311 }
00312
00314 bool
00315 StringBuffer::startsWith(char ch) const
00316 {
00317 return (m_len && m_bfr[0] == ch);
00318 }
00319
00321 void
00322 StringBuffer::chop()
00323 {
00324 if (m_len)
00325 {
00326 truncate(m_len-1);
00327 }
00328 }
00329
00331 void
00332 StringBuffer::trim()
00333 {
00334 if (m_len)
00335 {
00336 while (m_len && isspace(m_bfr[m_len-1]))
00337 {
00338 m_bfr[--m_len] = 0;
00339 }
00340
00341 if (m_len)
00342 {
00343 char *p = m_bfr;
00344 while (*p && isspace(*p))
00345 {
00346 ++p;
00347 }
00348
00349 if (*p && p > m_bfr)
00350 {
00351 m_len -= (p - m_bfr);
00352 memmove(m_bfr, p, m_len+1);
00353 }
00354 }
00355 }
00356 }
00357
00359
00360
00361 const char*
00362 StringBuffer::getLine(std::istream& is, bool resetBuffer)
00363 {
00364 if (resetBuffer)
00365 {
00366 reset();
00367 }
00368
00369 if (is)
00370 {
00371 size_t count = 0;
00372 std::streambuf *sb = is.rdbuf();
00373
00374 while (1)
00375 {
00376 int ch = sb->sbumpc();
00377 if (ch == EOF)
00378 {
00379 is.setstate(count == 0
00380 ? (std::ios::failbit | std::ios::eofbit) : std::ios::eofbit);
00381 break;
00382 }
00383
00384 ++count;
00385
00386 if (ch == '\n')
00387 {
00388 break;
00389 }
00390
00391 append(static_cast<char>(ch));
00392 }
00393 }
00394
00395 const char* p = ::strchr(m_bfr, '\r');
00396 if (p)
00397 {
00398 truncate(size_t(p-m_bfr));
00399 }
00400
00401 return m_bfr;
00402 }
00403
00405 std::ostream& operator<<(std::ostream& ostr, const StringBuffer& b)
00406 {
00407 ostr.write(b.c_str(), b.length());
00408 return ostr;
00409 }
00410
00412 bool operator==(const StringBuffer& x, const StringBuffer& y)
00413 {
00414 return x.equals(y);
00415 }
00416
00418 bool operator!=(const StringBuffer& x, const StringBuffer& y)
00419 {
00420 return !(x == y);
00421 }
00422
00424 bool operator==(const StringBuffer& x, const String& y)
00425 {
00426 return x.equals(y.c_str());
00427 }
00428
00430 bool operator!=(const StringBuffer& x, const String& y)
00431 {
00432 return !(x == y);
00433 }
00434
00436 bool operator==(const String& x, const StringBuffer& y)
00437 {
00438 return x.equals(y.c_str());
00439 }
00440
00442 bool operator!=(const String& x, const StringBuffer& y)
00443 {
00444 return !(x == y);
00445 }
00446
00447 }
00448