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 #include "LampBasic.h"
00026 #include "Core/Primitive/String.h"
00027 #include "Core/System/StringMethod.h"
00028
00029 namespace Lamp{
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 inline static char* newString(int length){
00040 char* returnString = new char[sizeof(int) + length + 1];
00041
00042 *(int*)returnString = 1;
00043 returnString += sizeof(int);
00044 return returnString;
00045 }
00046
00047
00048
00049
00050
00051
00052 inline static int releaseString(char** string){
00053 if((*string) != NULL){
00054
00055 int* refCount = (int*)((*string) - sizeof(int));
00056 (*refCount) -= 1;
00057 int returnCount = *refCount;
00058 if(returnCount == 0){ delete[] refCount; }
00059 (*string) = NULL;
00060 return returnCount;
00061 }
00062 return 0;
00063 }
00064
00065
00066
00067
00068
00069
00070 inline static int addReferenceCounter(char* string){
00071
00072 int* counterAddress = (int*)(string - sizeof(int));
00073 *counterAddress += 1;
00074 return *counterAddress;
00075 }
00076
00077
00078
00079
00080
00081
00082 inline static int getReferenceCounter(char* string){
00083 return *(int*)(string - sizeof(int));
00084 }
00085
00086
00087
00088
00089 String::String() : string_(NULL), size_(0){
00090 }
00091
00092
00093 String::String(const char* initString){
00094 if(initString == NULL){
00095 string_ = NULL;
00096 size_ = 0;
00097 return;
00098 }
00099 size_ = (int)StdStrlen(initString);
00100 Assert(size_ >= 0);
00101 if(size_ == 0){
00102 string_ = NULL;
00103 return;
00104 }
00105 string_ = newString(size_);
00106 StdStrcpy(string_, initString);
00107 }
00108
00109
00110 String::String(const String& copy){
00111 size_ = copy.getSize();
00112 Assert(size_ >= 0);
00113 if(size_ == 0){
00114 string_ = NULL;
00115 return;
00116 }
00117 string_ = copy.string_;
00118 addReferenceCounter(string_);
00119 }
00120
00121
00122 String::String(char* initString, int initLength){
00123 Assert(initString != NULL);
00124 Assert(initLength >= 0);
00125 string_ = initString;
00126 size_ = initLength;
00127 }
00128
00129
00130 String& String::operator =(const String& copy){
00131
00132 if(this == ©){ return *this; }
00133 releaseString(&string_);
00134 size_ = copy.getSize();
00135 Assert(size_ >= 0);
00136 if(size_ == 0){
00137 string_ = NULL;
00138 return *this;
00139 }
00140 string_ = copy.string_;
00141 addReferenceCounter(string_);
00142 return *this;
00143 }
00144
00145
00146 String& String::operator =(const char* copy){
00147 releaseString(&string_);
00148 if(copy == NULL){
00149 string_ = NULL;
00150 size_ = 0;
00151 return *this;
00152 }
00153 size_ = (int)StdStrlen(copy);
00154 Assert(size_ >= 0);
00155 if(size_ == 0){
00156 string_ = NULL;
00157 return *this;
00158 }
00159 string_ = newString(size_);
00160 StdStrcpy(string_, copy);
00161 return *this;
00162 }
00163
00164
00165 String::~String(){
00166 releaseString(&string_);
00167 }
00168
00169
00170
00171
00172 int String::getCharacterCount() const{
00173 return (int)StdMbslen(getBytes());
00174 }
00175
00176
00177 String String::getSubstring(int beginIndex) const{
00178 if(beginIndex == 0){ return *this; }
00179 Assert(beginIndex >= 0);
00180 Assert((beginIndex <= size_));
00181
00182 if(beginIndex == size_){ return String(); }
00183 int newLength = size_ - beginIndex;
00184 char* newArray = newString(newLength);
00185 StdStrcpy(newArray, string_ + beginIndex);
00186 return String(newArray, newLength);
00187 }
00188
00189
00190 String String::getSubstring(int beginIndex, int endIndex) const{
00191 Assert(beginIndex >= 0);
00192 Assert(endIndex >= 0);
00193 Assert((endIndex <= size_));
00194 Assert((beginIndex <= endIndex));
00195
00196 if(beginIndex == endIndex){ return String(); }
00197 int newLength = endIndex - beginIndex;
00198 char* newArray = newString(newLength);
00199 for(int i = 0; i < newLength; i++){
00200 newArray[i] = string_[i + beginIndex];
00201 }
00202 newArray[newLength] = '\0';
00203 return String(newArray, newLength);
00204 }
00205
00206
00207 String String::getUpperCase() const{
00208
00209 String returnString(this->getBytes());
00210 if(returnString.getSize() == 0){ return returnString; }
00211 StdStrupr(returnString.string_);
00212 return returnString;
00213 }
00214
00215
00216 String String::getLowerCase() const{
00217
00218 String returnString(this->getBytes());
00219 if(returnString.getSize() == 0){ return returnString; }
00220 StdStrlwr(returnString.string_);
00221 return returnString;
00222 }
00223
00224
00225 u_int String::getHashCode() const{
00226 u_int hashCode = 0;
00227 if(size_ == 0){ return hashCode; }
00228 const char* position = getBytes();
00229 for(int i = 0;i < size_;i++){
00230 hashCode = hashCode * 31 + position[i];
00231 }
00232 return hashCode;
00233 }
00234
00235
00236
00237
00238 bool String::parseChar(char* value) const{
00239 Assert(value != NULL);
00240 int scanValue;
00241 int scanCount = StdSscanf(string_, "%d", &scanValue);
00242 if((scanCount == 1) &&
00243 (scanValue <= Limit::charMax) && (scanValue >= Limit::charMin)){
00244 *value = (char)scanValue;
00245 return true;
00246 }
00247 return false;
00248 }
00249
00250
00251 bool String::parseUChar(u_char* value) const{
00252 Assert(value != NULL);
00253 int scanValue;
00254 int scanCount = StdSscanf(string_, "%d", &scanValue);
00255 if((scanCount == 1) &&
00256 (scanValue <= Limit::uCharMax) && (scanValue >= Limit::uCharMin)){
00257 *value = (u_char)scanValue;
00258 return true;
00259 }
00260 return false;
00261 }
00262
00263
00264 bool String::parseShort(short* value) const{
00265 Assert(value != NULL);
00266 int scanValue;
00267 int scanCount = StdSscanf(string_, "%d", &scanValue);
00268 if((scanCount == 1) &&
00269 (scanValue <= Limit::shortMax) && (scanValue >= Limit::shortMin)){
00270 *value = (short)scanValue;
00271 return true;
00272 }
00273 return false;
00274 }
00275
00276
00277 bool String::parseUShort(u_short* value) const{
00278 Assert(value != NULL);
00279 int scanValue;
00280 int scanCount = StdSscanf(string_, "%d", &scanValue);
00281 if((scanCount == 1) &&
00282 (scanValue <= Limit::uShortMax) && (scanValue >= Limit::uShortMin)){
00283 *value = (u_short)scanValue;
00284 return true;
00285 }
00286 return false;
00287 }
00288
00289
00290 bool String::parseInt(int* value) const{
00291 Assert(value != NULL);
00292 int scanCount = StdSscanf(string_, "%d", value);
00293 if(scanCount == 1){ return true; }
00294 return false;
00295 }
00296
00297
00298 bool String::parseUInt(u_int* value) const{
00299 Assert(value != NULL);
00300 int scanCount = StdSscanf(string_, "%u", value);
00301 if(scanCount == 1){ return true; }
00302 return false;
00303 }
00304
00305
00306 bool String::parseFloat(float* value) const{
00307 Assert(value != NULL);
00308 int scanCount = StdSscanf(string_, "%f", value);
00309 if(scanCount == 1){ return true; }
00310 return false;
00311 }
00312
00313
00314 bool String::parseDouble(double* value) const{
00315 Assert(value != NULL);
00316 int scanCount = StdSscanf(string_, "%lf", value);
00317 if(scanCount == 1){ return true; }
00318 return false;
00319 }
00320
00321
00322
00323
00324 String& String::append(const String& appendString){
00325 int appendLength = appendString.getSize();
00326 if(appendLength == 0){ return *this; }
00327 int newLength = size_ + appendLength;
00328 char* newArray = newString(newLength);
00329 if(size_ != 0){ std::memcpy(newArray, string_, size_); }
00330 std::memcpy(newArray + size_, appendString.getBytes(), appendLength);
00331 newArray[newLength] = '\0';
00332 releaseString(&string_);
00333 string_ = newArray;
00334 size_ = newLength;
00335 return *this;
00336 }
00337
00338
00339 String& String::append(const char* appendString){
00340 Assert(appendString != NULL);
00341 int appendLength = (int)StdStrlen(appendString);
00342 if(appendLength == 0){ return *this; }
00343 int newLength = size_ + appendLength;
00344 char* newArray = newString(newLength);
00345 if(size_ != 0){ std::memcpy(newArray, string_, size_); }
00346 std::memcpy(newArray + size_, appendString, appendLength);
00347 newArray[newLength] = '\0';
00348 releaseString(&string_);
00349 string_ = newArray;
00350 size_ = newLength;
00351 return *this;
00352 }
00353
00354
00355 String& String::format(const char* formatString, ...){
00356 Assert(formatString != NULL);
00357 releaseString(&string_);
00358
00359 if(formatString[0] == '\0'){
00360 string_ = NULL;
00361 size_ = 0;
00362 return *this;
00363 }
00364 int allocateSize = formatDefaultLength;
00365 va_list args;
00366 va_start(args, formatString);
00367 while(true){
00368 int maxLength = allocateSize - sizeof(int) - 1;
00369 string_ = newString(maxLength);
00370 int result = StdVsnprintf(string_, maxLength, formatString, args);
00371 if(result != -1){
00372 size_ = result;
00373 if(size_ == 0){
00374 releaseString(&string_);
00375 }else{
00376
00377 string_[size_] = '\0';
00378 }
00379 break;
00380 }
00381 allocateSize *= 2;
00382 releaseString(&string_);
00383 }
00384 va_end(args);
00385 return *this;
00386 }
00387
00388
00389
00390
00391 int String::compareTo(const String& compareString) const{
00392 return StdStrcmp(getBytes(), compareString.getBytes());
00393 }
00394
00395
00396 int String::compareTo(const char* compareString) const{
00397 Assert(compareString != NULL);
00398 return StdStrcmp(getBytes(), compareString);
00399 }
00400
00401
00402 int String::compareToIgnoreCase(const String& compareString) const{
00403 String source = this->getLowerCase();
00404 String destination = compareString.getLowerCase();
00405 return StdStrcmp(source.getBytes(), destination.getBytes());
00406 }
00407
00408
00409 bool String::equals(const String& compareString) const{
00410 return (StdStrcmp(getBytes(), compareString.getBytes()) == 0);
00411 }
00412
00413
00414 bool String::equals(const char* compareString) const{
00415 Assert(compareString != NULL);
00416 return (StdStrcmp(getBytes(), compareString) == 0);
00417 }
00418
00419
00420 bool String::equalsIsIgnoreCase(const String& compareString) const{
00421 String source = this->getLowerCase();
00422 String destination = compareString.getLowerCase();
00423 return (StdStrcmp(source.getBytes(), destination.getBytes()) == 0);
00424 }
00425
00426
00427 bool String::startsWith(const String& prefix) const{
00428 return (StdStrncmp(getBytes(), prefix.getBytes(), prefix.getSize()) == 0);
00429 }
00430
00431
00432 bool String::startsWith(const char* prefix) const{
00433 Assert(prefix != NULL);
00434 return (StdStrncmp(getBytes(), prefix, StdStrlen(prefix)) == 0);
00435 }
00436
00437
00438 bool String::endsWith(const String& suffix) const{
00439 int index = size_ - suffix.getSize();
00440 if(index < 0){ return false; }
00441 return (StdStrncmp(getBytes() + index,
00442 suffix.getBytes(), suffix.getSize()) == 0);
00443 }
00444
00445
00446 bool String::endsWith(const char* suffix) const{
00447 Assert(suffix != NULL);
00448 int suffixLength = (int)StdStrlen(suffix);
00449 int index = size_ - suffixLength;
00450 if(index < 0){ return false; }
00451 return (StdStrncmp(getBytes() + index, suffix, suffixLength) == 0);
00452 }
00453
00454
00455 int String::getIndexOf(const char searchChar) const{
00456 char* indexPointer = StdStrchr(getBytes(), searchChar);
00457 if(indexPointer == NULL){ return -1; }
00458 return (int)(indexPointer - getBytes());
00459 }
00460
00461
00462 int String::getIndexOf(const char* searchString) const{
00463 Assert(searchString != NULL);
00464 char* indexPointer = StdStrstr(getBytes(), searchString);
00465 if(indexPointer == NULL){ return -1; }
00466 return (int)(indexPointer - getBytes());
00467 }
00468
00469
00470 int String::getIndexOf(const String& searchString) const{
00471 char* indexPointer = StdStrstr(getBytes(), searchString.getBytes());
00472 if(indexPointer == NULL){ return -1; }
00473 return (int)(indexPointer - getBytes());
00474 }
00475
00476
00477 int String::getLastIndexOf(const char searchChar) const{
00478 char* indexPointer = StdStrrchr(getBytes(), searchChar);
00479 if(indexPointer == NULL){ return -1; }
00480 return (int)(indexPointer - getBytes());
00481 }
00482
00483
00484 int String::getLastIndexOf(const char* searchString) const{
00485 Assert(searchString != NULL);
00486 if(StdStrlen(searchString) == 0){ return size_; }
00487 const char* indexPointer = NULL;
00488 const char* target = getBytes();
00489 while(true){
00490 target = StdStrstr(target, searchString);
00491 if(target == NULL){ break; }
00492 indexPointer = target;
00493 target++;
00494 }
00495 if(indexPointer == NULL){ return -1; }
00496 return (int)(indexPointer - getBytes());
00497 }
00498
00499
00500 int String::getLastIndexOf(const String& searchString) const{
00501 if(searchString.getSize() == 0){ return size_; }
00502 const char* search = searchString.getBytes();
00503 const char* indexPointer = NULL;
00504 const char* target = getBytes();
00505 while(true){
00506 target = StdStrstr(target, search);
00507 if(target == NULL){ break; }
00508 indexPointer = target;
00509 target++;
00510 }
00511 if(indexPointer == NULL){ return -1; }
00512 return (int)(indexPointer - getBytes());
00513 }
00514
00515 #ifdef _DEBUG
00516
00517 void String::debugPrint(){
00518 DebugOut("[%2d] %s\n", getReferenceCounter(string_), string_);
00519 }
00520 #endif// End of _DEBUG
00521
00522 }
00523
00524
00525 const Lamp::String operator+(
00526 const Lamp::String& leftString, const Lamp::String& rightString){
00527 Lamp::String returnString(leftString);
00528 returnString.append(rightString);
00529 return returnString;
00530 }
00531