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 #include "AString.hh"
00034 #include <string.h>
00035 #include <ctype.h>
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038
00039 namespace coool
00040 {
00041 using namespace coool;
00042
00043
00044 static const int default_chunk_size = 8;
00045 static const char* myNameIs = "AString";
00046 static const char* empty_string = "";
00047
00048
00049 void AString::bigEnough(const int size)
00050 {
00051 if(size < 0){
00052 cerr << className() << "bigEnough: arg size = " << size
00053 << " is less than zero." << endl;
00054 exit(1);
00055 }
00056
00057 if(size >= 0 && mem < (size + 1)){
00058 char* tmp = contents;
00059
00060
00061
00062
00063
00064 int num_chunks = ((size + 1) + (chunksize() - 1)) / chunksize();
00065 mem = num_chunks * chunksize();
00066 contents = new char[mem];
00067 contents[0] = '\0';
00068
00069 if(tmp != NULL)
00070 strcpy(contents, tmp);
00071 delete tmp;
00072 }
00073 }
00074
00075 void AString::initVars() {
00076 length(0);
00077 mem = 0;
00078 contents = NULL;
00079 chunksize(default_chunk_size);
00080 }
00081
00082 int AString::inRange(const long i) const {
00083 return(i >= 0 && i < length());
00084 }
00085
00086 void AString::length(const int new_length){
00087 len = new_length >= 0 ? new_length : -1;
00088 }
00089
00090
00091
00092
00093
00094
00095 AString::AString(const char c){
00096 initVars();
00097 copy(c);
00098 }
00099
00100
00101
00102
00103
00104
00105 int AString::compare(const AString& as) const{
00106 if(this == &as)
00107 return 0;
00108 int asIsEmpty = as.empty();
00109 int thisIsEmpty = empty();
00110
00111 if(asIsEmpty && thisIsEmpty)
00112 return 0;
00113 else if(asIsEmpty || thisIsEmpty)
00114 return asIsEmpty ? 1 : -1;
00115 else
00116 return strcmp(contents, as.contents);
00117 }
00118
00119
00120
00121
00122
00123
00124 int AString::compare(const char* s) const {
00125 if(contents == s)
00126 return 0;
00127
00128 int sIsEmpty = (s == NULL ? True : (strlen(s) == 0 ? TRUE : FALSE));
00129 int thisIsEmpty = empty();
00130
00131 if(sIsEmpty && thisIsEmpty)
00132 return 0;
00133 else if(sIsEmpty || thisIsEmpty)
00134
00135 return sIsEmpty ? 1 : -1;
00136 else
00137 return strcmp(contents, s);
00138 }
00139
00140
00141
00142
00143 void AString::concat(const AString& as){
00144 if(!as.empty()){
00145 int this_length = length();
00146 int as_length = as.length();
00147 int m = this_length + as_length;
00148 bigEnough(m);
00149 char* start_pointer = &contents[this_length];
00150 length(m);
00151
00152
00153 strncpy(start_pointer, as.contents, as_length);
00154 contents[m] = '\0';
00155 }
00156 }
00157
00158
00159
00160
00161 void AString::concat(const char* s){
00162 if(s != NULL){
00163 int this_length = length();
00164 int s_length = strlen(s);
00165 int m = this_length + s_length;
00166 bigEnough(m);
00167 char* start_pointer = &contents[this_length];
00168 length(m);
00169 strncpy(start_pointer, s, s_length);
00170 contents[m] = '\0';
00171 }
00172 }
00173
00174
00175
00176
00177 void AString::concat(const char& c){
00178 int m = length();
00179 bigEnough(m + 1);
00180 contents[m++] = c;
00181 contents[m] = '\0';
00182 length(m);
00183 }
00184
00185
00186
00187
00188 void AString::copy(const AString& as){
00189 if(this != &as)
00190 if(!as.empty()){
00191 length(as.length());
00192 bigEnough(length());
00193 strcpy(contents, as.contents);
00194 }
00195 }
00196
00197
00198
00199
00200 void AString::copy(const char* cp){
00201 if(contents != cp)
00202 if(cp != NULL){
00203 length(strlen(cp));
00204 bigEnough(length());
00205 strcpy(contents, cp);
00206 }
00207 }
00208
00209
00210
00211
00212 void AString::copy(const char& c){
00213 length(1);
00214 bigEnough(length());
00215 contents[0] = c;
00216 contents[1] = '\0';
00217 }
00218
00219
00220
00221
00222 int AString::isNull() const {
00223 return(contents == NULL);
00224 }
00225
00226
00227
00228
00229
00230 AString::AString(){
00231 initVars();
00232 }
00233
00234
00235
00236 AString::AString(const char* cp){
00237 initVars();
00238 copy(cp);
00239 }
00240
00241
00242 AString::AString(const AString& as){
00243 initVars();
00244 copy(as);
00245 }
00246
00247 AString::~AString(){
00248 delete contents;
00249 }
00250
00251
00252
00253 int AString::chunksize() const {
00254 return(chunk_size > 0 ? chunk_size : default_chunk_size);
00255 }
00256
00257
00258
00259 void AString::chunksize(const int new_size){
00260 if(new_size > 0)
00261 chunk_size = new_size;
00262 }
00263
00264
00265
00266 int AString::empty() const {
00267 return (length() == 0);
00268 }
00269
00270
00271
00272
00273 int AString::length() const{
00274 if(len == -1){
00275 AString* that = (AString*)(this);
00276 that->length(isNull() ? 0 : strlen(contents));
00277 }
00278 return(len);
00279 }
00280
00281
00282
00283
00284 AString& AString::operator=(const AString& as){
00285 if(this != &as){
00286 delete contents;
00287 initVars();
00288 chunksize(as.chunksize());
00289 copy(as);
00290 }
00291 return *this;
00292 }
00293
00294
00295
00296
00297 AString& AString::operator=(const char* s){
00298 delete contents;
00299 initVars();
00300 copy(s);
00301 return *this;
00302 }
00303
00304
00305
00306
00307 const char& AString::operator[](const long i) const{
00308 if(!inRange(i)){
00309 cerr << className() << "[" << i << "], i is out of range" << endl;
00310 exit(1);
00311 }
00312 return(contents[i]);
00313 }
00314
00315
00316
00317 AString& AString::operator+=(const AString& as){
00318 concat(as);
00319 return *this;
00320 }
00321
00322
00323
00324 AString& AString::operator+=(const char* s){
00325 concat(s);
00326 return *this;
00327 }
00328
00329
00330
00331 AString::operator const char*() const{
00332 if(isNull())
00333 return empty_string;
00334 else
00335 return(contents);
00336 }
00337
00338 const char* AString::className() const{
00339 return(myNameIs);
00340 }
00341
00342
00343
00344 AString AString::asLowerCase() const
00345 {
00346 AString t = *this;
00347 for(int i = 0; i < len; i++)
00348 t.contents[i] = tolower(t.contents[i]);
00349 return t;
00350 }
00351
00352
00353
00354
00355
00356 AString operator+(const AString& as, const AString& bs){
00357 AString tmp;
00358 tmp.bigEnough(as.length() + bs.length());
00359 tmp.concat(as);
00360 tmp.concat(bs);
00361 return tmp;
00362 }
00363
00364
00365
00366 AString operator+(const AString& as, const char* s){
00367 AString tmp;
00368 tmp.bigEnough(as.length() + (s == NULL ? 0 : strlen(s)));
00369 tmp.concat(as);
00370 tmp.concat(s);
00371 return tmp;
00372 }
00373
00374
00375
00376 AString operator+(const char* s, const AString& as){
00377 AString tmp;
00378 tmp.bigEnough((s == NULL ? 0 : strlen(s)) + as.length());
00379 tmp.concat(s);
00380 tmp.concat(as);
00381 return tmp;
00382 }
00383
00384
00385 int operator==(const AString& as, const AString& bs){
00386 return(as.compare(bs) == 0);
00387 }
00388
00389 int operator==(const AString& as, const char* s){
00390 return(as.compare(s) == 0);
00391 }
00392
00393 int operator==(const char* s, const AString& as){
00394 return(as.compare(s) == 0);
00395 }
00396
00397
00398 int operator!=(const AString& as, const AString& bs){
00399 return(as.compare(bs) != 0);
00400 }
00401
00402 int operator!=(const AString& as, const char* s){
00403 return(as.compare(s) != 0);
00404 }
00405
00406 int operator!=(const char* s, const AString& as){
00407 return(as.compare(s) != 0);
00408 }
00409
00410
00411 int operator>(const AString& as, const AString& bs){
00412 return(as.compare(bs) > 0);
00413 }
00414
00415 int operator>(const AString& as, const char* s){
00416 return(as.compare(s) > 0);
00417 }
00418
00419 int operator>(const char* s, const AString& as){
00420 return(as.compare(s) < 0);
00421 }
00422
00423
00424 int operator>=(const AString& as, const AString& bs){
00425 return(as.compare(bs) >= 0);
00426 }
00427
00428 int operator>=(const AString& as, const char* s){
00429 return(as.compare(s) >= 0);
00430 }
00431
00432 int operator>=(const char* s, const AString& as){
00433 return(as.compare(s) <= 0);
00434 }
00435
00436
00437 int operator<(const AString& as, const AString& bs){
00438 return(as.compare(bs) < 0);
00439 }
00440
00441 int operator<(const AString& as, const char* s){
00442 return(as.compare(s) < 0);
00443 }
00444
00445 int operator<(const char* s, const AString& as){
00446 return(as.compare(s) > 0);
00447 }
00448
00449
00450 int operator<=(const AString& as, const AString& bs){
00451 return(as.compare(bs) <= 0);
00452 }
00453
00454 int operator<=(const AString& as, const char* s){
00455 return(as.compare(s) <= 0);
00456 }
00457
00458 int operator<=(const char* s, const AString& as){
00459 return(as.compare(s) >= 0);
00460 }
00461
00462 ostream& operator<<(ostream& fp, const AString& as)
00463 {
00464 fp << as.contents;
00465
00466 return fp;
00467 }
00468
00469 istream& operator>>(istream& fp, AString& as)
00470 {
00471 fp >> as.contents;
00472
00473 return fp;
00474 }
00475
00476
00477
00478
00479 #include <stdarg.h>
00480
00481
00482
00483
00484 AString ASFormat(char* fmt, ...){
00485 va_list arg_list;
00486 char s[1024];
00487
00488 va_start(arg_list, fmt);
00489 (void) vsprintf(s, fmt, arg_list);
00490 va_end(arg_list);
00491
00492 AString as = s;
00493 return as;
00494 }
00495
00496
00497
00498 AString toAS(unsigned char uc){
00499 return ASFormat("%c", uc);
00500 }
00501
00502
00503
00504 AString toAS(char c){
00505 return ASFormat("%c", c);
00506 }
00507
00508
00509
00510 AString toAS(unsigned short um){
00511 return ASFormat("%hu", um);
00512 }
00513
00514
00515
00516 AString toAS(short m){
00517 return ASFormat("%hd", m);
00518 }
00519
00520
00521
00522 AString toAS(unsigned int um){
00523 return ASFormat("%u", um);
00524 }
00525
00526
00527
00528 AString toAS(int m){
00529 return ASFormat("%d", m);
00530 }
00531
00532
00533
00534 AString toAS(unsigned long um){
00535 return ASFormat("%lu", um);
00536 }
00537
00538
00539
00540 AString toAS(long m){
00541 return ASFormat("%d", m);
00542 }
00543
00544
00545
00546 AString toAS(double d){
00547 return ASFormat("%g", d);
00548 }
00549
00550 }