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 
00204     inline int collate(const char *string) const
00205         {return compare(string);};
00206 
00212     bool equal(const char *string) const;
00213 
00218     virtual void retain(void);
00219 
00224     virtual void release(void);
00225 
00230     virtual cstring *c_copy(void) const;
00231 
00238     virtual void cow(strsize_t size = 0);
00239 
00240     strsize_t getStringSize(void);
00241 
00242 public:
00246 #if _MSC_VER > 1400        // windows broken dll linkage issue...
00247     const static strsize_t npos = ((strsize_t)-1);
00248 #else
00249     static const strsize_t npos;
00250 #endif
00251 
00252 
00256     string();
00257 
00262     string(long value);
00263 
00268     string(double value);
00269 
00274     string(strsize_t size);
00275 
00281     string(strsize_t size, char fill);
00282 
00290     string(strsize_t size, const char *format, ...) __PRINTF(3, 4);
00291 
00292 
00297     string(const char *text);
00298 
00305     string(const char *text, strsize_t size);
00306 
00313     string(const char *text, const char *end);
00314 
00320     string(const string& existing);
00321 
00326     virtual ~string();
00327 
00334     string get(strsize_t offset, strsize_t size = 0) const;
00335 
00341     int scanf(const char *format, ...) __SCANF(2, 3);
00342 
00349     int vscanf(const char *format, va_list args) __SCANF(2, 0);
00350 
00356     strsize_t printf(const char *format, ...) __PRINTF(2, 3);
00357 
00364     strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
00365 
00370     char *c_mem(void) const;
00371 
00376     const char *c_str(void) const;
00377 
00383     virtual bool resize(strsize_t size);
00384 
00389     void set(const char *text);
00390 
00398     void set(strsize_t offset, const char *text, strsize_t size = 0);
00399 
00407     void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00408 
00416     void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00417 
00422     void add(const char *text);
00423 
00428     void add(char character);
00429 
00434     void trim(const char *list);
00435 
00440     void chop(const char *list);
00441 
00446     void strip(const char *list);
00447 
00453     bool unquote(const char *quote);
00454 
00460     void cut(strsize_t offset, strsize_t size = 0);
00461 
00467     void clear(strsize_t offset, strsize_t size = 0);
00468 
00472     void clear(void);
00473 
00477     void upper(void);
00478 
00482     void lower(void);
00483 
00489     strsize_t ccount(const char *list) const;
00490 
00495     strsize_t count(void) const;
00496 
00501     strsize_t size(void) const;
00502 
00512     strsize_t offset(const char *pointer) const;
00513 
00519     char at(int position) const;
00520 
00526     const char *last(const char *list) const;
00527 
00533     const char *first(const char *list) const;
00534 
00539     const char *begin(void) const;
00540 
00545     const char *end(void) const;
00546 
00553     const char *skip(const char *list, strsize_t offset = 0) const;
00554 
00562     const char *rskip(const char *list, strsize_t offset = npos) const;
00563 
00570     const char *find(const char *list, strsize_t offset = 0) const;
00571 
00578     const char *rfind(const char *list, strsize_t offset = npos) const;
00579 
00585     void split(const char *pointer);
00586 
00592     void split(strsize_t offset);
00593 
00599     void rsplit(const char *pointer);
00600 
00606     void rsplit(strsize_t offset);
00607 
00613     const char *chr(char character) const;
00614 
00621     const char *rchr(char character) const;
00622 
00627     strsize_t len(void);
00628 
00633     char fill(void);
00634 
00639     inline operator const char *() const
00640         {return c_str();};
00641 
00646     inline const char *operator*() const
00647         {return c_str();};
00648 
00653     bool full(void) const;
00654 
00661     string operator()(int offset, strsize_t size) const;
00662 
00670     const char *operator()(int offset) const;
00671 
00677     const char operator[](int offset) const;
00678 
00683     bool operator!() const;
00684 
00689     operator bool() const;
00690 
00696     string& operator^=(const string& object);
00697 
00703     string& operator+=(const char *text);
00704 
00710     string& operator^=(const char *text);
00711 
00717     string& operator+(const char *text);
00718 
00725     string& operator&(const char *text);
00726 
00733     string& operator=(const string& object);
00734 
00739     string& operator=(const char *text);
00740 
00744     string& operator++(void);
00745 
00750     string& operator+=(strsize_t number);
00751 
00755     string& operator--(void);
00756 
00761     string& operator-=(strsize_t number);
00762 
00768     bool operator==(const char *text) const;
00769 
00775     bool operator!=(const char *text) const;
00776 
00782     bool operator<(const char *text) const;
00783 
00789     bool operator<=(const char *text) const;
00790 
00796     bool operator>(const char *text) const;
00797 
00803     bool operator>=(const char *text) const;
00804 
00810     string &operator%(short& value);
00811 
00817     string &operator%(unsigned short& value);
00818 
00824     string &operator%(long& value);
00825 
00831     string &operator%(unsigned long& value);
00832 
00838     string &operator%(double& value);
00839 
00845     string &operator%(const char *text);
00846 
00853     static int scanf(string& object, const char *format, ...) __SCANF(2, 3);
00854 
00861     static strsize_t printf(string& object, const char *format, ...) __PRINTF(2, 3);
00862 
00868     static void swap(string& object1, string& object2);
00869 
00874     static void fix(string& object);
00875 
00880     static void lower(char *text);
00881 
00886     static void upper(char *text);
00887 
00901     static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
00902 
00909     static char *skip(char *text, const char *list);
00910 
00917     static char *rskip(char *text, const char *list);
00918 
00926     static char *unquote(char *text, const char *quote);
00927 
00935     static char *rset(char *buffer, size_t size, const char *text);
00936 
00945     static char *set(char *buffer, size_t size, const char *text);
00946 
00956     static char *set(char *buffer, size_t size, const char *text, size_t max);
00957 
00967     static char *add(char *buffer, size_t size, const char *text);
00968 
00979     static char *add(char *buffer, size_t size, const char *text, size_t max);
00980 
00988     static const char *ifind(const char *text, const char *key, const char *optional);
00989 
00997     static const char *find(const char *text, const char *key, const char *optional);
00998 
01004     static size_t count(const char *text);
01005 
01012     static int compare(const char *text1, const char *text2);
01013 
01014     static inline int collate(const char *text1, const char *text2)
01015         {return compare(text1, text2);};
01016 
01023     static bool equal(const char *text1, const char *text2);
01024 
01032     static int compare(const char *text1, const char *text2, size_t size);
01033 
01041     static bool equal(const char *text1, const char *text2, size_t size);
01042 
01049     static int case_compare(const char *text1, const char *text2);
01050 
01057     static bool case_equal(const char *text1, const char *text2);
01058 
01066     static int case_compare(const char *text1, const char *text2, size_t size);
01067 
01075     static bool case_equal(const char *text1, const char *text2, size_t size);
01076 
01084     static char *trim(char *text, const char *list);
01085 
01093     static char *chop(char *text, const char *list);
01094 
01102     static char *strip(char *text, const char *list);
01103 
01112     static char *fill(char *text, size_t size, char character);
01113 
01120     static unsigned ccount(const char *text, const char *list);
01121 
01128     static char *find(char *text, const char *list);
01129 
01136     static char *rfind(char *text, const char *list);
01137 
01144     static char *first(char *text, const char *list);
01145 
01152     static char *last(char *text, const char *list);
01153 
01159     static char *dup(const char *text);
01160 
01174     inline static char *token(string& object, char **last, const char *list, const char *quote = NULL, const char *end = NULL)
01175         {return token(object.c_mem(), last, list, quote, end);};
01176 
01184     __SCANF(2,0) inline static int vscanf(string& object, const char *format, va_list args)
01185         {return object.vscanf(format, args);}
01186 
01194     __PRINTF(2,0) inline static strsize_t vprintf(string& object, const char *format, va_list args)
01195         {return object.vprintf(format, args);}
01196 
01202     inline static strsize_t len(string& object)
01203         {return object.len();};
01204 
01210     inline static char *mem(string& object)
01211         {return object.c_mem();};
01212 
01218     inline static strsize_t size(string& object)
01219         {return object.size();};
01220 
01225     inline static void clear(string& object)
01226         {object.clear();};
01227 
01234     inline static unsigned ccount(string& object, const char *list)
01235         {return object.ccount(list);};
01236 
01242     inline static size_t count(string& object)
01243         {return object.count();};
01244 
01249     inline static void upper(string& object)
01250         {object.upper();};
01251 
01256     inline static void lower(string& object)
01257         {object.lower();};
01258 
01265     inline static bool unquote(string& object, const char *quote)
01266         {return object.unquote(quote);};
01267 
01273     inline static void trim(string& object, const char *list)
01274         {object.trim(list);};
01275 
01281     inline static void chop(string& object, const char *list)
01282         {object.trim(list);};
01283 
01289     inline static void strip(string& object, const char *list)
01290         {object.trim(list);};
01291 
01298     inline static const char *find(string& object, const char *list)
01299         {return object.find(list);};
01300 
01307     inline static const char *rfind(string& object, const char *list)
01308         {return object.rfind(list);};
01309 
01316     inline static const char *first(string& object, const char *list)
01317         {return object.first(list);};
01318 
01325     inline static const char *last(string& object, const char *list)
01326         {return object.last(list);};
01327 
01334     inline static double tod(string& object, char **pointer = NULL)
01335         {return strtod(mem(object), pointer);};
01336 
01343     inline static long tol(string& object, char **pointer = NULL)
01344         {return strtol(mem(object), pointer, 0);};
01345 
01352     inline static double tod(const char *text, char **pointer = NULL)
01353         {return strtod(text, pointer);};
01354 
01361     inline static long tol(const char *text, char **pointer = NULL)
01362         {return strtol(text, pointer, 0);};
01363 
01372     static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
01373 
01381     static size_t b64decode(uint8_t *binary, const char *string, size_t size);
01382 
01389     static uint32_t crc24(uint8_t *binary, size_t size);
01390 
01397     static uint16_t crc16(uint8_t *binary, size_t size);
01398 
01406     static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
01407 
01415     static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
01416 
01417     static unsigned hexsize(const char *format);
01418 };
01419 
01427 class __EXPORT memstring : public string
01428 {
01429 public:
01430 #if _MSC_VER > 1400        // windows broken dll linkage issue...
01431     const static size_t header = sizeof(string::cstring);
01432 #else
01433     static const size_t header;
01434 #endif
01435 
01436 private:
01437     bool resize(strsize_t size);
01438     void cow(strsize_t adj = 0);
01439     void release(void);
01440 
01441 protected:
01442     cstring *c_copy(void) const;
01443 
01444 public:
01449     inline void operator=(string& object)
01450         {set(object.c_str());};
01451 
01456     inline void operator=(const char *text)
01457         {set(text);};
01458 
01465     memstring(void *memory, strsize_t size, char fill = 0);
01466 
01470     ~memstring();
01471 
01477     static memstring *create(strsize_t size, char fill = 0);
01478 
01485     static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
01486 };
01487 
01495 template<size_t S>
01496 class charbuf
01497 {
01498 private:
01499     char buffer[S];
01500 
01501 public:
01505     inline charbuf()
01506         {buffer[0] = 0;};
01507 
01513     inline charbuf(const char *text)
01514         {string::set(buffer, S, text);};
01515 
01520     inline void operator=(const char *text)
01521         {string::set(buffer, S, text);};
01522 
01528     inline void operator+=(const char *text)
01529         {string::add(buffer, S, text);};
01530 
01535     inline operator bool() const
01536         {return buffer[0];};
01537 
01542     inline bool operator!() const
01543         {return buffer[0] == 0;};
01544 
01549     inline operator char *()
01550         {return buffer;};
01551 
01556     inline char *operator*()
01557         {return buffer;};
01558 
01564     inline char operator[](size_t offset) const
01565         {return buffer[offset];};
01566 
01572     inline char *operator()(size_t offset)
01573         {return buffer + offset;};
01574 
01579     inline size_t size(void) const
01580         {return S;};
01581 };
01582 
01586 typedef string string_t;
01587 
01592 typedef string String;
01593 
01604 template<strsize_t S>
01605 class stringbuf : public memstring
01606 {
01607 private:
01608     char buffer[sizeof(cstring) + S];
01609 
01610 public:
01614     inline stringbuf() : memstring(buffer, S) {};
01615 
01620     inline stringbuf(const char *text) : memstring(buffer, S) {set(text);};
01621 
01626     inline void operator=(const char *text)
01627         {set(text);};
01628 
01633     inline void operator=(string& object)
01634         {set(object.c_str());};
01635 };
01636 
01637 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
01638 
01645 extern "C" inline int stricmp(const char *string1, const char *string2)
01646     {return string::case_compare(string1, string2);}
01647 
01655 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max)
01656     {return string::case_compare(string1, string2, max);}
01657 
01658 #endif
01659 
01666 inline bool eq(char const *s1, char const *s2)
01667     {return String::equal(s1, s2);}
01668 
01676 inline bool eq(char const *s1, char const *s2, size_t size)
01677     {return String::equal(s1, s2, size);}
01678 
01685 inline bool eq(String &s1, String &s2)
01686     {return String::equal(s1.c_str(), s2.c_str());}
01687 
01695 inline bool case_eq(char const *s1, char const *s2)
01696     {return String::case_equal(s1, s2);}
01697 
01698 // to be depreciated...
01699 inline bool ieq(char const *s1, char const *s2)
01700     {return String::case_equal(s1, s2);}
01701 
01710 inline bool case_eq(char const *s1, char const *s2, size_t size)
01711     {return String::case_equal(s1, s2, size);}
01712 
01713 inline bool ieq(char const *s1, char const *s2, size_t size)
01714     {return String::case_equal(s1, s2, size);}
01715 
01723 inline bool ieq(String &s1, String &s2)
01724     {return String::case_equal(s1.c_str(), s2.c_str());}
01725 
01726 inline String str(const char *string)
01727     {return (String)string;}
01728 
01729 inline String str(String& string)
01730     {return (String)string;}
01731 
01732 inline String str(short value)
01733     {String temp(16, "%hd", value); return temp;}
01734 
01735 inline String str(unsigned short value)
01736     {String temp(16, "%hu", value); return temp;}
01737 
01738 inline String str(long value)
01739     {String temp(32, "%ld", value); return temp;}
01740 
01741 inline String str(unsigned long value)
01742     {String temp(32, "%lu", value); return temp;}
01743 
01744 inline String str(double value)
01745     {String temp(40, "%f", value); return temp;}
01746 
01747 String str(CharacterProtocol& cp, strsize_t size);
01748 
01749 template<>
01750 inline void swap<string_t>(string_t& s1, string_t& s2)
01751     {String::swap(s1, s2);}
01752 
01753 END_NAMESPACE
01754 
01755 #endif