UCommon
ucommon/string.h
Go to the documentation of this file.
00001 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
00002 //
00003 // This file is part of GNU uCommon C++.
00004 //
00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU Lesser General Public License as published
00007 // by the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // GNU uCommon C++ is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public License
00016 // along with GNU uCommon C++.  If not, see <http://www.gnu.org/licenses/>.
00017 
00035 #ifndef _UCOMMON_STRING_H_
00036 #define _UCOMMON_STRING_H_
00037 
00038 #ifndef _UCOMMON_CPR_H_
00039 #include <ucommon/cpr.h>
00040 #endif
00041 
00042 #ifndef _UCOMMON_GENERICS_H_
00043 #include <ucommon/generics.h>
00044 #endif
00045 
00046 #ifndef _UCOMMON_PROTOCOLS_H_
00047 #include <ucommon/protocols.h>
00048 #endif
00049 
00050 #ifndef _UCOMMON_OBJECT_H_
00051 #include <ucommon/object.h>
00052 #endif
00053 
00054 #include <stdio.h>
00055 #include <string.h>
00056 #include <stdarg.h>
00057 
00058 #ifdef  HAVE_DIRENT_H
00059 #include <dirent.h>
00060 #endif
00061 
00062 #define PGP_B64_WIDTH   64
00063 #define MIME_B64_WIDTH  76
00064 
00065 NAMESPACE_UCOMMON
00066 
00070 typedef unsigned short strsize_t;
00071 
00082 class __EXPORT string : public ObjectProtocol
00083 {
00084 protected:
00096 public:
00097     class __EXPORT cstring : public CountedObject
00098     {
00099     public:
00100 #pragma pack(1)
00101         strsize_t max;  
00102         strsize_t len;  
00103         char fill;      
00104         char text[1];   
00105 #pragma pack()
00106 
00112         cstring(strsize_t size);
00113 
00121         cstring(strsize_t size, char fill);
00122 
00130         void clear(strsize_t offset, strsize_t size);
00131 
00138         void set(strsize_t offset, const char *text, strsize_t size);
00139 
00144         void set(const char *text);
00145 
00150         void add(const char *text);
00151 
00156         void add(char character);
00157 
00161         void fix(void);
00162 
00167         void unfix(void);
00168 
00174         void inc(strsize_t number);
00175 
00181         void dec(strsize_t number);
00182     };
00183 
00184 protected:
00185     cstring *str;  
00193     cstring *create(strsize_t size, char fill = 0) const;
00194 
00202     virtual int compare(const char *string) const;
00203 
00209     bool equal(const char *string) const;
00210 
00215     virtual void retain(void);
00216 
00221     virtual void release(void);
00222 
00227     virtual cstring *c_copy(void) const;
00228 
00235     virtual void cow(strsize_t size = 0);
00236 
00237     strsize_t getStringSize(void);
00238 
00239 public:
00243 #if _MSC_VER > 1400        // windows broken dll linkage issue...
00244     const static strsize_t npos = ((strsize_t)-1);
00245 #else
00246     static const strsize_t npos;
00247 #endif
00248 
00249 
00253     string();
00254 
00259     string(long value);
00260 
00265     string(double value);
00266 
00271     string(strsize_t size);
00272 
00278     string(strsize_t size, char fill);
00279 
00287     string(strsize_t size, const char *format, ...) __PRINTF(3, 4);
00288 
00289 
00294     string(const char *text);
00295 
00302     string(const char *text, strsize_t size);
00303 
00310     string(const char *text, const char *end);
00311 
00317     string(const string& existing);
00318 
00323     virtual ~string();
00324 
00331     string get(strsize_t offset, strsize_t size = 0) const;
00332 
00338     int scanf(const char *format, ...) __SCANF(2, 3);
00339 
00346     int vscanf(const char *format, va_list args) __SCANF(2, 0);
00347 
00353     strsize_t printf(const char *format, ...) __PRINTF(2, 3);
00354 
00361     strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
00362 
00367     char *c_mem(void) const;
00368 
00373     const char *c_str(void) const;
00374 
00380     virtual bool resize(strsize_t size);
00381 
00386     void set(const char *text);
00387 
00395     void set(strsize_t offset, const char *text, strsize_t size = 0);
00396 
00404     void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00405 
00413     void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00414 
00419     void add(const char *text);
00420 
00425     void add(char character);
00426 
00431     void trim(const char *list);
00432 
00437     void chop(const char *list);
00438 
00443     void strip(const char *list);
00444 
00450     bool unquote(const char *quote);
00451 
00457     void cut(strsize_t offset, strsize_t size = 0);
00458 
00464     void clear(strsize_t offset, strsize_t size = 0);
00465 
00469     void clear(void);
00470 
00474     void upper(void);
00475 
00479     void lower(void);
00480 
00486     strsize_t ccount(const char *list) const;
00487 
00492     strsize_t count(void) const;
00493 
00498     strsize_t size(void) const;
00499 
00509     strsize_t offset(const char *pointer) const;
00510 
00516     char at(int position) const;
00517 
00523     const char *last(const char *list) const;
00524 
00530     const char *first(const char *list) const;
00531 
00536     const char *begin(void) const;
00537 
00542     const char *end(void) const;
00543 
00550     const char *skip(const char *list, strsize_t offset = 0) const;
00551 
00559     const char *rskip(const char *list, strsize_t offset = npos) const;
00560 
00567     const char *find(const char *list, strsize_t offset = 0) const;
00568 
00575     const char *rfind(const char *list, strsize_t offset = npos) const;
00576 
00582     void split(const char *pointer);
00583 
00589     void split(strsize_t offset);
00590 
00596     void rsplit(const char *pointer);
00597 
00603     void rsplit(strsize_t offset);
00604 
00610     const char *chr(char character) const;
00611 
00618     const char *rchr(char character) const;
00619 
00624     strsize_t len(void);
00625 
00630     char fill(void);
00631 
00636     inline operator const char *() const
00637         {return c_str();};
00638 
00643     inline const char *operator*() const
00644         {return c_str();};
00645 
00650     bool full(void) const;
00651 
00658     string operator()(int offset, strsize_t size) const;
00659 
00667     const char *operator()(int offset) const;
00668 
00674     const char operator[](int offset) const;
00675 
00680     bool operator!() const;
00681 
00686     operator bool() const;
00687 
00693     string& operator^=(const string& object);
00694 
00700     string& operator+=(const char *text);
00701 
00707     string& operator^=(const char *text);
00708 
00714     string& operator+(const char *text);
00715 
00722     string& operator&(const char *text);
00723 
00730     string& operator=(const string& object);
00731 
00736     string& operator=(const char *text);
00737 
00741     string& operator++(void);
00742 
00747     string& operator+=(strsize_t number);
00748 
00752     string& operator--(void);
00753 
00758     string& operator-=(strsize_t number);
00759 
00765     bool operator==(const char *text) const;
00766 
00772     bool operator!=(const char *text) const;
00773 
00779     bool operator<(const char *text) const;
00780 
00786     bool operator<=(const char *text) const;
00787 
00793     bool operator>(const char *text) const;
00794 
00800     bool operator>=(const char *text) const;
00801 
00807     string &operator%(short& value);
00808 
00814     string &operator%(unsigned short& value);
00815 
00821     string &operator%(long& value);
00822 
00828     string &operator%(unsigned long& value);
00829 
00835     string &operator%(double& value);
00836 
00842     string &operator%(const char *text);
00843 
00850     static int scanf(string& object, const char *format, ...) __SCANF(2, 3);
00851 
00858     static strsize_t printf(string& object, const char *format, ...) __PRINTF(2, 3);
00859 
00865     static void swap(string& object1, string& object2);
00866 
00871     static void fix(string& object);
00872 
00877     static void lower(char *text);
00878 
00883     static void upper(char *text);
00884 
00898     static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
00899 
00906     static char *skip(char *text, const char *list);
00907 
00914     static char *rskip(char *text, const char *list);
00915 
00923     static char *unquote(char *text, const char *quote);
00924 
00932     static char *rset(char *buffer, size_t size, const char *text);
00933 
00942     static char *set(char *buffer, size_t size, const char *text);
00943 
00953     static char *set(char *buffer, size_t size, const char *text, size_t max);
00954 
00964     static char *add(char *buffer, size_t size, const char *text);
00965 
00976     static char *add(char *buffer, size_t size, const char *text, size_t max);
00977 
00985     static const char *ifind(const char *text, const char *key, const char *optional);
00986 
00994     static const char *find(const char *text, const char *key, const char *optional);
00995 
01001     static size_t count(const char *text);
01002 
01009     static int compare(const char *text1, const char *text2);
01010 
01017     static bool equal(const char *text1, const char *text2);
01018 
01026     static int compare(const char *text1, const char *text2, size_t size);
01027 
01035     static bool equal(const char *text1, const char *text2, size_t size);
01036 
01043     static int case_compare(const char *text1, const char *text2);
01044 
01051     static bool case_equal(const char *text1, const char *text2);
01052 
01060     static int case_compare(const char *text1, const char *text2, size_t size);
01061 
01069     static bool case_equal(const char *text1, const char *text2, size_t size);
01070 
01078     static char *trim(char *text, const char *list);
01079 
01087     static char *chop(char *text, const char *list);
01088 
01096     static char *strip(char *text, const char *list);
01097 
01106     static char *fill(char *text, size_t size, char character);
01107 
01114     static unsigned ccount(const char *text, const char *list);
01115 
01122     static char *find(char *text, const char *list);
01123 
01130     static char *rfind(char *text, const char *list);
01131 
01138     static char *first(char *text, const char *list);
01139 
01146     static char *last(char *text, const char *list);
01147 
01153     static char *dup(const char *text);
01154 
01168     inline static char *token(string& object, char **last, const char *list, const char *quote = NULL, const char *end = NULL)
01169         {return token(object.c_mem(), last, list, quote, end);};
01170 
01178     __SCANF(2,0) inline static int vscanf(string& object, const char *format, va_list args)
01179         {return object.vscanf(format, args);}
01180 
01188     __PRINTF(2,0) inline static strsize_t vprintf(string& object, const char *format, va_list args)
01189         {return object.vprintf(format, args);}
01190 
01196     inline static strsize_t len(string& object)
01197         {return object.len();};
01198 
01204     inline static char *mem(string& object)
01205         {return object.c_mem();};
01206 
01212     inline static strsize_t size(string& object)
01213         {return object.size();};
01214 
01219     inline static void clear(string& object)
01220         {object.clear();};
01221 
01228     inline static unsigned ccount(string& object, const char *list)
01229         {return object.ccount(list);};
01230 
01236     inline static size_t count(string& object)
01237         {return object.count();};
01238 
01243     inline static void upper(string& object)
01244         {object.upper();};
01245 
01250     inline static void lower(string& object)
01251         {object.lower();};
01252 
01259     inline static bool unquote(string& object, const char *quote)
01260         {return object.unquote(quote);};
01261 
01267     inline static void trim(string& object, const char *list)
01268         {object.trim(list);};
01269 
01275     inline static void chop(string& object, const char *list)
01276         {object.trim(list);};
01277 
01283     inline static void strip(string& object, const char *list)
01284         {object.trim(list);};
01285 
01292     inline static const char *find(string& object, const char *list)
01293         {return object.find(list);};
01294 
01301     inline static const char *rfind(string& object, const char *list)
01302         {return object.rfind(list);};
01303 
01310     inline static const char *first(string& object, const char *list)
01311         {return object.first(list);};
01312 
01319     inline static const char *last(string& object, const char *list)
01320         {return object.last(list);};
01321 
01328     inline static double tod(string& object, char **pointer = NULL)
01329         {return strtod(mem(object), pointer);};
01330 
01337     inline static long tol(string& object, char **pointer = NULL)
01338         {return strtol(mem(object), pointer, 0);};
01339 
01346     inline static double tod(const char *text, char **pointer = NULL)
01347         {return strtod(text, pointer);};
01348 
01355     inline static long tol(const char *text, char **pointer = NULL)
01356         {return strtol(text, pointer, 0);};
01357 
01366     static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
01367 
01375     static size_t b64decode(uint8_t *binary, const char *string, size_t size);
01376 
01383     static uint32_t crc24(uint8_t *binary, size_t size);
01384 
01391     static uint16_t crc16(uint8_t *binary, size_t size);
01392 
01400     static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
01401 
01409     static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
01410 
01411     static unsigned hexsize(const char *format);
01412 };
01413 
01421 class __EXPORT memstring : public string
01422 {
01423 public:
01424 #if _MSC_VER > 1400        // windows broken dll linkage issue...
01425     const static size_t header = sizeof(string::cstring);
01426 #else
01427     static const size_t header;
01428 #endif
01429 
01430 private:
01431     bool resize(strsize_t size);
01432     void cow(strsize_t adj = 0);
01433     void release(void);
01434 
01435 protected:
01436     cstring *c_copy(void) const;
01437 
01438 public:
01443     inline void operator=(string& object)
01444         {set(object.c_str());};
01445 
01450     inline void operator=(const char *text)
01451         {set(text);};
01452 
01459     memstring(void *memory, strsize_t size, char fill = 0);
01460 
01464     ~memstring();
01465 
01471     static memstring *create(strsize_t size, char fill = 0);
01472 
01479     static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
01480 };
01481 
01489 template<size_t S>
01490 class charbuf
01491 {
01492 private:
01493     char buffer[S];
01494 
01495 public:
01499     inline charbuf()
01500         {buffer[0] = 0;};
01501 
01507     inline charbuf(const char *text)
01508         {string::set(buffer, S, text);};
01509 
01514     inline void operator=(const char *text)
01515         {string::set(buffer, S, text);};
01516 
01522     inline void operator+=(const char *text)
01523         {string::add(buffer, S, text);};
01524 
01529     inline operator bool() const
01530         {return buffer[0];};
01531 
01536     inline bool operator!() const
01537         {return buffer[0] == 0;};
01538 
01543     inline operator char *()
01544         {return buffer;};
01545 
01550     inline char *operator*()
01551         {return buffer;};
01552 
01558     inline char operator[](size_t offset) const
01559         {return buffer[offset];};
01560 
01566     inline char *operator()(size_t offset)
01567         {return buffer + offset;};
01568 
01573     inline size_t size(void) const
01574         {return S;};
01575 };
01576 
01580 typedef string string_t;
01581 
01586 typedef string String;
01587 
01598 template<strsize_t S>
01599 class stringbuf : public memstring
01600 {
01601 private:
01602     char buffer[sizeof(cstring) + S];
01603 
01604 public:
01608     inline stringbuf() : memstring(buffer, S) {};
01609 
01614     inline stringbuf(const char *text) : memstring(buffer, S) {set(text);};
01615 
01620     inline void operator=(const char *text)
01621         {set(text);};
01622 
01627     inline void operator=(string& object)
01628         {set(object.c_str());};
01629 };
01630 
01631 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
01632 
01639 extern "C" inline int stricmp(const char *string1, const char *string2)
01640     {return string::case_compare(string1, string2);}
01641 
01649 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max)
01650     {return string::case_compare(string1, string2, max);}
01651 
01652 #endif
01653 
01660 inline bool eq(char const *s1, char const *s2)
01661     {return String::equal(s1, s2);}
01662 
01670 inline bool eq(char const *s1, char const *s2, size_t size)
01671     {return String::equal(s1, s2, size);}
01672 
01679 inline bool eq(String &s1, String &s2)
01680     {return String::equal(s1.c_str(), s2.c_str());}
01681 
01689 inline bool case_eq(char const *s1, char const *s2)
01690     {return String::case_equal(s1, s2);}
01691 
01692 // to be depreciated...
01693 inline bool ieq(char const *s1, char const *s2)
01694     {return String::case_equal(s1, s2);}
01695 
01704 inline bool case_eq(char const *s1, char const *s2, size_t size)
01705     {return String::case_equal(s1, s2, size);}
01706 
01707 inline bool ieq(char const *s1, char const *s2, size_t size)
01708     {return String::case_equal(s1, s2, size);}
01709 
01717 inline bool ieq(String &s1, String &s2)
01718     {return String::case_equal(s1.c_str(), s2.c_str());}
01719 
01720 inline String str(const char *string)
01721     {return (String)string;}
01722 
01723 inline String str(String& string)
01724     {return (String)string;}
01725 
01726 inline String str(short value)
01727     {String temp(16, "%hd", value); return temp;}
01728 
01729 inline String str(unsigned short value)
01730     {String temp(16, "%hu", value); return temp;}
01731 
01732 inline String str(long value)
01733     {String temp(32, "%ld", value); return temp;}
01734 
01735 inline String str(unsigned long value)
01736     {String temp(32, "%lu", value); return temp;}
01737 
01738 inline String str(double value)
01739     {String temp(40, "%f", value); return temp;}
01740 
01741 String str(CharacterProtocol& cp, strsize_t size);
01742 
01743 template<>
01744 inline void swap<string_t>(string_t& s1, string_t& s2)
01745     {String::swap(s1, s2);}
01746 
01747 END_NAMESPACE
01748 
01749 #endif