00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "nstring.h"
00023
00024 const nuint32 NString::ALLOC_SIZE = 64;
00025 const nint32 NString::NOT_FOUND = -1;
00026
00031 NString::NString(void)
00032 : m_string(NULL),
00033 m_used(0),
00034 m_allocated(0)
00035 {
00036 set("");
00037 }
00038
00039
00040 NString::NString(const char *str)
00041 : m_string(NULL),
00042 m_used(0),
00043 m_allocated(0)
00044 {
00045 set(str);
00046 }
00047
00048
00049 NString::NString(const NString &str)
00050 : m_string(NULL),
00051 m_used(0),
00052 m_allocated(0)
00053 {
00054 set(str);
00055 }
00056
00057 NString::~NString(void) {
00058 delete[] m_string;
00059
00060 }
00061
00062 bool NString::needsMemory(nuint32 bytes) {
00063 if (bytes >= m_allocated) {
00064 return true;
00065 }
00066
00067 if (bytes >= (m_allocated - m_used)) {
00068 return true;
00069 }
00070
00071 return false;
00072 }
00073
00074
00075 nuint32 NString::calculateBlocks(nuint32 bytes) {
00076 nuint32 blocks = 0;
00077 nuint32 mod = 0;
00078
00079 blocks = bytes / ALLOC_SIZE;
00080 mod = bytes % ALLOC_SIZE;
00081 if (blocks == 0) {
00082 blocks = 1;
00083 }
00084
00085 if (mod > 0) {
00086 blocks++;
00087 }
00088
00089 return blocks;
00090 }
00091
00092
00093 inline void NString::memcopy(char *dest) {
00094 assert(dest);
00095
00096 if (m_string) {
00097 memcpy(dest, m_string, m_used);
00098
00099
00100 delete[] m_string;
00101 }
00102
00103 m_string = dest;
00104 }
00105
00106
00107 void NString::realloc(nuint32 bytes) {
00108 nuint32 blocks = 0;
00109
00110 char *data_ptr = NULL;
00111
00112 if (!needsMemory(bytes)) {
00113 return;
00114 }
00115
00116 blocks = calculateBlocks(bytes + m_used);
00117 m_allocated = blocks * ALLOC_SIZE;
00118
00119 data_ptr = new char[m_allocated];
00120
00121
00122 memset(data_ptr, 0, m_allocated);
00123 memcopy(data_ptr);
00124 }
00125
00126 inline nuint32 NString::freeBytes(void) const {
00127 return m_allocated - m_used;
00128 }
00129
00130
00131 NString &NString::set(const char *str) {
00132 unsigned int len = 0;
00133
00134
00135 if (str) {
00136 len = strlen(str);
00137
00138 if (len == 0) {
00139 memset(m_string, 0, m_allocated);
00140 m_used = 0;
00141 }
00142 else {
00143 if (m_allocated <= len) {
00144 realloc(len + 1);
00145 }
00146
00147 memset(m_string, 0, m_allocated);
00148 memcpy(m_string, str, len);
00149 m_used = len;
00150 }
00151 }
00152 else {
00153 len = 1;
00154 if (m_allocated <= len) {
00155 realloc(len);
00156 }
00157 memset(m_string, 0, m_allocated);
00158 m_used = 0;
00159 }
00160
00161 return *this;
00162 }
00163
00164
00165 NString &NString::set(const NString &str) {
00166 return set(str.toChar());
00167 }
00168
00169 const char *NString::toChar() const {
00170 return m_string;
00171 }
00172
00173
00174 NString NString::number(int num) {
00175 char tmpBuff[1024];
00176
00177 memset(tmpBuff, 0, sizeof(tmpBuff));
00178 #ifdef _MSC_VER
00179 _snprintf_s(tmpBuff, sizeof(tmpBuff), "%i", num);
00180 #else
00181 snprintf(tmpBuff, sizeof(tmpBuff), "%i", num);
00182 #endif
00183
00184 return NString(tmpBuff);
00185 }
00186
00187
00188 NString NString::number(nint64 num) {
00189 char tmpBuff[1024];
00190
00191 memset(tmpBuff, 0, sizeof(tmpBuff));
00192 #ifdef _MSC_VER
00193 _snprintf_s(tmpBuff, sizeof(tmpBuff), "%lli", num);
00194 #else
00195 snprintf(tmpBuff, sizeof(tmpBuff), "%lli", num);
00196 #endif // _MSC_VER
00197
00198 return NString(tmpBuff);
00199 }
00200
00201
00202 unsigned int NString::length(void) const {
00203 return m_used;
00204 }
00205
00206
00207 bool NString::isNull() const {
00208 if (!m_string || this->length() == 0) {
00209 return true;
00210 }
00211
00212 return false;
00213 }
00214
00215
00216 NString &NString::append(const char *str, nuint32 bytes) {
00217 assert(str);
00218
00219 if (freeBytes() < bytes) {
00220 realloc(bytes);
00221 }
00222
00223 strncat(m_string, str, bytes);
00224 m_used += bytes;
00225 m_string[m_used] = 0;
00226 return *this;
00227 }
00228
00229 inline NString &NString::append(const char *str) {
00230 assert(str);
00231 return append(str, strlen(str));
00232 }
00233
00234
00235 NString &NString::append(const NString &str) {
00236 append(str.toChar());
00237 return *this;
00238 }
00239
00240
00241 NString &NString::append(char c) {
00242 return append(&c, 2);
00243 }
00244
00245 NString &NString::insert(nuint32 pos, nuint32 size, const NString str) {
00246 char tmp[m_used];
00247 nuint32 bytes = 0;
00248
00249 if (pos > m_used) {
00250 pos = m_used;
00251
00252 }
00253 strcpy(tmp, m_string);
00254 bytes = this->length() + size + 1;
00255 if (freeBytes() < bytes) {
00256 realloc(bytes);
00257 }
00258
00259 memset(m_string, 0, sizeof(m_allocated));
00260 strncpy(m_string, tmp, pos);
00261 strncat(m_string, str.toChar(), size);
00262 strncat(m_string, tmp + pos, m_used);
00263 m_used = bytes;
00264
00265 return *this;
00266 }
00267
00268
00269 NString &NString::insert(nuint32 pos, const NString str) {
00270 return insert(pos, str.length(), str);
00271 }
00272
00273
00274 bool NString::compare(nuint32 pos, nuint32 size, const NString &str) const {
00275 if (isNull() && str.isNull()) {
00276 return true;
00277 }
00278 else {
00279 if (isNull() && (str == "")) {
00280 return true;
00281 }
00282 }
00283
00284 if (size == 0) {
00285 return false;
00286 }
00287
00288 if (pos > this->length() || (pos + size) > this->length()
00289 || size > str.length())
00290 {
00291 return false;
00292 }
00293
00294 if (strncmp(m_string + pos, str.toChar(), size) == 0) {
00295 return true;
00296 }
00297
00298 return false;
00299 }
00300
00301 bool NString::compare(nuint32 pos, const NString &str) const {
00302 return compare(pos, this->length(), str);
00303
00304 }
00305
00306 bool NString::compare(nuint32 pos, nuint32 size, const NString &str,
00307 nuint32 str_pos) const
00308 {
00309 if (pos > this->length() || (pos + size) > this->length() ||
00310 str_pos < str.length())
00311 {
00312 return false;
00313 }
00314
00315 if (strncmp(m_string + pos, str.toChar() + str_pos, size) == 0) {
00316 return true;
00317 }
00318
00319 return true;
00320 }
00321
00322 NString NString::substr(nuint32 pos, nuint32 size) const {
00323 NString ret;
00324 char tmp[m_used + 1];
00325
00326 if (pos > this->length() || (pos + size) > this->length()) {
00327 return ret;
00328 }
00329
00330 memset(tmp, 0, sizeof(tmp));
00331 memcpy(tmp, m_string + pos, size);
00332 ret = tmp;
00333
00334 return ret;
00335 }
00336
00337
00338 nint32 NString::find(const NString &str, nuint32 pos, nuint32 ocur) const {
00339 nint32 ret = 0;
00340 for (nuint32 i = 0; i < ocur; i++) {
00341 ret = find(str, pos);
00342 if (ret == NString::NOT_FOUND) {
00343 return NString::NOT_FOUND;
00344 }
00345 }
00346
00347 return ret;
00348 }
00349
00350
00351 nint32 NString::find(const NString &str, nuint32 pos) const {
00352 for (nuint32 i = pos; i < m_used; i++) {
00353 if (this->operator[](i) == str[0]) {
00354 if (compare(i, str.length(), str)) {
00355 return i;
00356 }
00357 }
00358 }
00359
00360 return NString::NOT_FOUND;
00361
00362 }
00363
00364
00365 nint32 NString::find(const NString &str) const {
00366 return find(str, 0);
00367 }
00368
00369
00370 NString &NString::replace_first(const NString &src, const NString &dest) {
00371 NString tmp;
00372 nuint32 pos = NString::NOT_FOUND;
00373
00374 pos = find(src);
00375 tmp = "";
00376 if (pos != NString::NOT_FOUND) {
00377
00378 tmp += substr(0, pos);
00379
00380 tmp += dest;
00381
00382 tmp += substr(pos + src.length(), length() - (pos + src.length()));
00383
00384 set(tmp);
00385 }
00386
00387
00388 return *this;
00389 }
00390
00391
00392 NString &NString::replace(const NString &src, const NString &dest) {
00393 NString tmp = *this;
00394 NString last;
00395
00396 do {
00397 tmp.replace_first(src, dest);
00398
00399 if (tmp == *this) {
00400 break;
00401 }
00402 set(tmp);
00403 } while (true);
00404
00405 return *this;
00406 }
00407
00408
00409 NString &NString::replace(const NString &src, const NString &dest,
00410 nuint32 ocur)
00411 {
00412 NString tmp = *this;
00413 NString last;
00414
00415 nuint32 count = 0;
00416 do {
00417 tmp.replace_first(src, dest);
00418
00419 if (tmp == *this) {
00420 break;
00421 }
00422
00423 count++;
00424 set(tmp);
00425 } while (count < ocur);
00426
00427 return *this;
00428 }
00429
00430
00431 NList<NString> NString::split(const NString &str) {
00432 nint32 pos = 0;
00433 nint32 last = 0;
00434 NString tmp;
00435 NList<NString> ret;
00436
00437 do {
00438 last = find(str, pos);
00439 if (last > NString::NOT_FOUND) {
00440 tmp = substr(pos, last - pos);
00441 ret.append(tmp);
00442
00443
00444 }
00445 else {
00446 if (pos == 0 && last == NString::NOT_FOUND) {
00447 tmp = substr(pos, length() - pos);
00448 }
00449 else {
00450 tmp = substr(pos, length() - pos);
00451 }
00452 ret.append(tmp);
00453
00454
00455 break;
00456 }
00457 pos = last + 1;
00458 } while (pos != NString::NOT_FOUND);
00459
00460 return ret;
00461 }
00462
00463
00464 NString NString::operator+(const char *str) {
00465 return append(str);
00466 }
00467
00468
00469 NString NString::operator+(char c) {
00470 return append(c);
00471 }
00472
00473
00474 NString NString::operator+(const NString &str) {
00475 return append(str);
00476 }
00477
00478
00479 NString &NString::operator+=(const char *str) {
00480 return append(str);
00481 }
00482
00483
00484 NString &NString::operator+=(const NString &str) {
00485 return append(str);
00486 }
00487
00488
00489 NString &NString::operator+=(char c) {
00490 return append(c);
00491 }
00492
00493
00494 char NString::operator[](unsigned int index) const {
00495 return m_string[index];
00496 }
00497
00498
00499 bool NString::operator==(const NString &str) const {
00500 return compare(0, str);
00501 }
00502
00503
00504 bool NString::operator!=(const NString &str) const {
00505 return (!compare(0, str));
00506 }
00507
00508
00509
00510 bool NString::operator>(const NString &str) const {
00511 int res = 0;
00512
00513 res = strcmp(m_string, str.toChar());
00514 if (res <= 0) {
00515 return false;
00516 }
00517
00518 return true;
00519 }
00520
00521
00522 bool NString::operator<(const NString &str) const {
00523 int res = 0;
00524
00525 res = strcmp(m_string, str.toChar());
00526 if (res >= 0) {
00527 return false;
00528 }
00529
00530 return true;
00531 }
00532
00533
00534 bool NString::operator>=(const NString &str) const {
00535 int res = 0;
00536
00537 res = strcmp(m_string, str.toChar());
00538 if (res < 0) {
00539 return false;
00540 }
00541
00542 return true;
00543 }
00544
00545
00546 bool NString::operator<=(const NString &str) const {
00547 int res = 0;
00548
00549 res = strcmp(m_string, str.toChar());
00550 if (res > 0) {
00551 return false;
00552 }
00553
00554 return true;
00555 }
00556
00557
00558 NString &NString::operator=(const NString &str) {
00559 return set(str);
00560 }
00561
00562
00563 NString &NString::arg(const char *fmt, ...) {
00564 va_list ap;
00565 char *ret = NULL;
00566
00567 assert(fmt);
00568 set(fmt);
00569
00570 va_start(ap, fmt);
00571 free(ret);
00572
00573 n_vasprintf(fmt, ap, ret);
00574 if (ret) {
00575 set(ret);
00576 free(ret);
00577 }
00578 va_end(ap);
00579
00580 return *this;
00581 }