nstring.cpp

Go to the documentation of this file.
00001 // LICENSE: (Please see the file COPYING for details)
00002 //
00003 // NUS - Nemesis Utilities System: A C++ application development framework 
00004 // Copyright (C) 2006, 2008 Otavio Rodolfo Piske
00005 //
00006 //  This file is part of NUS
00007 //
00008 //  This library is free software; you can redistribute it and/or
00009 //  modify it under the terms of the GNU Lesser General Public
00010 //  License as published by the Free Software Foundation version 2.1
00011 //  of the License.
00012 //
00013 //  This library is distributed in the hope that it will be useful,
00014 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 //  Lesser General Public License for more details.
00017 //
00018 //  You should have received a copy of the GNU Lesser General Public
00019 //  License along with this library; if not, write to the Free Software
00020 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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             //printf("[DEBUG] Deallocated: %i bytes at %p (%s)\n", m_allocated, 
00099             //    m_string, m_string);
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       //printf("[DEBUG] Allocated: %i bytes in %i blocks at %p (%s)\n", 
00121       //    m_allocated, blocks, data_ptr, m_string);
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             //printf("[DEBUG] Input len is %i\n", len);
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); // 2 -> for the char and the NULL terminator
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             //printf("Found in = %i\n", pos);
00378             tmp += substr(0, pos);
00379             //printf("TMP = %s\n", tmp.toChar());
00380             tmp += dest;
00381             //printf("E) TMP = %s\n", tmp.toChar());
00382             tmp += substr(pos + src.length(), length() - (pos + src.length()));
00383 
00384             set(tmp);
00385       }
00386       
00387       //printf("F) TMP = %s\n", tmp.toChar());
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             // printf("1) TMP = %s\n", tmp.toChar());
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             // printf("1) TMP = %s\n", tmp.toChar());
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                   //printf("[DEBUG] Adding %s (from %i:%i)\n", 
00443                   //    tmp.toChar(), pos, last);
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                   //printf("[DEBUG] Adding last %s (from %i:%i|%i)\n", 
00454                   //    tmp.toChar(), pos, last, length());
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 }

Generated on Wed Mar 5 23:10:36 2008 for NemesisUtilitiesSystem by  doxygen 1.5.4