WvStreams
|
00001 /* -*- Mode: C++ -*- 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * Various little string functions... 00006 * 00007 * FIXME: and some other assorted crap that belongs anywhere but here. 00008 */ 00009 #ifndef __WVSTRUTILS_H 00010 #define __WVSTRUTILS_H 00011 00012 #include <sys/types.h> // for off_t 00013 #include <time.h> 00014 #include <ctype.h> 00015 #include "wvstring.h" 00016 #include "wvstringlist.h" 00017 #include "wvhex.h" 00018 #ifndef _WIN32 00019 #include "wvregex.h" 00020 #endif 00021 00034 char *terminate_string(char *string, char c); 00035 00044 char *trim_string(char *string); 00045 00050 char *trim_string(char *string, char c); 00051 00065 WvString spacecat(WvStringParm a, WvStringParm b, char sep = ' ', 00066 bool onesep = false); 00067 00068 00073 char *non_breaking(const char *string); 00074 00079 void replace_char(void *string, char c1, char c2, int length); 00080 00084 char *snip_string(char *haystack, char *needle); 00085 00086 #ifndef _WIN32 00087 00091 char *strlwr(char *string); 00092 00097 char *strupr(char *string); 00098 00099 #endif 00100 00102 bool is_word(const char *string); 00103 00112 WvString hexdump_buffer(const void *buf, size_t len, bool charRep = true); 00113 00118 bool isnewline(char c); 00119 00127 WvString url_decode(WvStringParm str, bool no_space = false); 00128 00129 00138 WvString url_encode(WvStringParm str, WvStringParm unsafe = ""); 00139 00140 00144 WvString diff_dates(time_t t1, time_t t2); 00145 00146 00151 WvString rfc822_date(time_t _when = -1); 00152 00154 WvString rfc1123_date(time_t _when); 00155 00157 WvString local_date(time_t _when = -1); 00158 00160 WvString intl_time(time_t _when = -1); 00161 00163 WvString intl_date(time_t _when = -1); 00164 00166 WvString intl_datetime(time_t _when = -1); 00167 00168 time_t intl_gmtoff(time_t t); 00169 00170 #ifndef _WIN32 00171 00176 WvString passwd_crypt(const char *str); 00177 00178 #endif 00179 00184 WvString passwd_md5(const char *str); 00185 00190 WvString backslash_escape(WvStringParm s1); 00191 00193 int strcount(WvStringParm s, const char c); 00194 00199 WvString encode_hostname_as_DN(WvStringParm hostname); 00200 00207 WvString nice_hostname(WvStringParm name); 00208 00214 WvString getfilename(WvStringParm fullname); 00215 WvString getdirname(WvStringParm fullname); 00216 00217 /* 00218 * Possible rounding methods for numbers -- remember from school? 00219 */ 00220 enum RoundingMethod 00221 { 00222 ROUND_DOWN, 00223 ROUND_DOWN_AT_POINT_FIVE, 00224 ROUND_UP_AT_POINT_FIVE, 00225 ROUND_UP 00226 }; 00227 00233 WvString sizetoa(unsigned long long blocks, unsigned long blocksize = 1, 00234 RoundingMethod rounding_method = ROUND_UP_AT_POINT_FIVE); 00235 00240 WvString sizektoa(unsigned long long kbytes, 00241 RoundingMethod rounding_method = ROUND_UP_AT_POINT_FIVE); 00242 00248 WvString sizeitoa(unsigned long long blocks, unsigned long blocksize = 1, 00249 RoundingMethod rounding_method = ROUND_UP_AT_POINT_FIVE); 00250 00255 WvString sizekitoa(unsigned long long kbytes, 00256 RoundingMethod rounding_method = ROUND_UP_AT_POINT_FIVE); 00257 00261 WvString secondstoa(unsigned int total_seconds); 00262 00267 int lookup(const char *str, const char * const *table, 00268 bool case_sensitive = false); 00269 00277 template<class StringCollection> 00278 void strcoll_split(StringCollection &coll, WvStringParm _s, 00279 const char *splitchars = " \t", int limit = 0) 00280 { 00281 WvString s(_s); 00282 char *sptr = s.edit(), *eptr, oldc; 00283 00284 // Simple if statement to catch (and add) empty (but not NULL) strings. 00285 if (sptr && !*sptr ) 00286 { 00287 WvString *emptyString = new WvString(""); 00288 coll.add(emptyString, true); 00289 } 00290 00291 // Needed to catch delimeters at the beginning of the string. 00292 bool firstrun = true; 00293 00294 while (sptr && *sptr) 00295 { 00296 --limit; 00297 00298 if (firstrun) 00299 { 00300 firstrun = false; 00301 } 00302 else 00303 { 00304 sptr += strspn(sptr, splitchars); 00305 } 00306 00307 if (limit) 00308 { 00309 eptr = sptr + strcspn(sptr, splitchars); 00310 } 00311 else 00312 { 00313 eptr = sptr + strlen(sptr); 00314 } 00315 00316 oldc = *eptr; 00317 *eptr = 0; 00318 00319 WvString *newstr = new WvString(sptr); 00320 coll.add(newstr, true); 00321 00322 *eptr = oldc; 00323 sptr = eptr; 00324 } 00325 } 00326 00327 00341 template<class StringCollection> 00342 void strcoll_splitstrict(StringCollection &coll, WvStringParm _s, 00343 const char *splitchars = " \t", int limit = 0) 00344 { 00345 WvString s(_s); 00346 char *cur = s.edit(); 00347 00348 if (!cur) return; 00349 00350 for (;;) 00351 { 00352 --limit; 00353 if (!limit) 00354 { 00355 coll.add(new WvString(cur), true); 00356 break; 00357 } 00358 00359 int len = strcspn(cur, splitchars); 00360 00361 char tmp = cur[len]; 00362 cur[len] = 0; 00363 coll.add(new WvString(cur), true); 00364 cur[len] = tmp; 00365 00366 if (!cur[len]) break; 00367 cur += len + 1; 00368 } 00369 } 00370 00371 00372 #ifndef _WIN32 // don't have regex on win32 00373 00380 template<class StringCollection> 00381 void strcoll_split(StringCollection &coll, WvStringParm s, 00382 const WvRegex ®ex, int limit = 0) 00383 { 00384 int start = 0; 00385 int match_start, match_end; 00386 int count = 0; 00387 00388 while ((limit == 0 || count < limit) 00389 && regex.continuable_match(&s[start], match_start, match_end) 00390 && match_end > 0) 00391 { 00392 WvString *substr = new WvString; 00393 int len = match_start; 00394 substr->setsize(len+1); 00395 memcpy(substr->edit(), &s[start], len); 00396 substr->edit()[len] = '\0'; 00397 coll.add(substr, true); 00398 start += match_end; 00399 ++count; 00400 } 00401 00402 if (limit == 0 || count < limit) 00403 { 00404 WvString *last = new WvString(&s[start]); 00405 last->unique(); 00406 coll.add(last, true); 00407 } 00408 } 00409 #endif 00410 00411 00417 template<class StringCollection> 00418 WvString strcoll_join(const StringCollection &coll, 00419 const char *joinchars = " \t") 00420 { 00421 size_t joinlen = strlen(joinchars); 00422 size_t totlen = 1; 00423 typename StringCollection::Iter s( 00424 const_cast<StringCollection&>(coll)); 00425 for (s.rewind(); s.next(); ) 00426 { 00427 if (s->cstr()) 00428 totlen += strlen(s->cstr()); 00429 totlen += joinlen; 00430 } 00431 totlen -= joinlen; // no join chars at tail 00432 00433 WvString total; 00434 total.setsize(totlen); 00435 00436 char *te = total.edit(); 00437 te[0] = 0; 00438 bool first = true; 00439 for (s.rewind(); s.next(); ) 00440 { 00441 if (first) 00442 first = false; 00443 else 00444 strcat(te, joinchars); 00445 if (s->cstr()) 00446 strcat(te, s->cstr()); 00447 } 00448 return total; 00449 } 00450 00455 WvString strreplace(WvStringParm s, WvStringParm a, WvStringParm b); 00456 00458 WvString undupe(WvStringParm s, char c); 00459 00461 WvString hostname(); 00462 00464 WvString fqdomainname(); 00465 00467 WvString wvgetcwd(); 00468 00473 WvString metriculate(const off_t i); 00474 00479 WvString afterstr(WvStringParm line, WvStringParm a); 00480 00485 WvString beforestr(WvStringParm line, WvStringParm a); 00486 00493 WvString substr(WvString line, unsigned int pos, unsigned int len); 00494 00499 WvString depunctuate(WvStringParm line); 00500 00501 // Converts a string in decimal to an arbitrary numeric type 00502 template<class T> 00503 bool wvstring_to_num(WvStringParm str, T &n) 00504 { 00505 bool neg = false; 00506 n = 0; 00507 00508 for (const char *p = str; *p; ++p) 00509 { 00510 if (isdigit(*p)) 00511 { 00512 n = n * T(10) + T(*p - '0'); 00513 } 00514 else if ((const char *)str == p 00515 && *p == '-') 00516 { 00517 neg = true; 00518 } 00519 else return false; 00520 } 00521 00522 if (neg) 00523 n = -n; 00524 00525 return true; 00526 } 00527 00528 /* 00529 * Before using the C-style string escaping functions below, please consider 00530 * using the functions in wvtclstring.h instead; they usualy lead to much more 00531 * human readable and manageable results, and allow representation of 00532 * lists of strings. 00533 */ 00534 00535 struct CStrExtraEscape 00536 { 00537 char ch; 00538 const char *esc; 00539 }; 00540 extern const CStrExtraEscape CSTR_TCLSTR_ESCAPES[]; 00541 00543 // 00544 // If data is NULL, returns WvString::null; otherwise, returns an allocated 00545 // WvString containing the C-style string constant that represents the data. 00546 // 00547 // All printable characters including space except " and \ are represented with 00548 // escaping. 00549 // 00550 // The usual C escapes are performed, such as \n, \r, \", \\ and \0. 00551 // 00552 // All other characters are escaped in uppercase hex form, eg. \x9E 00553 // 00554 // The extra_escapes parameter allows for additional characters beyond 00555 // the usual ones escaped in C; setting it to CSTR_TCLSTR_ESCAPES will 00556 // escape { and } as < and >, which allows the resulting strings to be 00557 // TCL-string coded without ridiculous double-escaping. 00558 // 00559 WvString cstr_escape(const void *data, size_t size, 00560 const CStrExtraEscape extra_escapes[] = NULL); 00561 00563 // 00564 // This function does *not* include the trailing null that a C compiler would -- 00565 // if you want this null, put \0 at the end of the C-style string 00566 // 00567 // If cstr is correctly formatted and max_size is large enough for the 00568 // resulting data, returns true and size will equal the size of the 00569 // resulting data. If data is not NULL it will contain this data. 00570 // 00571 // If cstr is correctly formatted but max_size is too small for the resulting 00572 // data, returns false and size will equal the minimum value of min_size 00573 // for this function to have returned true. If data is non-NULL it will 00574 // contain the first max_size bytes of resulting data. 00575 // 00576 // If cstr is incorrectly formatted, returns false and size will equal 0. 00577 // 00578 // This functions works just as well on multiple, whitespace-separated 00579 // C-style strings as well. This allows you to concatenate strings produced 00580 // by cstr_escape, and the result of cstr_unescape will be the data blocks 00581 // concatenated together. This implies that the empty string corresponds 00582 // to a valid data block of length zero; however, a null string still returns 00583 // an error. 00584 // 00585 // The extra_escapes parameter must match that used in the call to 00586 // cstr_escape used to produce the escaped strings. 00587 // 00588 bool cstr_unescape(WvStringParm cstr, void *data, size_t max_size, size_t &size, 00589 const CStrExtraEscape extra_escapes[] = NULL); 00590 00591 static inline bool is_int(const char *str) 00592 { 00593 if (!str) 00594 return false; 00595 00596 if (*str == '-') 00597 ++str; 00598 00599 if (!*str) 00600 return false; 00601 00602 while (*str) 00603 if (!isdigit(*str++)) 00604 return false; 00605 00606 return true; 00607 } 00608 00611 WvString ptr2str(void* ptr); 00612 00613 #endif // __WVSTRUTILS_H