WvStreams
wvstrutils.h
Go to the documentation of this file.
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 &regex, 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