73 |
|
my_data = data; |
74 |
|
} |
75 |
|
|
76 |
< |
void GStr::make_unique() {//make sure is not a reference to other string |
76 |
> |
void GStr::make_unique() {//make sure it's not a reference to other string |
77 |
|
if (my_data->ref_count > 1) { |
78 |
|
Data *data = new_data(length()); |
79 |
|
::memcpy(data->chars, chars(), length()); |
331 |
|
} |
332 |
|
|
333 |
|
bool GStr::startsWith(const char *s) const { |
334 |
< |
return (index(s, 0) == 0); |
334 |
> |
//return (index(s, 0) == 0); |
335 |
> |
return ::startsWith(this->chars(), s); |
336 |
> |
} |
337 |
> |
|
338 |
> |
bool GStr::startsWith(const GStr& s) const { |
339 |
> |
//return (index(s, 0) == 0); |
340 |
> |
return ::startsWith(this->chars(), s.chars()); |
341 |
> |
} |
342 |
> |
|
343 |
> |
bool GStr::endsWith(const char *s) const { |
344 |
> |
//return (index(s, 0) == 0); |
345 |
> |
return ::endsWith(this->chars(), s); |
346 |
> |
} |
347 |
> |
|
348 |
> |
bool GStr::endsWith(const GStr& s) const { |
349 |
> |
//return (index(s, 0) == 0); |
350 |
> |
return ::endsWith(this->chars(), s.chars()); |
351 |
|
} |
352 |
|
|
353 |
|
bool GStr::contains(char c) const { |
388 |
|
GStr& GStr::trim(char c) { |
389 |
|
register int istart; |
390 |
|
register int iend; |
391 |
< |
for (istart=0; istart<length() && chars()[istart]==c;istart++); |
391 |
> |
for (istart=0; istart<length() && chars()[istart]==c;istart++) ; |
392 |
|
if (istart==length()) { |
393 |
|
make_unique(); //edit operation ahead |
394 |
|
replace_data(0); //string was entirely trimmed |
395 |
|
return *this; |
396 |
|
} |
397 |
< |
for (iend=length()-1; iend>istart && chars()[iend]==c;iend--); |
397 |
> |
for (iend=length()-1; iend>istart && chars()[iend]==c;iend--) ; |
398 |
|
int newlen=iend-istart+1; |
399 |
|
if (newlen==length()) //nothing to trim |
400 |
|
return *this; |
408 |
|
GStr& GStr::trim(const char* c) { |
409 |
|
register int istart; |
410 |
|
register int iend; |
411 |
< |
for (istart=0; istart<length() && strchr(c, chars()[istart])!=NULL ;istart++); |
411 |
> |
for (istart=0; istart<length() && strchr(c, chars()[istart])!=NULL ;istart++) ; |
412 |
|
if (istart==length()) { |
413 |
|
replace_data(0); //string was entirely trimmed |
414 |
|
return *this; |
415 |
|
} |
416 |
< |
for (iend=length()-1; iend>istart && strchr(c, chars()[iend])!=NULL;iend--); |
416 |
> |
for (iend=length()-1; iend>istart && strchr(c, chars()[iend])!=NULL;iend--) ; |
417 |
|
int newlen=iend-istart+1; |
418 |
|
if (newlen==length()) //nothing to trim |
419 |
|
return *this; |
428 |
|
//only trim the right end |
429 |
|
//register int istart; |
430 |
|
register int iend; |
431 |
< |
for (iend=length()-1; iend>=0 && chars()[iend]==c;iend--); |
431 |
> |
for (iend=length()-1; iend>=0 && chars()[iend]==c;iend--) ; |
432 |
|
if (iend==-1) { |
433 |
|
replace_data(0); //string was entirely trimmed |
434 |
|
return *this; |
446 |
|
|
447 |
|
GStr& GStr::trimR(const char* c) { |
448 |
|
register int iend; |
449 |
< |
for (iend=length()-1; iend>=0 && strchr(c,chars()[iend])!=NULL;iend--); |
449 |
> |
for (iend=length()-1; iend>=0 && strchr(c,chars()[iend])!=NULL;iend--) ; |
450 |
|
if (iend==-1) { |
451 |
|
replace_data(0); //string was entirely trimmed |
452 |
|
return *this; |
487 |
|
|
488 |
|
GStr& GStr::trimL(char c) { |
489 |
|
register int istart; |
490 |
< |
for (istart=0; istart<length() && chars()[istart]==c;istart++); |
490 |
> |
for (istart=0; istart<length() && chars()[istart]==c;istart++) ; |
491 |
|
if (istart==length()) { |
492 |
|
replace_data(0); //string was entirely trimmed |
493 |
|
return *this; |
504 |
|
|
505 |
|
GStr& GStr::trimL(const char* c) { |
506 |
|
register int istart; |
507 |
< |
for (istart=0; istart<length() && strchr(c,chars()[istart])!=NULL;istart++); |
507 |
> |
for (istart=0; istart<length() && strchr(c,chars()[istart])!=NULL;istart++) ; |
508 |
|
if (istart==length()) { |
509 |
|
replace_data(0); //string was entirely trimmed |
510 |
|
return *this; |
659 |
|
idx += length(); |
660 |
|
|
661 |
|
// A length of -1 specifies the rest of the string. |
662 |
< |
if (len == -1 || len>length()-idx) |
662 |
> |
if (len < 0 || len>length()-idx) |
663 |
|
len = length() - idx; |
664 |
|
|
665 |
|
if (idx<0 || idx>=length() || len<0 ) |
991 |
|
return idx - chars(); |
992 |
|
} |
993 |
|
|
994 |
< |
int GStr::rindex(char c) const { |
995 |
< |
if (c == '\0' || length()==0) |
996 |
< |
return -1; |
997 |
< |
char* idx= rstrchr((char*)chars(), c); |
998 |
< |
if (idx==NULL) return -1; |
999 |
< |
else return idx-chars(); |
994 |
> |
int GStr::rindex(char c, int end_index) const { |
995 |
> |
if (c == 0 || length()==0 || end_index>=length()) return -1; |
996 |
> |
if (end_index<0) end_index=my_data->length-1; |
997 |
> |
for (int i=end_index;i>=0;i--) { |
998 |
> |
if (my_data->chars[i]==c) return i; |
999 |
> |
} |
1000 |
> |
return -1; |
1001 |
|
} |
1002 |
|
|
1003 |
< |
int GStr::rindex(const char* str) const { |
1004 |
< |
if (str==NULL || *str == '\0' || length()==0) |
1003 |
> |
int GStr::rindex(const char* str, int end_index) const { |
1004 |
> |
if (str==NULL || *str == '\0' || length()==0 || end_index>=length()) |
1005 |
|
return -1; |
1006 |
< |
char* idx= rstrfind((char*)chars(), str); |
1007 |
< |
if (idx==NULL) return -1; |
1008 |
< |
else return idx-chars(); |
1006 |
> |
int slen=strlen(str); |
1007 |
> |
if (end_index<0) end_index=my_data->length-1; |
1008 |
> |
//end_index is the index of the right-side boundary |
1009 |
> |
//the scanning starts at the end |
1010 |
> |
if (end_index>=0 && end_index<slen-1) return -1; |
1011 |
> |
for (int i=end_index-slen+1;i>=0;i--) { |
1012 |
> |
if (memcmp((void*)(my_data->chars+i),(void*)str, slen)==0) |
1013 |
> |
return i; |
1014 |
> |
} |
1015 |
> |
return -1; |
1016 |
|
} |
1017 |
|
|
1018 |
|
GStr GStr::split(const char* delim) { |