29 String::String(
const char *cstr)
32 if (cstr) copy(cstr, strlen(cstr));
35 String::String(
const String &value)
41 #ifdef __GXX_EXPERIMENTAL_CXX0X__
42 String::String(
String &&rval)
47 String::String(StringSumHelper &&rval)
54 String::String(
char c)
63 String::String(
unsigned char value,
unsigned char base)
67 utoa(value, buf, base);
71 String::String(
int value,
unsigned char base)
75 itoa(value, buf, base);
79 String::String(
unsigned int value,
unsigned char base)
83 utoa(value, buf, base);
87 String::String(
long value,
unsigned char base)
91 ltoa(value, buf, base);
95 String::String(
unsigned long value,
unsigned char base)
99 ultoa(value, buf, base);
112 inline void String::init(
void)
120 void String::invalidate(
void)
122 if (buffer) free(buffer);
127 unsigned char String::reserve(
unsigned int size)
129 if (buffer && capacity >= size)
return 1;
130 if (changeBuffer(size)) {
131 if (len == 0) buffer[0] = 0;
137 unsigned char String::changeBuffer(
unsigned int maxStrLen)
139 char *newbuffer = (
char *)realloc(buffer, maxStrLen + 1);
142 capacity = maxStrLen;
152 String & String::copy(
const char *cstr,
unsigned int length)
154 if (!reserve(length)) {
159 strcpy(buffer, cstr);
163 #ifdef __GXX_EXPERIMENTAL_CXX0X__
164 void String::move(
String &rhs)
167 if (capacity >= rhs.len) {
168 strcpy(buffer, rhs.buffer);
177 capacity = rhs.capacity;
187 if (
this == &rhs)
return *
this;
189 if (rhs.buffer) copy(rhs.buffer, rhs.len);
195 #ifdef __GXX_EXPERIMENTAL_CXX0X__
198 if (
this != &rval) move(rval);
202 String & String::operator = (StringSumHelper &&rval)
204 if (
this != &rval) move(rval);
209 String & String::operator = (
const char *cstr)
211 if (cstr) copy(cstr, strlen(cstr));
221 unsigned char String::concat(
const String &s)
223 return concat(s.buffer, s.len);
226 unsigned char String::concat(
const char *cstr,
unsigned int length)
228 unsigned int newlen = len + length;
230 if (length == 0)
return 1;
231 if (!reserve(newlen))
return 0;
232 strcpy(buffer + len, cstr);
237 unsigned char String::concat(
const char *cstr)
240 return concat(cstr, strlen(cstr));
243 unsigned char String::concat(
char c)
248 return concat(buf, 1);
251 unsigned char String::concat(
unsigned char num)
255 return concat(buf, strlen(buf));
258 unsigned char String::concat(
int num)
262 return concat(buf, strlen(buf));
265 unsigned char String::concat(
unsigned int num)
269 return concat(buf, strlen(buf));
272 unsigned char String::concat(
long num)
276 return concat(buf, strlen(buf));
279 unsigned char String::concat(
unsigned long num)
283 return concat(buf, strlen(buf));
290 StringSumHelper & operator + (
const StringSumHelper &lhs,
const String &rhs)
292 StringSumHelper &a =
const_cast<StringSumHelper&
>(lhs);
293 if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
297 StringSumHelper & operator + (
const StringSumHelper &lhs,
const char *cstr)
299 StringSumHelper &a =
const_cast<StringSumHelper&
>(lhs);
300 if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
304 StringSumHelper & operator + (
const StringSumHelper &lhs,
char c)
306 StringSumHelper &a =
const_cast<StringSumHelper&
>(lhs);
307 if (!a.concat(c)) a.invalidate();
311 StringSumHelper & operator + (
const StringSumHelper &lhs,
unsigned char num)
313 StringSumHelper &a =
const_cast<StringSumHelper&
>(lhs);
314 if (!a.concat(num)) a.invalidate();
318 StringSumHelper & operator + (
const StringSumHelper &lhs,
int num)
320 StringSumHelper &a =
const_cast<StringSumHelper&
>(lhs);
321 if (!a.concat(num)) a.invalidate();
325 StringSumHelper & operator + (
const StringSumHelper &lhs,
unsigned int num)
327 StringSumHelper &a =
const_cast<StringSumHelper&
>(lhs);
328 if (!a.concat(num)) a.invalidate();
332 StringSumHelper & operator + (
const StringSumHelper &lhs,
long num)
334 StringSumHelper &a =
const_cast<StringSumHelper&
>(lhs);
335 if (!a.concat(num)) a.invalidate();
339 StringSumHelper & operator + (
const StringSumHelper &lhs,
unsigned long num)
341 StringSumHelper &a =
const_cast<StringSumHelper&
>(lhs);
342 if (!a.concat(num)) a.invalidate();
350 int String::compareTo(
const String &s)
const
352 if (!buffer || !s.buffer) {
353 if (s.buffer && s.len > 0)
return 0 - *(
unsigned char *)s.buffer;
354 if (buffer && len > 0)
return *(
unsigned char *)buffer;
357 return strcmp(buffer, s.buffer);
360 unsigned char String::equals(
const String &s2)
const
362 return (len == s2.len && compareTo(s2) == 0);
365 unsigned char String::equals(
const char *cstr)
const
367 if (len == 0)
return (cstr == NULL || *cstr == 0);
368 if (cstr == NULL)
return buffer[0] == 0;
369 return strcmp(buffer, cstr) == 0;
372 unsigned char String::operator<(
const String &rhs)
const
374 return compareTo(rhs) < 0;
377 unsigned char String::operator>(
const String &rhs)
const
379 return compareTo(rhs) > 0;
382 unsigned char String::operator<=(
const String &rhs)
const
384 return compareTo(rhs) <= 0;
387 unsigned char String::operator>=(
const String &rhs)
const
389 return compareTo(rhs) >= 0;
392 unsigned char String::equalsIgnoreCase(
const String &s2 )
const
394 if (
this == &s2)
return 1;
395 if (len != s2.len)
return 0;
396 if (len == 0)
return 1;
397 const char *p1 = buffer;
398 const char *p2 = s2.buffer;
405 unsigned char String::startsWith(
const String &s2 )
const
407 if (len < s2.len)
return 0;
408 return startsWith(s2, 0);
411 unsigned char String::startsWith(
const String &s2,
unsigned int offset )
const
413 if (offset > len - s2.len || !buffer || !s2.buffer)
return 0;
414 return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
417 unsigned char String::endsWith(
const String &s2 )
const
419 if ( len < s2.len || !buffer || !s2.buffer)
return 0;
420 return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
427 char String::charAt(
unsigned int loc)
const
429 return operator[](loc);
432 void String::setCharAt(
unsigned int loc,
char c)
434 if (loc < len) buffer[loc] = c;
437 char & String::operator[](
unsigned int index)
439 static char dummy_writable_char;
440 if (index >= len || !buffer) {
441 dummy_writable_char = 0;
442 return dummy_writable_char;
444 return buffer[index];
447 char String::operator[](
unsigned int index )
const
449 if (index >= len || !buffer)
return 0;
450 return buffer[index];
453 void String::getBytes(
unsigned char *buf,
unsigned int bufsize,
unsigned int index)
const
455 if (!bufsize || !buf)
return;
460 unsigned int n = bufsize - 1;
461 if (n > len - index) n = len - index;
462 strncpy((
char *)buf, buffer + index, n);
470 int String::indexOf(
char c)
const
472 return indexOf(c, 0);
475 int String::indexOf(
char ch,
unsigned int fromIndex )
const
477 if (fromIndex >= len)
return -1;
478 const char* temp = strchr(buffer + fromIndex, ch);
479 if (temp == NULL)
return -1;
480 return temp - buffer;
483 int String::indexOf(
const String &s2)
const
485 return indexOf(s2, 0);
488 int String::indexOf(
const String &s2,
unsigned int fromIndex)
const
490 if (fromIndex >= len)
return -1;
491 const char *found = strstr(buffer + fromIndex, s2.buffer);
492 if (found == NULL)
return -1;
493 return found - buffer;
496 int String::lastIndexOf(
char theChar )
const
498 return lastIndexOf(theChar, len - 1);
501 int String::lastIndexOf(
char ch,
unsigned int fromIndex)
const
503 if (fromIndex >= len)
return -1;
504 char tempchar = buffer[fromIndex + 1];
505 buffer[fromIndex + 1] =
'\0';
506 char* temp = strrchr( buffer, ch );
507 buffer[fromIndex + 1] = tempchar;
508 if (temp == NULL)
return -1;
509 return temp - buffer;
512 int String::lastIndexOf(
const String &s2)
const
514 return lastIndexOf(s2, len - s2.len);
517 int String::lastIndexOf(
const String &s2,
unsigned int fromIndex)
const
519 if (s2.len == 0 || len == 0 || s2.len > len)
return -1;
520 if (fromIndex >= len) fromIndex = len - 1;
522 for (
char *p = buffer; p <= buffer + fromIndex; p++) {
523 p = strstr(p, s2.buffer);
525 if ((
unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
530 String String::substring(
unsigned int left )
const
532 return substring(left, len);
535 String String::substring(
unsigned int left,
unsigned int right)
const
538 unsigned int temp = right;
543 if (left > len)
return out;
544 if (right > len) right = len;
545 char temp = buffer[right];
546 buffer[right] =
'\0';
548 buffer[right] = temp;
556 void String::replace(
char find,
char replace)
559 for (
char *p = buffer; *p; p++) {
560 if (*p == find) *p = replace;
564 void String::replace(
const String& find,
const String& replace)
566 if (len == 0 || find.len == 0)
return;
567 int diff = replace.len - find.len;
568 char *readFrom = buffer;
571 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
572 memcpy(foundAt, replace.buffer, replace.len);
573 readFrom = foundAt + replace.len;
575 }
else if (diff < 0) {
576 char *writeTo = buffer;
577 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
578 unsigned int n = foundAt - readFrom;
579 memcpy(writeTo, readFrom, n);
581 memcpy(writeTo, replace.buffer, replace.len);
582 writeTo += replace.len;
583 readFrom = foundAt + find.len;
586 strcpy(writeTo, readFrom);
588 unsigned int size = len;
589 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
590 readFrom = foundAt + find.len;
593 if (size == len)
return;
594 if (size > capacity && !changeBuffer(size))
return;
596 while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
597 readFrom = buffer + index + find.len;
598 memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
601 memcpy(buffer + index, replace.buffer, replace.len);
607 void String::toLowerCase(
void)
610 for (
char *p = buffer; *p; p++) {
615 void String::toUpperCase(
void)
618 for (
char *p = buffer; *p; p++) {
623 void String::trim(
void)
625 if (!buffer || len == 0)
return;
626 char *begin = buffer;
627 while (
isspace(*begin)) begin++;
628 char *end = buffer + len - 1;
629 while (
isspace(*end) && end >= begin) end--;
630 len = end + 1 - begin;
631 if (begin > buffer) memcpy(buffer, begin, len);
639 long String::toInt(
void)
const
641 if (buffer)
return atol(buffer);