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 #include "CSConfig.h"
00030 #include <inttypes.h>
00031
00032 #include <assert.h>
00033 #include <string.h>
00034 #include <ctype.h>
00035
00036 #include "CSGlobal.h"
00037 #include "CSUTF8.h"
00038 #include "CSStorage.h"
00039 #include "CSMemory.h"
00040 #include "CSString.h"
00041 #include "CSStrUtil.h"
00042 #include "CSGlobal.h"
00043
00044
00045
00046
00047
00048
00049
00050 CSStringBufferImpl::CSStringBufferImpl():
00051 iBuffer(NULL),
00052 iGrow(0),
00053 iSize(0),
00054 myStrLen(0)
00055 {
00056 iGrow = 20;
00057 }
00058
00059 CSStringBufferImpl::CSStringBufferImpl(uint32_t grow):
00060 iBuffer(NULL),
00061 iGrow(0),
00062 iSize(0),
00063 myStrLen(0)
00064 {
00065 iGrow = grow;
00066 }
00067
00068 CSStringBufferImpl::~CSStringBufferImpl()
00069 {
00070 clear();
00071 }
00072
00073 void CSStringBufferImpl::clear()
00074 {
00075 if (iBuffer)
00076 cs_free(iBuffer);
00077 iBuffer = NULL;
00078 iSize = 0;
00079 myStrLen = 0;
00080 }
00081
00082 void CSStringBufferImpl::append(char ch)
00083 {
00084 if (iSize == myStrLen) {
00085 cs_realloc((void **) &iBuffer, iSize + iGrow);
00086 iSize += iGrow;
00087 }
00088 iBuffer[myStrLen] = ch;
00089 myStrLen++;
00090 }
00091
00092 void CSStringBufferImpl::append(const char *str, size_t len)
00093 {
00094 if (myStrLen + len > iSize) {
00095 size_t add = len;
00096
00097 if (add < iGrow)
00098 add = iGrow;
00099 cs_realloc((void **) &iBuffer, iSize + add);
00100 iSize += add;
00101 }
00102 memcpy(iBuffer + myStrLen, str, len);
00103 myStrLen += len;
00104 }
00105
00106 void CSStringBufferImpl::append(int value)
00107 {
00108 char buffer[100];
00109
00110 snprintf(buffer, 100, "%d", value);
00111 append(buffer);
00112 }
00113
00114 void CSStringBufferImpl::append(uint32_t value)
00115 {
00116 char buffer[100];
00117
00118 snprintf(buffer, 100, "%"PRIu32, value);
00119 append(buffer);
00120 }
00121
00122 void CSStringBufferImpl::append(uint64_t value)
00123 {
00124 char buffer[100];
00125
00126 snprintf(buffer, 100, "%"PRIu64, value);
00127 append(buffer);
00128 }
00129
00130 char *CSStringBufferImpl::getCString()
00131 {
00132 if (iSize == myStrLen) {
00133 cs_realloc((void **) &iBuffer, iSize + 1);
00134 iSize++;
00135 }
00136 iBuffer[myStrLen] = 0;
00137 return iBuffer;
00138 }
00139
00140 char *CSStringBufferImpl::take()
00141 {
00142 char *buf;
00143
00144 cs_realloc((void **) &iBuffer, myStrLen + 1);
00145 iSize = myStrLen + 1;
00146 iBuffer[myStrLen] = 0;
00147
00148 buf = iBuffer;
00149 iBuffer = NULL;
00150 iSize = 0;
00151 myStrLen = 0;
00152 return buf;
00153 }
00154
00155 void CSStringBufferImpl::setLength(uint32_t len)
00156 {
00157 if (len > iSize) {
00158 cs_realloc((void **) &iBuffer, len + 1);
00159 iSize = len+1;
00160 }
00161 myStrLen = len;
00162 }
00163
00164 uint32_t CSStringBufferImpl::ignore(uint32_t pos, char ch)
00165 {
00166 while (pos < myStrLen && iBuffer[pos] == ch)
00167 pos++;
00168 return pos;
00169 }
00170
00171 uint32_t CSStringBufferImpl::find(uint32_t pos, char ch)
00172 {
00173 while (pos < myStrLen && iBuffer[pos] != ch)
00174 pos++;
00175 return pos;
00176 }
00177
00178 uint32_t CSStringBufferImpl::trim(uint32_t pos, char ch)
00179 {
00180 while (pos > 0 && iBuffer[pos-1] == ch)
00181 pos--;
00182 return pos;
00183 }
00184
00185 CSString *CSStringBufferImpl::substr(uint32_t pos, uint32_t len)
00186 {
00187 CSString *s = CSString::newString(iBuffer + pos, len);
00188
00189 return s;
00190 }
00191
00192
00193
00194
00195
00196
00197 CSString *CSString::concat(CSString *cat_str)
00198 {
00199 CSString *new_str = NULL;
00200 uint32_t len_a, len_b;
00201
00202 enter_();
00203 len_a = length();
00204 len_b = cat_str->length();
00205 new_str = clone(len_a + len_b);
00206 push_(new_str);
00207
00208 for (uint32_t i=0; i<len_b; i++)
00209 new_str->setCharAt(len_a+i, cat_str->charAt(i));
00210
00211 pop_(new_str);
00212 return_(new_str);
00213 }
00214
00215 CSString *CSString::concat(const char *cat_str)
00216 {
00217 CSString *new_str = NULL;
00218 uint32_t len_a, len_b;
00219
00220 enter_();
00221 len_a = length();
00222 len_b = strlen(cat_str);
00223 new_str = clone(len_a + len_b);
00224 push_(new_str);
00225
00226 for (uint32_t i=0; i<len_b; i++)
00227 new_str->setCharAt(len_a+i, cat_str[i]);
00228
00229 pop_(new_str);
00230 return_(new_str);
00231 }
00232
00233 CSString *CSString::toUpper()
00234 {
00235 CSString *new_str = NULL;
00236 uint32_t len;
00237
00238 enter_();
00239 new_str = clone();
00240 push_(new_str);
00241
00242 len = new_str->length();
00243 for (uint32_t i=0; i<len; i++)
00244 new_str->setCharAt(i, upperCharAt(i));
00245
00246 pop_(new_str);
00247 return_(new_str);
00248 }
00249
00250 uint32_t CSString::hashKey()
00251 {
00252 register uint32_t h = 0, g;
00253
00254 for (uint32_t i=0; i<length(); i++) {
00255 h = (h << 4) + (uint32_t) upperCharAt(i);
00256 if ((g = (h & 0xF0000000)))
00257 h = (h ^ (g >> 24)) ^ g;
00258 }
00259
00260 return (h);
00261 }
00262
00263 uint32_t CSString::locate(const char *w_cstr, int32_t count)
00264 {
00265 int32_t len = length();
00266 int32_t i;
00267
00268 if (count >= 0) {
00269 i = 0;
00270 while (i < len) {
00271 if (startsWith((uint32_t) i, w_cstr)) {
00272 count--;
00273 if (!count)
00274 return i;
00275 }
00276 i++;
00277 }
00278 }
00279 else {
00280 count = -count;
00281 i = len - (int32_t) strlen(w_cstr);
00282 while (i >= 0) {
00283 if (startsWith((uint32_t) i, w_cstr)) {
00284 count--;
00285 if (!count)
00286 return i;
00287 }
00288 i--;
00289 }
00290 }
00291 return i;
00292 }
00293
00294 uint32_t CSString::locate(uint32_t pos, const char *w_cstr)
00295 {
00296 uint32_t len = length();
00297 uint32_t i;
00298
00299 if (pos > len)
00300 return len;
00301 i = pos;
00302 while (i < len) {
00303 if (startsWith(i, w_cstr))
00304 return i;
00305 i++;
00306 }
00307 return i;
00308 }
00309
00310 uint32_t CSString::locate(uint32_t pos, CS_CHAR ch)
00311 {
00312 uint32_t len = length();
00313 uint32_t i;
00314
00315 if (pos > len)
00316 return len;
00317 i = pos;
00318 while (i < len) {
00319 if (charAt(i) == ch)
00320 return i;
00321 i++;
00322 }
00323 return i;
00324 }
00325
00326 uint32_t CSString::skip(uint32_t pos, CS_CHAR ch)
00327 {
00328 uint32_t len = length();
00329 uint32_t i;
00330
00331 if (pos > len)
00332 return len;
00333 i = pos;
00334 while (i < len) {
00335 if (charAt(i) != ch)
00336 return i;
00337 i++;
00338 }
00339 return i;
00340 }
00341
00342 CSString *CSString::substr(uint32_t index, uint32_t size)
00343 {
00344 return clone(index, size);
00345 }
00346
00347 CSString *CSString::substr(uint32_t index)
00348 {
00349 return clone(index, length() - index);
00350
00351 }
00352
00353 CSString *CSString::left(const char *w_cstr, int32_t count)
00354 {
00355 uint32_t idx = locate(w_cstr, count);
00356
00357 if (idx == (uint32_t)-1)
00358 return CSString::newString("");
00359 return substr(0, idx);
00360 }
00361
00362 CSString *CSString::left(const char *w_cstr)
00363 {
00364 return left(w_cstr, 1);
00365 }
00366
00367 CSString *CSString::right(const char *w_cstr, int32_t count)
00368 {
00369 uint32_t idx = locate(w_cstr, count);
00370
00371 if (idx == (uint32_t)-1) {
00372 return RETAIN(this);
00373 }
00374
00375 if (idx == length())
00376 return newString("");
00377
00378 return substr(idx + strlen(w_cstr));
00379 }
00380
00381 CSString *CSString::right(const char *w_cstr)
00382 {
00383 return right(w_cstr, 1);
00384 }
00385
00386 bool CSString::startsWith(const char *w_str)
00387 {
00388 return startsWith(0, w_str);
00389 }
00390
00391 bool CSString::endsWith(const char *w_str)
00392 {
00393 return startsWith(length() - strlen(w_str), w_str);
00394 }
00395
00396 uint32_t CSString::nextPos(uint32_t pos)
00397 {
00398 if (pos >= length())
00399 return length();
00400 return pos + 1;
00401 }
00402
00403 CSString *CSString::clone(uint32_t len)
00404 {
00405 return clone(0, len);
00406 }
00407
00408 CSString *CSString::clone()
00409 {
00410 return clone(0, length());
00411 }
00412
00413 bool CSString::equals(const char *str)
00414 {
00415 uint32_t len = length();
00416 uint32_t i;
00417
00418 for (i=0; i<len && *str; i++) {
00419 if (charAt(i) != *str)
00420 return false;
00421 str++;
00422 }
00423 return i==len && !*str;
00424 }
00425
00426
00427
00428
00429
00430
00431 CSString::CSString():
00432 myCString(NULL),
00433 myStrLen(0)
00434 {
00435 }
00436
00437 CSString::CSString(const char *cstr):
00438 myCString(cs_strdup(cstr)),
00439 myStrLen(strlen(cstr))
00440 {
00441 }
00442
00443 CSString::~CSString()
00444 {
00445 if (myCString)
00446 cs_free(myCString);
00447 }
00448
00449 const char *CSString::getCString()
00450 {
00451 return myCString;
00452 }
00453
00454 CS_CHAR CSString::charAt(uint32_t pos)
00455 {
00456 if (pos < myStrLen)
00457 return (CS_CHAR) (unsigned char) myCString[pos];
00458 return (CS_CHAR) 0;
00459 }
00460
00461 CS_CHAR CSString::upperCharAt(uint32_t pos)
00462 {
00463 if (pos < myStrLen)
00464 return (CS_CHAR) (unsigned char) toupper(myCString[pos]);
00465 return (CS_CHAR) 0;
00466 }
00467
00468 void CSString::setCharAt(uint32_t pos, CS_CHAR ch)
00469 {
00470 if (pos < myStrLen)
00471 myCString[pos] = (unsigned char) ch;
00472 }
00473
00474 int CSString::compare(const char *val, uint32_t len)
00475 {
00476 const char *pa = myCString, *pb = val;
00477 int r = 0;
00478
00479 enter_();
00480
00481 if (pa && pb) {
00482 while (*pa && *pb && len) {
00483 r = toupper(*pa) - toupper(*pb);
00484 if (r != 0)
00485 break;
00486 pa++;
00487 pb++;
00488 len--;
00489 }
00490 if (len)
00491 r = toupper(*pa) - toupper(*pb);
00492 }
00493
00494 return_(r);
00495 }
00496
00497 int CSString::compare(CSString *val)
00498 {
00499 return compare(val->getCString(), (uint32_t)-1);
00500 }
00501
00502 bool CSString::startsWith(uint32_t index, const char *w_str)
00503 {
00504 uint32_t len = strlen(w_str);
00505 char *str;
00506
00507 if (index > myStrLen)
00508 index = myStrLen;
00509 str = myCString + index;
00510 for (uint32_t i=0; i<len && *str; i++) {
00511 if (*str != *w_str)
00512 return false;
00513 str++;
00514 w_str++;
00515 }
00516 return (*w_str == 0);
00517 }
00518
00519 void CSString::setLength(uint32_t len)
00520 {
00521 cs_realloc((void **) &myCString, len+1);
00522 myCString[len] = 0;
00523 myStrLen = len;
00524 }
00525
00526 CSString *CSString::clone(uint32_t pos, uint32_t len)
00527 {
00528 CSString *str = NULL;
00529
00530 enter_();
00531 new_(str, CSString());
00532 push_(str);
00533
00534 str->myCString = (char *) cs_malloc(len + 1);
00535 str->myStrLen = len;
00536 if (pos > myStrLen)
00537 pos = myStrLen;
00538 if (len > myStrLen - pos) {
00539
00540
00541
00542
00543
00544 str->myCString[len] = 0;
00545 len = myStrLen - pos;
00546 }
00547 memcpy(str->myCString, myCString+pos, len);
00548 str->myCString[len] = 0;
00549
00550 pop_(str);
00551 return_(str);
00552 }
00553
00554 CSObject *CSString::getKey()
00555 {
00556 return (CSObject *) this;
00557 }
00558
00559 int CSString::compareKey(CSObject *key)
00560 {
00561 return compare((CSString *) key);
00562 }
00563
00564 CSString *CSString::newString(const char *cstr)
00565 {
00566 CSString *str;
00567
00568 enter_();
00569 new_(str, CSString());
00570 push_(str);
00571 str->myCString = cs_strdup(cstr);
00572 str->myStrLen = strlen(cstr);
00573 pop_(str);
00574 return_(str);
00575 }
00576
00577 CSString *CSString::newString(const char *bytes, uint32_t len)
00578 {
00579 CSString *str;
00580
00581 enter_();
00582 new_(str, CSString());
00583 push_(str);
00584 str->myStrLen = len;
00585 str->myCString = (char *) cs_malloc(len+1);
00586 memcpy(str->myCString, bytes, len);
00587 str->myCString[len] = 0;
00588 pop_(str);
00589 return_(str);
00590 }
00591
00592 CSString *CSString::newString(CSStringBuffer *sb)
00593 {
00594 CSString *str;
00595
00596 enter_();
00597 push_(sb);
00598 new_(str, CSString());
00599 push_(str);
00600 str->myStrLen = sb->length();
00601 str->myCString = sb->take();
00602 pop_(str);
00603 pop_(sb);
00604 return_(str);
00605 }
00606