UCommon
/usr/src/RPM/BUILD/ucommon-6.3.3/inc/ucommon/string.h
Go to the documentation of this file.
00001 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
00002 // Copyright (C) 2015 Cherokees of Idaho.
00003 //
00004 // This file is part of GNU uCommon C++.
00005 //
00006 // GNU uCommon C++ is free software: you can redistribute it and/or modify
00007 // it under the terms of the GNU Lesser General Public License as published
00008 // by the Free Software Foundation, either version 3 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // GNU uCommon C++ is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public License
00017 // along with GNU uCommon C++.  If not, see <http://www.gnu.org/licenses/>.
00018 
00036 #ifndef _UCOMMON_STRING_H_
00037 #define _UCOMMON_STRING_H_
00038 
00039 #ifndef _UCOMMON_CPR_H_
00040 #include <ucommon/cpr.h>
00041 #endif
00042 
00043 #ifndef _UCOMMON_GENERICS_H_
00044 #include <ucommon/generics.h>
00045 #endif
00046 
00047 #ifndef _UCOMMON_PROTOCOLS_H_
00048 #include <ucommon/protocols.h>
00049 #endif
00050 
00051 #ifndef _UCOMMON_OBJECT_H_
00052 #include <ucommon/object.h>
00053 #endif
00054 
00055 #include <stdio.h>
00056 #include <string.h>
00057 #include <stdarg.h>
00058 
00059 #ifdef  HAVE_DIRENT_H
00060 #include <dirent.h>
00061 #endif
00062 
00063 #define PGP_B64_WIDTH   64
00064 #define MIME_B64_WIDTH  76
00065 
00066 namespace ucommon {
00067 
00071 typedef unsigned short strsize_t;
00072 
00083 class __EXPORT String : public ObjectProtocol
00084 {
00085 protected:
00097 public:
00098     enum {
00099         SENSITIVE = 0x00,
00100         INSENSITIVE = 0x01
00101     };
00102 
00103     class __EXPORT regex
00104     {
00105     private:
00106         void *object;
00107         void *results;
00108         size_t count;
00109 
00110     public:
00111         regex(const char *pattern, size_t size = 1);
00112         regex(size_t size = 1);
00113         ~regex();
00114 
00115         size_t offset(unsigned member);
00116         size_t size(unsigned member);
00117 
00118         inline size_t members(void) const
00119             {return count;}
00120 
00121         bool match(const char *text, unsigned flags = 0);
00122 
00123         regex& operator=(const char *string);
00124 
00125         bool operator*=(const char *string);
00126 
00127         operator bool() const
00128             {return object != NULL;}
00129 
00130         bool operator!() const
00131             {return object == NULL;}
00132     };
00133 
00134     class __EXPORT cstring : public CountedObject
00135     {
00136     protected:
00137         void dealloc(void);
00138 
00139     public:
00140 #pragma pack(1)
00141         strsize_t max;  
00142         strsize_t len;  
00143         char fill;      
00144         char text[1];   
00145 #pragma pack()
00146 
00152         cstring(strsize_t size);
00153 
00161         cstring(strsize_t size, char fill);
00162 
00170         void clear(strsize_t offset, strsize_t size);
00171 
00178         void set(strsize_t offset, const char *text, strsize_t size);
00179 
00184         void set(const char *text);
00185 
00190         void add(const char *text);
00191 
00196         void add(char character);
00197 
00201         void fix(void);
00202 
00207         void unfix(void);
00208 
00214         void inc(strsize_t number);
00215 
00221         void dec(strsize_t number);
00222     };
00223 
00224 protected:
00225     cstring *str;  
00233     cstring *create(strsize_t size, char fill = 0) const;
00234 
00235 public:
00243     virtual int compare(const char *string) const;
00244 
00245     inline int collate(const char *string) const
00246         {return compare(string);}
00247 
00248 protected:
00254     bool equal(const char *string) const;
00255 
00260     virtual void retain(void);
00261 
00266     virtual void release(void);
00267 
00272     virtual cstring *c_copy(void) const;
00273 
00280     virtual void cow(strsize_t size = 0);
00281 
00282     strsize_t getStringSize(void) const;
00283 
00284 public:
00285 #if _MSC_VER > 1400        // windows broken dll linkage issue...
00286     const static strsize_t npos = ((strsize_t)-1);
00287     const static char eos = '\0';
00288 #else
00289     static const strsize_t npos;
00290     static const char eos;
00291 #endif
00292 
00293 
00297     String();
00298 
00303     String(long value);
00304 
00309     String(double value);
00310 
00315     String(strsize_t size);
00316 
00322     String(strsize_t size, char fill);
00323 
00331     String(strsize_t size, const char *format, ...) __PRINTF(3, 4);
00332 
00333 
00338     String(const char *text);
00339 
00346     String(const char *text, strsize_t size);
00347 
00354     String(const char *text, const char *end);
00355 
00361     String(const String& existing);
00362 
00367     virtual ~String();
00368 
00375     String get(strsize_t offset, strsize_t size = 0) const;
00376 
00382     int scanf(const char *format, ...) __SCANF(2, 3);
00383 
00390     int vscanf(const char *format, va_list args) __SCANF(2, 0);
00391 
00397     strsize_t printf(const char *format, ...) __PRINTF(2, 3);
00398 
00405     strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
00406 
00411     char *c_mem(void) const;
00412 
00417     const char *c_str(void) const;
00418 
00424     virtual bool resize(strsize_t size);
00425 
00430     void set(const char *text);
00431 
00439     void set(strsize_t offset, const char *text, strsize_t size = 0);
00440 
00448     void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00449 
00457     void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00458 
00463     void add(const char *text);
00464 
00469     void add(char character);
00470 
00475     void trim(const char *list);
00476 
00481     inline void trim(strsize_t count = 1)
00482         {operator+=(count);}
00483 
00488     void chop(const char *list);
00489 
00494     inline void chop(strsize_t count = 1)
00495         {operator-=(count);}
00496 
00501     void strip(const char *list);
00502 
00508     bool unquote(const char *quote);
00509 
00515     void cut(strsize_t offset, strsize_t size = 0);
00516 
00523     void paste(strsize_t offset, const char *text, strsize_t size = 0);
00524 
00530     void clear(strsize_t offset, strsize_t size = 0);
00531 
00535     void clear(void);
00536 
00540     void upper(void);
00541 
00545     void lower(void);
00546 
00550     void erase(void);
00551 
00557     strsize_t ccount(const char *list) const;
00558 
00563     strsize_t count(void) const;
00564 
00569     strsize_t size(void) const;
00570 
00580     strsize_t offset(const char *pointer) const;
00581 
00587     char at(int position) const;
00588 
00593     const char *begin(void) const;
00594 
00599     const char *end(void) const;
00600 
00607     const char *skip(const char *list, strsize_t offset = 0) const;
00608 
00616     const char *rskip(const char *list, strsize_t offset = npos) const;
00617 
00623     const char *search(const char *string, unsigned instance = 0, unsigned flags = 0) const;
00624 
00625     const char *search(regex& expr, unsigned instance = 0, unsigned flags = 0) const;
00626 
00627     unsigned replace(const char *string, const char *text = NULL, unsigned flags = 0);
00628 
00629     unsigned replace(regex& expr, const char *text = NULL, unsigned flags = 0);
00630 
00637     const char *find(const char *list, strsize_t offset = 0) const;
00638 
00645     const char *rfind(const char *list, strsize_t offset = npos) const;
00646 
00652     void split(const char *pointer);
00653 
00659     void split(strsize_t offset);
00660 
00666     void rsplit(const char *pointer);
00667 
00673     void rsplit(strsize_t offset);
00674 
00680     const char *chr(char character) const;
00681 
00688     const char *rchr(char character) const;
00689 
00694     strsize_t len(void) const;
00695 
00700     char fill(void);
00701 
00706     inline operator const char *() const
00707         {return c_str();}
00708 
00713     inline const char *operator*() const
00714         {return c_str();}
00715 
00720     bool full(void) const;
00721 
00728     String operator()(int offset, strsize_t size) const;
00729 
00735     inline String left(strsize_t size) const
00736         {return operator()(0, size);}
00737 
00743     inline String right(strsize_t offset) const
00744         {return operator()(-((int)offset), 0);}
00745 
00752     inline String copy(strsize_t offset, strsize_t size) const
00753         {return operator()((int)offset, size);}
00754 
00762     const char *operator()(int offset) const;
00763 
00769     const char operator[](int offset) const;
00770 
00775     bool operator!() const;
00776 
00781     operator bool() const;
00782 
00788     String& operator^=(const String& object);
00789 
00794     String& operator|=(const char *text);
00795 
00796     String& operator&=(const char *text);
00797 
00803     String& operator+=(const char *text);
00804 
00810     String& operator^=(const char *text);
00811 
00816     String operator+(const char *text);
00817 
00824     String& operator|(const char *text);
00825 
00832     String& operator&(const char *text);
00833 
00840     String& operator=(const String& object);
00841 
00842     bool operator*=(const char *substring);
00843 
00844     bool operator*=(regex& expr);
00845 
00850     String& operator=(const char *text);
00851 
00855     String& operator++(void);
00856 
00861     String& operator+=(strsize_t number);
00862 
00866     String& operator--(void);
00867 
00872     String& operator-=(strsize_t number);
00873 
00878     String& operator*=(strsize_t number);
00879 
00885     bool operator==(const char *text) const;
00886 
00892     bool operator!=(const char *text) const;
00893 
00899     bool operator<(const char *text) const;
00900 
00906     bool operator<=(const char *text) const;
00907 
00913     bool operator>(const char *text) const;
00914 
00920     bool operator>=(const char *text) const;
00921 
00922     inline String& operator<<(const char *text)
00923         {add(text); return *this;}
00924 
00925     inline String& operator<<(char code)
00926         {add(code); return *this;}
00927 
00933     String &operator%(short& value);
00934 
00940     String &operator%(unsigned short& value);
00941 
00947     String &operator%(long& value);
00948 
00954     String &operator%(unsigned long& value);
00955 
00961     String &operator%(double& value);
00962 
00968     String &operator%(const char *text);
00969 
00975     static void swap(String& object1, String& object2);
00976 
00981     static void fix(String& object);
00982 
00990     static bool check(const char *string, size_t maximum, size_t minimum = 0);
00991 
00996     static void erase(char *text);
00997 
01002     static void lower(char *text);
01003 
01008     static void upper(char *text);
01009 
01023     static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
01024 
01031     static char *skip(char *text, const char *list);
01032 
01039     static char *rskip(char *text, const char *list);
01040 
01048     static char *unquote(char *text, const char *quote);
01049 
01057     static char *rset(char *buffer, size_t size, const char *text);
01058 
01067     static char *set(char *buffer, size_t size, const char *text);
01068 
01078     static char *set(char *buffer, size_t size, const char *text, size_t max);
01079 
01089     static char *add(char *buffer, size_t size, const char *text);
01090 
01101     static char *add(char *buffer, size_t size, const char *text, size_t max);
01102 
01110     static const char *ifind(const char *text, const char *key, const char *optional);
01111 
01119     static const char *find(const char *text, const char *key, const char *optional);
01120 
01126     static size_t count(const char *text);
01127 
01134     static int compare(const char *text1, const char *text2);
01135 
01136     static inline int collate(const char *text1, const char *text2)
01137         {return compare(text1, text2);}
01138 
01145     static bool equal(const char *text1, const char *text2);
01146 
01154     static int compare(const char *text1, const char *text2, size_t size);
01155 
01163     static bool equal(const char *text1, const char *text2, size_t size);
01164 
01171     static int case_compare(const char *text1, const char *text2);
01172 
01179     static bool eq_case(const char *text1, const char *text2);
01180 
01188     static int case_compare(const char *text1, const char *text2, size_t size);
01189 
01197     static bool eq_case(const char *text1, const char *text2, size_t size);
01198 
01206     static char *trim(char *text, const char *list);
01207 
01215     static char *chop(char *text, const char *list);
01216 
01224     static char *strip(char *text, const char *list);
01225 
01234     static char *fill(char *text, size_t size, char character);
01235 
01242     static unsigned ccount(const char *text, const char *list);
01243 
01250     static char *find(char *text, const char *list);
01251 
01258     static size_t seek(char *text, const char *list);
01259 
01266     static char *rfind(char *text, const char *list);
01267 
01273     static char *dup(const char *text);
01274 
01281     static char *left(const char *text, size_t size);
01282 
01289     static const char *pos(const char *text, ssize_t offset);
01290 
01291     inline static char *right(const char *text, size_t size)
01292         {return dup(pos(text, -(signed)size));}
01293 
01294     inline static char *copy(const char *text, size_t offset, size_t len)
01295         {return left(pos(text, offset), len);}
01296 
01297     static void cut(char *text, size_t offset, size_t len);
01298 
01299     static void paste(char *text, size_t max, size_t offset, const char *data, size_t len = 0);
01300 
01313     inline char *token(char **last, const char *list, const char *quote = NULL, const char *end = NULL)
01314         {return token(c_mem(), last, list, quote, end);}
01315 
01322     inline double tod(char **pointer = NULL)
01323         {return strtod(c_mem(), pointer);}
01324 
01331     inline long tol(char **pointer = NULL)
01332         {return strtol(c_mem(), pointer, 0);}
01333 
01340     inline static double tod(const char *text, char **pointer = NULL)
01341         {return strtod(text, pointer);}
01342 
01349     inline static long tol(const char *text, char **pointer = NULL)
01350         {return strtol(text, pointer, 0);}
01351 
01358     static String b64(const uint8_t *binary, size_t size);
01359 
01368     static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
01369 
01377     static size_t b64decode(uint8_t *binary, const char *string, size_t size);
01378 
01385     static uint32_t crc24(uint8_t *binary, size_t size);
01386 
01393     static uint16_t crc16(uint8_t *binary, size_t size);
01394 
01401     static String hex(const unsigned char *binary, size_t size);
01402 
01410     static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
01411 
01419     static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
01420 
01421     static unsigned hexsize(const char *format);
01422 };
01423 
01431 class __EXPORT memstring : public String
01432 {
01433 public:
01434 #if _MSC_VER > 1400        // windows broken dll linkage issue...
01435     const static size_t header = sizeof(String::cstring);
01436 #else
01437     static const size_t header;
01438 #endif
01439 
01440 private:
01441     bool resize(strsize_t size);
01442     void cow(strsize_t adj = 0);
01443     void release(void);
01444 
01445 protected:
01446     cstring *c_copy(void) const;
01447 
01448 public:
01453     inline void operator=(String& object)
01454         {set(object.c_str());}
01455 
01460     inline void operator=(const char *text)
01461         {set(text);}
01462 
01469     memstring(void *memory, strsize_t size, char fill = 0);
01470 
01474     ~memstring();
01475 
01481     static memstring *create(strsize_t size, char fill = 0);
01482 
01489     static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
01490 };
01491 
01499 template<size_t S>
01500 class charbuf
01501 {
01502 private:
01503     char buffer[S];
01504 
01505 public:
01509     inline charbuf()
01510         {buffer[0] = 0;}
01511 
01517     inline charbuf(const char *text)
01518         {String::set(buffer, S, text);}
01519 
01523     inline charbuf(const charbuf& copy)
01524         {String::set(buffer, S, copy.buffer);}
01525 
01530     inline void operator=(const char *text)
01531         {String::set(buffer, S, text);}
01532 
01538     inline void operator+=(const char *text)
01539         {String::add(buffer, S, text);}
01540 
01545     inline operator bool() const
01546         {return buffer[0];}
01547 
01552     inline bool operator!() const
01553         {return buffer[0] == 0;}
01554 
01559     inline operator char *()
01560         {return buffer;}
01561 
01566     inline char *operator*()
01567         {return buffer;}
01568 
01574     inline char& operator[](size_t offset) const
01575         {return buffer[offset];}
01576 
01582     inline char *operator()(size_t offset)
01583         {return buffer + offset;}
01584 
01589     inline size_t size(void) const
01590         {return S;}
01591 
01596     inline size_t len(void) const
01597         {return strlen(buffer);}
01598 };
01599 
01603 typedef String string_t;
01604 
01605 typedef String::regex stringex_t;
01606 
01617 template<strsize_t S>
01618 class stringbuf : public memstring
01619 {
01620 private:
01621     char buffer[sizeof(cstring) + S];
01622 
01623 public:
01627     inline stringbuf() : memstring(buffer, S) {}
01628 
01633     inline stringbuf(const char *text) : memstring(buffer, S) {set(text);}
01634 
01639     inline void operator=(const char *text)
01640         {set(text);}
01641 
01646     inline void operator=(String& object)
01647         {set(object.c_str());}
01648 };
01649 
01650 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
01651 
01652 #ifndef stricmp
01653 #define stricmp(x,y) String::case_compare(x,y)
01654 #endif
01655 
01656 #ifndef strnicmp
01657 #define strnicmp(x,y,z) String::case_compare(x,y,z)
01658 #endif
01659 
01660 #endif
01661 
01668 inline bool eq(char const *s1, char const *s2)
01669     {return String::equal(s1, s2);}
01670 
01671 inline bool ne(char const *s1, char const *s2)
01672     {return !String::equal(s1, s2);}
01673 
01681 inline bool eq(char const *s1, char const *s2, size_t size)
01682     {return String::equal(s1, s2, size);}
01683 
01684 inline bool ne(char const *s1, char const *s2, size_t size)
01685     {return !String::equal(s1, s2, size);}
01686 
01696 inline bool eq(String &s1, const char *s2)
01697     {return s1.compare(s2) == 0;}
01698 
01699 inline bool ne(String &s1, String &s2)
01700     {return s1.compare(s2) != 0;}
01701 
01702 inline bool lt(String &s1, const char *s2)
01703     {return s1.compare(s2) < 0;}
01704 
01705 inline bool gt(String &s1, const char *s2)
01706     {return s1.compare(s2) > 0;}
01707 
01708 inline bool le(String &s1, const char *s2)
01709     {return s1.compare(s2) <= 0;}
01710 
01711 inline bool ge(String &s1, const char *s2)
01712     {return s1.compare(s2) >= 0;}
01713 
01721 inline bool eq_case(char const *s1, char const *s2)
01722     {return String::eq_case(s1, s2);}
01723 
01724 inline bool ne_case(char const *s1, char const *s2)
01725     {return !String::eq_case(s1, s2);}
01726 
01735 inline bool eq_case(char const *s1, char const *s2, size_t size)
01736     {return String::eq_case(s1, s2, size);}
01737 
01738 inline String str(const char *string)
01739     {return (String)string;}
01740 
01741 inline String str(String& string)
01742     {return (String)string;}
01743 
01744 inline String str(short value)
01745     {String temp(16, "%hd", value); return temp;}
01746 
01747 inline String str(unsigned short value)
01748     {String temp(16, "%hu", value); return temp;}
01749 
01750 inline String str(long value)
01751     {String temp(32, "%ld", value); return temp;}
01752 
01753 inline String str(unsigned long value)
01754     {String temp(32, "%lu", value); return temp;}
01755 
01756 inline String str(double value)
01757     {String temp(40, "%f", value); return temp;}
01758 
01759 String str(CharacterProtocol& cp, strsize_t size);
01760 
01761 template<>
01762 inline void swap<string_t>(string_t& s1, string_t& s2)
01763     {String::swap(s1, s2);}
01764 
01765 class __EXPORT strdup_t
01766 {
01767 private:
01768     char *data;
01769 
01770 public:
01771     inline strdup_t()
01772         {data = NULL;}
01773 
01774     inline strdup_t(char *str)
01775         {data = str;}
01776 
01777     inline ~strdup_t()
01778         {if(data) ::free(data);}
01779 
01780     inline strdup_t& operator=(char *str)
01781         {if(data) ::free(data); data = str; return *this;}
01782 
01783     inline operator bool() const
01784         {return data != NULL;}
01785 
01786     inline bool operator!() const
01787         {return data == NULL;}
01788 
01789     inline operator char*() const
01790         {return data;}
01791 
01792     inline const char *c_str(void) const
01793         {return data;}
01794 
01795     inline const char *operator*() const
01796         {return data;}
01797 
01798     inline char& operator[](int size)
01799         {return data[size];}
01800 
01801     inline char *operator+(size_t size)
01802         {return data + size;}
01803 };
01804 
01805 } // namespace ucommon
01806 
01807 #endif