00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <eyedbconfig.h>
00025
00026 #include <ctype.h>
00027 #ifdef HAVE_SYS_TYPES_H
00028 #include <sys/types.h>
00029 #endif
00030 #ifdef HAVE_REGEX_H
00031 #include <regex.h>
00032 #elif defined(HAVE_LIBGEN_H)
00033 #include <libgen.h>
00034 #else
00035 #error No regular expression implementation available on this platform
00036 #endif
00037
00038 #include <eyedb/syscls.h>
00039 #include <eyedblib/strutils.h>
00040
00041 using namespace std;
00042
00043
00044
00045
00046
00047 namespace eyedb {
00048
00049
00050
00051
00052
00053 OString *
00054 OString::ostring(Database * db)
00055 {
00056 return new OString(db);
00057 }
00058
00059 OString *
00060 OString::ostring(Database * db, const char * s)
00061 {
00062 OString * os = new OString(db);
00063
00064 os->assign(s);
00065
00066 return os;
00067 }
00068
00069 OString *
00070 OString::ostring(Database * db, const char * s, int len)
00071 {
00072 OString * os = new OString(db);
00073
00074 os->assign(s, len);
00075
00076 return os;
00077 }
00078
00079 OString *
00080 OString::ostring(Database * db, const char * s, int offset, int len)
00081 {
00082
00083 OString * os = new OString(db);
00084
00085 os->assign(s, offset, len);
00086
00087 return os;
00088
00089 }
00090
00091 OString *
00092 OString::ostring(Database * db, const OString & s)
00093 {
00094 OString * os = new OString(db);
00095
00096 os->setS(s.getS());
00097
00098 return os;
00099 }
00100
00101 OString *
00102 OString::ostring(Database * db, char s)
00103 {
00104 std::string is = str_convert(s);
00105
00106 OString * os = new OString(db);
00107 os->setS(is.c_str());
00108
00109 return os;
00110 }
00111
00112 OString *
00113 OString::ostring(Database * db, int s)
00114 {
00115 std::string is = str_convert(s);
00116
00117 OString * os = new OString(db);
00118 os->setS(is.c_str());
00119
00120 return os;
00121 }
00122
00123 OString *
00124 OString::ostring(Database * db, double s)
00125 {
00126 std::string is = str_convert(s);
00127
00128 OString * os = new OString(db);
00129 os->setS(is.c_str());
00130
00131 return os;
00132 }
00133
00134 char *
00135 OString::substr(const char * s, int offset, int len)
00136 {
00137 char * s_copy = 0;
00138
00139 int s_len = strlen(s);
00140 if( offset >= s_len
00141 || offset < 0
00142 || len < 0 )
00143 {
00144 return 0;
00145 }
00146
00147 if( offset + len > s_len )
00148 {
00149 len = s_len - offset;
00150 }
00151
00152 s_copy = new char[len + 1];
00153
00154 strncpy( s_copy, s + offset, len);
00155 s_copy[len] = '\0';
00156
00157 return s_copy;
00158 }
00159
00160 char *
00161 OString::toLower(const char * s)
00162 {
00163 char * s2 = new char[strlen(s) + 1];
00164 char * p = s2;
00165
00166 while (*s++)
00167 *p++ = (char)tolower( *s);
00168
00169 *p = '\0';
00170
00171 return s2;
00172 }
00173
00174 char *
00175 OString::toUpper(const char * s)
00176 {
00177 char * s2 = new char[strlen(s) + 1];
00178 char * p = s2;
00179
00180 while (*s++)
00181 *p++ = (char)toupper( *s);
00182
00183 *p = '\0';
00184
00185 return s2;
00186 }
00187
00188 char *
00189 OString::rtrim(const char * s)
00190 {
00191 const char * s_rtrimmed = s + strlen(s) - 1;
00192
00193 while (s_rtrimmed >= s
00194 && ((*s_rtrimmed=='\n') || (*s_rtrimmed=='\r') || (*s_rtrimmed=='\t') || (*s_rtrimmed=='\v')))
00195 s_rtrimmed--;
00196
00197 int return_value_size = s_rtrimmed - s + 1;
00198 char * return_value = new char[return_value_size + 1];
00199 strncpy(return_value, s, return_value_size);
00200 return_value[return_value_size] = '\0';
00201
00202 return return_value;
00203 }
00204
00205 char *
00206 OString::ltrim(const char * s)
00207 {
00208 const char * s_ltrimmed = s + strspn(s, "\n\r\t\v ");
00209
00210 char * return_value = new char[strlen(s_ltrimmed + 1)];
00211 strcpy(return_value, s_ltrimmed);
00212
00213 return return_value;
00214 }
00215
00216 Status
00217 OString::setChar(char c, int offset)
00218 {
00219 return setS(offset, c);
00220 }
00221
00222 char
00223 OString::getChar(int offset) const
00224 {
00225 return getS(offset);
00226 }
00227
00228 OString &
00229 OString::append(const char * s)
00230 {
00231 std::string is(getS());
00232
00233 is += s;
00234
00235 setS(is.c_str());
00236
00237 return *this;
00238 }
00239
00240 OString &
00241 OString::append(const char * s, int len)
00242 {
00243 return append(s, 0 , len);
00244 }
00245
00246 OString &
00247 OString::append(const char * s, int offset, int len)
00248 {
00249 char * sub = OString::substr(s, offset, len);
00250
00251 if( sub != 0 )
00252 {
00253 append(sub);
00254 delete sub;
00255 }
00256
00257 return *this;
00258 }
00259
00260 OString &
00261 OString::prepend(const char * s)
00262 {
00263 std::string is(s);
00264
00265 is += getS();
00266
00267 setS(is.c_str());
00268
00269 return *this;
00270 }
00271
00272 OString &
00273 OString::prepend(const char * s, int len)
00274 {
00275 return prepend(s, 0, len);
00276 }
00277
00278 OString &
00279 OString::prepend(const char * s, int offset, int len)
00280 {
00281 char * sub = OString::substr(s, offset, len);
00282
00283 if( sub != 0 )
00284 {
00285 prepend(sub);
00286 delete sub;
00287 }
00288
00289 return *this;
00290 }
00291
00292 OString &
00293 OString::insert(int offset, const char * s)
00294 {
00295 return insert(offset, s, 0, strlen(s));
00296 }
00297
00298 OString &
00299 OString::insert(int offset, const char * s, int len)
00300 {
00301 return insert(offset, s, 0, len);
00302 }
00303
00304 OString &
00305 OString::insert(int offset, const char * s, int offset2, int len)
00306 {
00307 const char * this_s = getS().c_str();
00308
00309
00310 if( offset < 0
00311 || offset2 < 0
00312 || len <= 0 )
00313 {
00314 return *this;
00315 }
00316
00317
00318 char * inserted_s = new char[strlen(this_s) + strlen(s) + 1];
00319 inserted_s[0] = '\0';
00320
00321 strncat(inserted_s, this_s, offset);
00322 strncat(inserted_s, s + offset2, len);
00323 strcat(inserted_s, this_s + offset);
00324
00325 setS(inserted_s);
00326
00327 delete inserted_s;
00328
00329 return *this;
00330 }
00331
00332 OString *
00333 OString::concat(Database * db, const char * s1, const char * s2)
00334 {
00335 OString * os = OString::ostring(db, s1);
00336
00337 os->append(s2);
00338
00339 return os;
00340 }
00341
00342 int
00343 OString::first(const char * s) const
00344 {
00345 return find(s, 0);
00346 }
00347
00348 int
00349 OString::last(const char * s) const
00350 {
00351
00352 cerr << "Not implemented" << endl;
00353 return 0;
00354 }
00355
00356 int
00357 OString::find(const char * s, int offset) const
00358 {
00359 const char * this_s = getS().c_str();
00360
00361 if (offset > strlen(this_s) || offset < 0 || !*s)
00362 {
00363 return -1;
00364 }
00365
00366 int find_offset = -1;
00367
00368 char * match = (char *)strstr(this_s + offset, s);
00369 if( match != 0)
00370 {
00371 find_offset = match - this_s;
00372 }
00373
00374 return find_offset;
00375 }
00376
00378 OString *
00379 OString::substr(int offset, int len) const
00380 {
00381 OString * os = OString::ostring(0, getS().c_str(), offset, len);
00382
00383 return os;
00384 }
00385
00387 OString *
00388 OString::substr(const char * regexp, int offset) const
00389 {
00390
00391 const char * regexp_subject = getS().c_str();
00392
00393 if( offset > strlen(regexp_subject)
00394 || offset < 0)
00395 {
00396 return OString::ostring(0);
00397 }
00398
00399
00400
00401 #ifdef HAVE_REGCOMP
00402 regex_t * compiled_regexp = (regex_t *)malloc(sizeof(regex_t));
00403
00404 int reg_status = regcomp(compiled_regexp, regexp, REG_EXTENDED);
00405 if ( reg_status != 0)
00406 {
00407 free(compiled_regexp);
00408 return OString::ostring(0);
00409 }
00410
00411 regmatch_t match[1];
00412 reg_status = regexec((regex_t *)compiled_regexp, regexp_subject + offset, 1, match, 0);
00413 if ( reg_status != 0)
00414 {
00415 free(compiled_regexp);
00416 return OString::ostring(0);
00417 }
00418
00419 const char * start_match = regexp_subject + offset + match[0].rm_so;
00420 const char * end_match = regexp_subject + offset + match[0].rm_eo;
00421 #elif defined(HAVE_REGCMP)
00422 char * compiled_regexp = regcmp(regexp, (char *)0);
00423
00424 if(compiled_regexp == 0)
00425 {
00426 return OString::ostring(0);
00427 }
00428
00429 const char * end_match = regex(compiled_regexp, regexp_subject + offset);
00430 const char * start_match = __loc1;
00431 #endif
00432
00433 free(compiled_regexp);
00434
00435
00436 OString * os = 0;
00437 if( end_match )
00438 {
00439 os = OString::ostring(0, start_match, 0, end_match - start_match);
00440 }
00441 else
00442 {
00443 os = OString::ostring(0);
00444 }
00445
00446 return os;
00447
00448 }
00449
00450 OString &
00451 OString::erase(int offset, int len)
00452 {
00453
00454 const char * this_s = getS().c_str();
00455
00456 int this_len = strlen(this_s);
00457 if( offset > this_len
00458 || offset < 0
00459 || len <= 0 )
00460 {
00461 return *this;
00462 }
00463
00464 if( offset + len > this_len )
00465 {
00466 len = this_len - offset;
00467 }
00468
00469
00470
00471 char * erased_string = new char[this_len + 1];
00472
00473 strncpy(erased_string, this_s, offset);
00474 strcpy(erased_string + offset, this_s + offset + len);
00475
00476 setS(erased_string);
00477
00478 delete erased_string;
00479
00480 return *this;
00481 }
00482
00483 OString &
00484 OString::replace(int offset, int len, const char * s)
00485 {
00486 return replace(offset, len, s, 0, strlen(s));
00487 }
00488
00489 OString &
00490 OString::replace(int offset, int len, const char * s, int len2)
00491 {
00492 return replace(offset, len, s, 0, len2);
00493 }
00494
00495 OString &
00496 OString::replace(int offset, int len, const char * s, int offset2, int len2)
00497 {
00498
00499 const char * this_s = getS().c_str();
00500
00501 int this_len = strlen(this_s);
00502 int s_len = strlen(s);
00503
00504 if( offset > this_len
00505 || offset < 0
00506 || len <= 0
00507 || offset2 > s_len
00508 || offset2 < 0
00509 || len2 <= 0 )
00510 {
00511 return *this;
00512 }
00513
00514 if( offset + len > this_len )
00515 {
00516 len = this_len - offset;
00517 }
00518
00519
00520
00521
00522 char * replaced_string = new char[this_len + s_len + 1];
00523 replaced_string[0] = '\0';
00524
00525 strncat(replaced_string, this_s, offset);
00526 strncat(replaced_string, s + offset2, len2);
00527 strcat(replaced_string, this_s + offset + len);
00528
00529 setS(replaced_string);
00530
00531 delete [] replaced_string;
00532
00533 return *this;
00534 }
00535
00536
00537 OString &
00538 OString::replace(const char * s1, const char * s2)
00539 {
00540 const char * this_s = getS().c_str();
00541 int s1_len = strlen(s1);
00542
00543
00544
00545 char * replaced_string = new char[strlen(this_s) * ( strlen(s2) + 1 ) + 1];
00546 replaced_string[0] = '\0';
00547
00548 int current_offset = 0;
00549 int previous_offset = 0;
00550 while( (current_offset = find(s1, previous_offset)) >= 0 )
00551 {
00552 strncat(replaced_string, this_s + previous_offset, current_offset - previous_offset);
00553 strcat(replaced_string, s2);
00554
00555 previous_offset = current_offset + s1_len;
00556 }
00557
00558
00559 if( previous_offset < strlen(this_s) )
00560 {
00561 strcat(replaced_string, this_s + previous_offset);
00562 }
00563
00564 setS(replaced_string);
00565
00566
00567 delete [] replaced_string;
00568
00569 return *this;
00570 }
00571
00572 OString &
00573 OString::assign(const char * s)
00574 {
00575 setS(s);
00576
00577 return *this;
00578 }
00579
00580 OString &
00581 OString::assign(const char * s, int len)
00582 {
00583 char * sub = OString::substr(s, 0, len);
00584
00585 if( sub != 0 )
00586 {
00587 setS(sub);
00588 delete sub;
00589 }
00590
00591 return *this;
00592 }
00593
00594 OString &
00595 OString::assign(const char * s, int offset, int len)
00596 {
00597 char * sub = OString::substr(s, offset, len);
00598
00599 if( sub != 0 )
00600 {
00601 setS(sub);
00602 delete sub;
00603 }
00604
00605 return *this;
00606 }
00607
00608 Status
00609 OString::reset()
00610 {
00611 return setS("");
00612 }
00613
00614 OString &
00615 OString::toLower()
00616 {
00617 char * s2 = toLower(getS().c_str());
00618 setS(s2);
00619 delete s2;
00620
00621 return *this;
00622 }
00623
00624 OString &
00625 OString::toUpper()
00626 {
00627 char * s2 = toUpper(getS().c_str());
00628 setS(s2);
00629 delete s2;
00630
00631 return *this;
00632 }
00633
00634 OString &
00635 OString::rtrim()
00636 {
00637 char * s2 = rtrim(getS().c_str());
00638 setS(s2);
00639 delete s2;
00640
00641 return *this;
00642 }
00643
00644 OString &
00645 OString::ltrim()
00646 {
00647 char * s2 = ltrim(getS().c_str());
00648 setS(s2);
00649 delete s2;
00650
00651 return *this;
00652 }
00653
00654 int
00655 OString::compare(const char * s) const
00656 {
00657 return strcmp(getS().c_str(), s);
00658 }
00659
00660 int
00661 OString::compare(const char * s, int to) const
00662 {
00663 return strncmp(getS().c_str(), s, to);
00664 }
00665
00666 int
00667 OString::compare(const char * s, int from, int to) const
00668 {
00669 const char * this_s = getS().c_str();
00670
00671 if(from >= strlen(s)
00672 || from >= strlen(this_s) )
00673 {
00674 return 0;
00675 }
00676
00677 return strncmp(this_s + from, s + from, to);
00678 }
00679
00680 Bool
00681 OString::is_null() const
00682 {
00683 return ( (length() == 0) ? True : False);
00684 }
00685
00686
00687 Bool
00688 OString::match(const char * regexp) const
00689 {
00690 const char * regexp_subject = getS().c_str();
00691
00692 #ifdef HAVE_REGCOMP
00693 regex_t * compiled_regexp = (regex_t *)malloc(sizeof(regex_t));
00694
00695 int reg_status = regcomp(compiled_regexp, regexp, REG_EXTENDED);
00696 if ( reg_status != 0)
00697 {
00698 free(compiled_regexp);
00699 return False;
00700 }
00701
00702 regmatch_t match[1];
00703 reg_status = regexec((regex_t *)compiled_regexp, regexp_subject, 1, match, 0);
00704 if ( reg_status != 0)
00705 {
00706 free(compiled_regexp);
00707 return False;
00708 }
00709
00710 const char * start_match = regexp_subject + match[0].rm_so;
00711 const char * end_match = regexp_subject + match[0].rm_eo;
00712 #elif defined(HAVE_REGCMP)
00713 char * compiled_regexp = regcmp(regexp, (char *)0);
00714
00715 if(compiled_regexp == 0)
00716 {
00717 return False;
00718 }
00719
00720 char * end_match = regex(compiled_regexp, regexp_subject);
00721 char * start_match = __loc1;
00722 #endif
00723
00724 free(compiled_regexp);
00725
00726 if( (regexp_subject + strlen(regexp_subject)) == end_match
00727 && regexp_subject == start_match)
00728 {
00729 return True;
00730 }
00731 else
00732 {
00733 return False;
00734 }
00735 }
00736
00737 int
00738 OString::length() const
00739 {
00740 return strlen(getS().c_str());
00741 }
00742
00743 char **
00744 OString::split(const char * separator, int & nb_pieces) const
00745 {
00746
00747 char * s_copy = strdup(getS().c_str());
00748
00749
00750 nb_pieces = 1;
00751
00752 int separator_len = strlen(separator);
00753
00754 int previous_offset = 0;
00755 int current_offset = 0;
00756 while( (current_offset = find(separator, previous_offset)) >= 0 )
00757 {
00758 s_copy[current_offset] = '\0';
00759
00760 ++nb_pieces;
00761 previous_offset = current_offset + separator_len;
00762 }
00763
00764
00765 typedef char * token;
00766 token * return_value = new token[nb_pieces];
00767
00768 char * cursor = s_copy;
00769 for(int i=0; i < nb_pieces; ++i)
00770 {
00771 int token_len = strlen(cursor);
00772
00773 char * current_token = new char[token_len + 1];
00774 strcpy(current_token, cursor);
00775 return_value[i] = current_token;
00776
00777
00778 cursor += token_len + separator_len;
00779 }
00780
00781
00782 free(s_copy);
00783
00784 return return_value;
00785 }
00786
00787 char **
00788 OString::regexp_split(const char * regexp_separator, int & nb_pieces) const
00789 {
00790
00791 char * s_copy = strdup(getS().c_str());
00792
00793
00794 #ifdef HAVE_REGCOMP
00795 regex_t * compiled_separator = (regex_t *)malloc(sizeof(regex_t));
00796
00797 int reg_status = regcomp(compiled_separator, regexp_separator, REG_EXTENDED);
00798 if ( reg_status != 0)
00799 {
00800 free(compiled_separator);
00801 return 0;
00802 }
00803 #elif defined(HAVE_REGCMP)
00804 char * compiled_separator = regcmp(regexp_separator, (char*)0);
00805 if( compiled_separator == 0 )
00806 {
00807 return 0;
00808 }
00809 #endif
00810
00811
00812
00813 nb_pieces = 0;
00814
00815 typedef char * token;
00816 token * return_value = new token[strlen(s_copy)];
00817
00818 char * cursor1 = s_copy;
00819 char * cursor2 = s_copy;
00820
00821 #ifdef HAVE_REGEXEC
00822 regmatch_t match[1];
00823 while( regexec( compiled_separator, cursor1, 1, match, 0) == 0)
00824 #elif defined(HAVE_REGEX)
00825 while( (cursor2 = regex(compiled_separator, cursor1)) != 0 )
00826 #endif
00827
00828
00829 {
00830 #ifdef HAVE_REGEXEC
00831 char * separator = cursor1 + match[0].rm_so;
00832 char * cursor2 = cursor1 + match[0].rm_eo;
00833 #elif defined(HAVE_REGEX)
00834 char * separator = __loc1;
00835 #endif
00836
00837 int separator_len = cursor2 - separator;
00838
00839 int token_len = separator - cursor1;
00840 char * current_token = new char[ token_len + 1];
00841 current_token[0] = '\0';
00842 strncat(current_token, cursor1, token_len);
00843 return_value[nb_pieces] = current_token;
00844
00845
00846 ++nb_pieces;
00847 cursor1 = cursor2;
00848 }
00849
00850
00851 char * current_token = new char[ strlen(cursor1) + 1];
00852 strcpy(current_token, cursor1);
00853 return_value[nb_pieces] = current_token;
00854 ++nb_pieces;
00855
00856
00857
00858 free(s_copy);
00859 free(compiled_separator);
00860
00861 return return_value;
00862
00863 }
00864 }
00865