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
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #if !defined(ALIZE_String_cpp)
00056 #define ALIZE_String_cpp
00057
00058 #if defined(_WIN32)
00059 #define _CRT_SECURE_NO_WARNINGS
00060 #endif
00061
00062 #include <new>
00063 #include <cstring>
00064 #include <iostream>
00065 #include <sstream>
00066 #include <iomanip>
00067 #include "alizeString.h"
00068 #include "Exception.h"
00069
00070 using namespace alize;
00071 typedef String S;
00072
00073
00074 S::String(const char* c)
00075 :Object()
00076 {
00077 unsigned long length = (unsigned long)strlen(c);
00078 create(length, length+length+1, c);
00079 }
00080
00081 S::String(const String& s)
00082 :Object()
00083 {
00084 create(s._length, s._length+s._length+1, s._string);
00085 }
00086
00087 S& S::duplicate() const
00088 {
00089 S* p = new (std::nothrow) S(*this);
00090 assertMemoryIsAllocated(p, __FILE__, __LINE__);
00091 return *p;
00092 }
00093
00094 S S::valueOf(unsigned long v)
00095 {
00096 std::ostringstream o;
00097 o << v << std::ends;
00098 return o.str().c_str();
00099 }
00100
00101 S S::valueOf(long v)
00102 {
00103 std::ostringstream o;
00104 o << v << std::ends;
00105 return o.str().c_str();
00106 }
00107
00108 S S::valueOf(double v)
00109 {
00110 std::ostringstream o;
00111 o << std::setprecision(19) << v << std::ends;
00112 return o.str().c_str();
00113 }
00114
00115 S S::valueOf(unsigned int v)
00116 {
00117 std::ostringstream o;
00118 o << v << std::ends;
00119 return o.str().c_str();
00120 }
00121
00122 S S::valueOf(int v)
00123 {
00124 std::ostringstream o;
00125 o << v << std::ends;
00126 return o.str().c_str();
00127 }
00128
00129 S S::valueOf(bool value) { return value?"true":"false"; }
00130
00131 double S::toDouble() const
00132 {
00133
00134 double v;
00135 std::istringstream stream(_string);
00136 stream >> v;
00137 if (stream.fail())
00138 throw Exception("cannot convert '" + *this
00139 + "' to double float", __FILE__, __LINE__);
00140 return v;
00141 }
00142
00143 bool S::toBool() const
00144 {
00145 if (strcmp(_string, "true") == 0)
00146 return true;
00147 if (strcmp(_string, "false") == 0)
00148 return false;
00149 throw Exception("cannot convert '" + *this
00150 + "' to boolean", __FILE__, __LINE__);
00151 return true;
00152 }
00153
00154 long S::toLong() const
00155 {
00156 long v;
00157 std::istringstream stream(_string);
00158 stream >> v;
00159 if (stream.fail())
00160 throw Exception("cannot convert '" + *this
00161 + "' to long integer", __FILE__, __LINE__);
00162 return v;
00163 }
00164
00165 unsigned long S::toULong() const
00166 {
00167 unsigned long v;
00168 std::istringstream stream(_string);
00169 stream >> v;
00170 if (stream.fail())
00171 throw Exception("cannot convert '" + *this
00172 + "' to unsigned long integer", __FILE__, __LINE__);
00173 return v;
00174 }
00175
00176 const S& S::operator=(const String& s)
00177 {
00178 if (_string != s._string)
00179 {
00180 if (_capacity < s._length+1)
00181 {
00182 delete[] _string;
00183 create(s._length, s._length+s._length+1, s._string);
00184 }
00185 else
00186 {
00187 _length = s._length;
00188 strcpy(_string, s._string);
00189 }
00190 }
00191 assert(_length == s._length);
00192 return *this;
00193 }
00194
00195 const S& S::operator=(const char* s)
00196 {
00197 unsigned long len = (unsigned long)strlen(s);
00198 if (_string != s)
00199 {
00200 if (_capacity < len+1)
00201 {
00202 delete[] _string;
00203 create(len, len+len+1, s);
00204 }
00205 else
00206 {
00207 _length = len;
00208 strcpy(_string, s);
00209 }
00210 }
00211 assert(_length == len);
00212 return *this;
00213 }
00214
00215 S& S::operator+=(const String& s)
00216 {
00217 char* oldString = _string;
00218 unsigned long newLength = _length+s._length;
00219 if (_capacity < newLength+1)
00220 {
00221 create(newLength, newLength+newLength+1, oldString);
00222 delete [] oldString;
00223 }
00224 strcat(_string, s._string);
00225 _length = newLength;
00226 return *this;
00227 }
00228
00229 S& S::operator+=(const char* s)
00230 {
00231 char* oldString = _string;
00232 unsigned long newLength = _length+strlen(s);
00233 if (_capacity < newLength+1)
00234 {
00235 create(newLength, newLength+newLength+1, oldString);
00236 delete [] oldString;
00237 }
00238 strcat(_string, s);
00239 _length = newLength;
00240 return *this;
00241 }
00242
00243 S S::operator+(const String& s) const
00244 {
00245 String x(*this);
00246 x += s;
00247 return x;
00248 }
00249
00250 S S::operator+(const char* s) const
00251 {
00252 String x(*this);
00253 x += s;
00254 return x;
00255 }
00256
00257 bool S::operator==(const String& s) const
00258 {
00259 return strcmp(_string, s._string) == 0;
00260 }
00261
00262 bool S::operator!=(const String& s) const
00263 {
00264 return strcmp(_string, s._string) != 0;
00265 }
00266
00267 bool S::operator==(const char* s) const
00268 {
00269 return strcmp(_string, s) == 0;
00270 }
00271
00272 bool S::operator!=(const char* s) const
00273 {
00274 return strcmp(_string, s) != 0;
00275 }
00276
00277 bool S::operator<(const String& s) const
00278 {
00279 return strcmp(_string, s._string) < 0;
00280 }
00281
00282 bool S::operator<=(const String& s) const
00283 {
00284 return strcmp(_string, s._string) <= 0;
00285 }
00286
00287 bool S::operator>(const String& s) const
00288 {
00289 return strcmp(_string, s._string) > 0;
00290 }
00291
00292 bool S::operator>=(const String& s) const
00293 {
00294 return strcmp(_string, s._string) >= 0;
00295 }
00296
00297 unsigned long String::length() const { return _length; }
00298
00299 S S::operator[](unsigned long index) const
00300 {
00301 if (index >= _length)
00302 return "";
00303 char oneChar[] = {0, 0};
00304 oneChar[0] = _string[index];
00305 return oneChar;
00306 }
00307
00308 void S::reset() { _length = 0; _string[0] = 0; }
00309
00310 bool S::isEmpty() const { return _length == 0; }
00311
00312 bool S::endsWith(const String& s) const
00313
00314 {
00315 if (s._length == 0)
00316 return true;
00317 if (_length < s._length)
00318 return false;
00319 return strncmp(_string+(_length - s._length), s._string, s._length) == 0;
00320
00321 }
00322
00323 bool S::beginsWith(const String& s) const
00324
00325 {
00326 if (s._length == 0)
00327 return true;
00328 if (_length < s._length)
00329 return false;
00330 return strncmp(_string, s._string, s._length) == 0;
00331
00332 }
00333
00334 long S::find(const String& s, unsigned long start) const
00335
00336 {
00337 if (s._length == 0)
00338 return -1;
00339 unsigned long i;
00340 for (; start+s._length<=_length; start++)
00341 {
00342 for (i=0; i<s._length; i++)
00343 {
00344 if (_string[start+i] != s._string[i])
00345 break;
00346 }
00347 if (i == s._length)
00348 return start;
00349 }
00350 return -1;
00351 }
00352
00353 S S::getToken(unsigned long index, const String& separator) const
00354 {
00355 if (separator.length() != 1)
00356 throw Exception("separator length must be 1", __FILE__, __LINE__);
00357 char sep = *separator.c_str();
00358
00359 S s;
00360 long tokenCount = 0;
00361 long start = -1;
00362 long end = -1;
00363 long i;
00364 char previous = sep;
00365 long l = length();
00366 for (i=0; i<l; i++)
00367 {
00368 if ( (sep == ' ' && _string[i] != ' ' && _string[i] != '\t') ||
00369 (sep != ' ' && _string[i] != sep) )
00370 {
00371 if ( (sep == ' ' && (previous == ' ' || previous == '\t')) ||
00372 (sep != ' ' && previous == sep) )
00373 {
00374 tokenCount++;
00375 start = i;
00376 previous = '\1';
00377 }
00378 }
00379 else
00380 {
00381 if ( (sep == ' ' && previous != ' ' && previous != '\t') ||
00382 (sep != ' ' && previous != sep) )
00383 {
00384 end = i-1;
00385 previous = sep;
00386 if (tokenCount == (long)index+1)
00387 break;
00388 start = -1;
00389 end = -1;
00390 }
00391 }
00392 }
00393 if ( (sep == ' ' && previous != ' ' && previous != '\t') ||
00394 (sep != ' ' && previous != sep) )
00395 end = i-1;
00396 if (tokenCount != (long)index+1)
00397 {
00398 start = -1;
00399 end = -1;
00400 }
00401
00402 if (start != -1)
00403 {
00404 char* string = new (std::nothrow) char[end-start+2];
00405 assertMemoryIsAllocated(string, __FILE__, __LINE__);
00406 for (i=start; i<=end; i++)
00407 { string[i-start]=_string[i]; }
00408 string[end-start+1] = 0;
00409 s = string;
00410 delete [] string;
00411 }
00412 return s;
00413 }
00414
00415 const char* String::c_str() const { return _string; }
00416
00417 S S::getClassName() const { return "String"; }
00418
00419 S S::toString() const
00420 {
00421 return Object::toString() + " '" + _string;
00422 }
00423
00424 void S::create(unsigned long length, unsigned long capacity,
00425 const char* c)
00426 {
00427 _length = length;
00428 _capacity = capacity<length+1?length+1:capacity;
00429 _string = new (std::nothrow) char[_capacity];
00430 assertMemoryIsAllocated(_string, __FILE__, __LINE__);
00431 strcpy(_string, c);
00432 }
00433
00434 S::~String()
00435 {
00436 assert(_string != NULL);
00437 delete[] _string;
00438 }
00439
00440
00441
00442
00443
00444 ALIZE_API S operator+(const char* c, const String& s)
00445 {
00446 String x(c);
00447 x += s;
00448 return x;
00449 }
00450
00451 ALIZE_API std::ostream& operator<<(std::ostream& o, const S& s)
00452 {
00453 return o << s.c_str();
00454 }
00455
00456
00457 #endif // !defined(ALIZE_String_cpp)