00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <ndb_global.h>
00019 #include <BaseString.hpp>
00020 #include <basestring_vsnprintf.h>
00021
00022 BaseString::BaseString()
00023 {
00024 m_chr = new char[1];
00025 m_chr[0] = 0;
00026 m_len = 0;
00027 }
00028
00029 BaseString::BaseString(const char* s)
00030 {
00031 const size_t n = strlen(s);
00032 m_chr = new char[n + 1];
00033 memcpy(m_chr, s, n + 1);
00034 m_len = n;
00035 }
00036
00037 BaseString::BaseString(const BaseString& str)
00038 {
00039 const char* const s = str.m_chr;
00040 const size_t n = str.m_len;
00041 char* t = new char[n + 1];
00042 memcpy(t, s, n + 1);
00043 m_chr = t;
00044 m_len = n;
00045 }
00046
00047 BaseString::~BaseString()
00048 {
00049 delete[] m_chr;
00050 }
00051
00052 BaseString&
00053 BaseString::assign(const char* s)
00054 {
00055 const size_t n = strlen(s);
00056 char* t = new char[n + 1];
00057 memcpy(t, s, n + 1);
00058 delete[] m_chr;
00059 m_chr = t;
00060 m_len = n;
00061 return *this;
00062 }
00063
00064 BaseString&
00065 BaseString::assign(const char* s, size_t n)
00066 {
00067 char* t = new char[n + 1];
00068 memcpy(t, s, n);
00069 t[n] = 0;
00070 delete[] m_chr;
00071 m_chr = t;
00072 m_len = n;
00073 return *this;
00074 }
00075
00076 BaseString&
00077 BaseString::assign(const BaseString& str, size_t n)
00078 {
00079 if (n > str.m_len)
00080 n = str.m_len;
00081 return assign(str.m_chr, n);
00082 }
00083
00084 BaseString&
00085 BaseString::append(const char* s)
00086 {
00087 const size_t n = strlen(s);
00088 char* t = new char[m_len + n + 1];
00089 memcpy(t, m_chr, m_len);
00090 memcpy(t + m_len, s, n + 1);
00091 delete[] m_chr;
00092 m_chr = t;
00093 m_len += n;
00094 return *this;
00095 }
00096
00097 BaseString&
00098 BaseString::append(char c) {
00099 return appfmt("%c", c);
00100 }
00101
00102 BaseString&
00103 BaseString::append(const BaseString& str)
00104 {
00105 return append(str.m_chr);
00106 }
00107
00108 BaseString&
00109 BaseString::append(const Vector<BaseString> &vector,
00110 const BaseString &separator) {
00111 for(size_t i=0;i<vector.size(); i++) {
00112 append(vector[i]);
00113 if(i<vector.size()-1)
00114 append(separator);
00115 }
00116 return *this;
00117 }
00118
00119 BaseString&
00120 BaseString::assfmt(const char *fmt, ...)
00121 {
00122 char buf[1];
00123 va_list ap;
00124 int l;
00125
00126
00127
00128
00129
00130 va_start(ap, fmt);
00131 l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1;
00132 va_end(ap);
00133 if(l > (int)m_len) {
00134 delete[] m_chr;
00135 m_chr = new char[l];
00136 }
00137 va_start(ap, fmt);
00138 basestring_vsnprintf(m_chr, l, fmt, ap);
00139 va_end(ap);
00140 m_len = strlen(m_chr);
00141 return *this;
00142 }
00143
00144 BaseString&
00145 BaseString::appfmt(const char *fmt, ...)
00146 {
00147 char buf[1];
00148 va_list ap;
00149 int l;
00150
00151
00152
00153
00154
00155 va_start(ap, fmt);
00156 l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1;
00157 va_end(ap);
00158 char *tmp = new char[l];
00159 va_start(ap, fmt);
00160 basestring_vsnprintf(tmp, l, fmt, ap);
00161 va_end(ap);
00162 append(tmp);
00163 delete[] tmp;
00164 return *this;
00165 }
00166
00167 BaseString&
00168 BaseString::operator=(const BaseString& str)
00169 {
00170 if (this != &str) {
00171 this->assign(str);
00172 }
00173 return *this;
00174 }
00175
00176 int
00177 BaseString::split(Vector<BaseString> &v,
00178 const BaseString &separator,
00179 int maxSize) const {
00180 char *str = strdup(m_chr);
00181 int i, start, len, num = 0;
00182 len = strlen(str);
00183 for(start = i = 0;
00184 (i <= len) && ( (maxSize<0) || ((int)v.size()<=maxSize-1) );
00185 i++) {
00186 if(strchr(separator.c_str(), str[i]) || i == len) {
00187 if(maxSize < 0 || (int)v.size() < maxSize-1)
00188 str[i] = '\0';
00189 v.push_back(BaseString(str+start));
00190 num++;
00191 start = i+1;
00192 }
00193 }
00194 free(str);
00195
00196 return num;
00197 }
00198
00199 ssize_t
00200 BaseString::indexOf(char c) {
00201 char *p;
00202 p = strchr(m_chr, c);
00203 if(p == NULL)
00204 return -1;
00205 return (ssize_t)(p-m_chr);
00206 }
00207
00208 ssize_t
00209 BaseString::lastIndexOf(char c) {
00210 char *p;
00211 p = strrchr(m_chr, c);
00212 if(p == NULL)
00213 return -1;
00214 return (ssize_t)(p-m_chr);
00215 }
00216
00217 BaseString
00218 BaseString::substr(ssize_t start, ssize_t stop) {
00219 if(stop < 0)
00220 stop = length();
00221 ssize_t len = stop-start;
00222 if(len <= 0)
00223 return BaseString("");
00224 BaseString s;
00225 s.assign(m_chr+start, len);
00226 return s;
00227 }
00228
00229 static bool
00230 iswhite(char c) {
00231 switch(c) {
00232 case ' ':
00233 case '\t':
00234 return true;
00235 default:
00236 return false;
00237 }
00238
00239 }
00240
00241 char **
00242 BaseString::argify(const char *argv0, const char *src) {
00243 Vector<char *> vargv;
00244
00245 if(argv0 != NULL)
00246 vargv.push_back(strdup(argv0));
00247
00248 char *tmp = new char[strlen(src)+1];
00249 char *dst = tmp;
00250 const char *end = src + strlen(src);
00251
00252
00253
00254
00255
00256
00257
00258 while(src < end && *src) {
00259
00260 while(src < end && *src && iswhite(*src))
00261 src++;
00262
00263 char *begin = dst;
00264 while(src < end && *src) {
00265
00266 if(*src == '"') {
00267 src++;
00268 while(src < end && *src && *src != '"') {
00269 if(*src == '\\')
00270 src++;
00271 *dst++ = *src++;
00272 }
00273 src++;
00274 if(src >= end)
00275 goto end;
00276 }
00277
00278
00279 if(*src == '\\')
00280 src++;
00281 else if(iswhite(*src))
00282 break;
00283
00284
00285 *dst++ = *src++;
00286 }
00287
00288
00289 *dst++ = '\0';
00290 src++;
00291
00292 vargv.push_back(strdup(begin));
00293 }
00294 end:
00295
00296 delete[] tmp;
00297 vargv.push_back(NULL);
00298
00299
00300
00301
00302 char **argv = (char **)malloc(sizeof(*argv) * (vargv.size()));
00303 if(argv == NULL)
00304 return NULL;
00305
00306 for(size_t i = 0; i < vargv.size(); i++){
00307 argv[i] = vargv[i];
00308 }
00309
00310 return argv;
00311 }
00312
00313 BaseString&
00314 BaseString::trim(const char * delim){
00315 trim(m_chr, delim);
00316 m_len = strlen(m_chr);
00317 return * this;
00318 }
00319
00320 char*
00321 BaseString::trim(char * str, const char * delim){
00322 int len = strlen(str) - 1;
00323 for(; len > 0 && strchr(delim, str[len]); len--);
00324
00325 int pos = 0;
00326 for(; pos <= len && strchr(delim, str[pos]); pos++);
00327
00328 if(pos > len){
00329 str[0] = 0;
00330 return 0;
00331 } else {
00332 memmove(str, &str[pos], len - pos + 1);
00333 str[len-pos+1] = 0;
00334 }
00335
00336 return str;
00337 }
00338
00339 int
00340 BaseString::vsnprintf(char *str, size_t size, const char *format, va_list ap)
00341 {
00342 return(basestring_vsnprintf(str, size, format, ap));
00343 }
00344
00345 int
00346 BaseString::snprintf(char *str, size_t size, const char *format, ...)
00347 {
00348 va_list ap;
00349 va_start(ap, format);
00350 int ret= basestring_vsnprintf(str, size, format, ap);
00351 va_end(ap);
00352 return(ret);
00353 }
00354
00355
00356 #ifdef TEST_BASE_STRING
00357
00358
00359
00360
00361
00362
00363
00364 int main()
00365 {
00366 BaseString s("abc");
00367 BaseString t(s);
00368 s.assign("def");
00369 t.append("123");
00370 assert(s == "def");
00371 assert(t == "abc123");
00372 s.assign("");
00373 t.assign("");
00374 for (unsigned i = 0; i < 1000; i++) {
00375 s.append("xyz");
00376 t.assign(s);
00377 assert(strlen(t.c_str()) % 3 == 0);
00378 }
00379
00380 {
00381 BaseString s(":123:abc:;:foo:");
00382 Vector<BaseString> v;
00383 assert(s.split(v, ":;") == 7);
00384
00385 assert(v[0] == "");
00386 assert(v[1] == "123");
00387 assert(v[2] == "abc");
00388 assert(v[3] == "");
00389 assert(v[4] == "");
00390 assert(v[5] == "foo");
00391 assert(v[6] == "");
00392 }
00393
00394 {
00395 BaseString s(":123:abc:foo:bar");
00396 Vector<BaseString> v;
00397 assert(s.split(v, ":;", 4) == 4);
00398
00399 assert(v[0] == "");
00400 assert(v[1] == "123");
00401 assert(v[2] == "abc");
00402 assert(v[3] == "foo:bar");
00403
00404 BaseString n;
00405 n.append(v, "()");
00406 assert(n == "()123()abc()foo:bar");
00407 n = "";
00408 n.append(v);
00409 assert(n == " 123 abc foo:bar");
00410 }
00411
00412 {
00413 assert(BaseString("hamburger").substr(4,2) == "");
00414 assert(BaseString("hamburger").substr(3) == "burger");
00415 assert(BaseString("hamburger").substr(4,8) == "urge");
00416 assert(BaseString("smiles").substr(1,5) == "mile");
00417 assert(BaseString("012345").indexOf('2') == 2);
00418 assert(BaseString("hej").indexOf('X') == -1);
00419 }
00420
00421 {
00422 assert(BaseString(" 1").trim(" ") == "1");
00423 assert(BaseString("1 ").trim(" ") == "1");
00424 assert(BaseString(" 1 ").trim(" ") == "1");
00425 assert(BaseString("abc\t\n\r kalleabc\t\r\n").trim("abc\t\r\n ") == "kalle");
00426 assert(BaseString(" ").trim(" ") == "");
00427 }
00428 return 0;
00429 }
00430
00431 #endif
00432
00433 template class Vector<char *>;
00434 template class Vector<BaseString>;