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     enum {
00098         SENSITIVE = 0x00,
00099         INSENSITIVE = 0x01
00100     };
00101 
00102     class __EXPORT regex
00103     {
00104     private:
00105         void *object;
00106         void *results;
00107         size_t count;
00108 
00109     public:
00110         regex(const char *pattern, size_t slots = 1);
00111         regex(size_t slots = 1);
00112         ~regex();
00113 
00114         size_t offset(unsigned member);
00115         size_t size(unsigned member);
00116 
00117         inline size_t members(void)
00118             {return count;};
00119 
00120         bool match(const char *text, unsigned flags = 0);
00121 
00122         regex& operator=(const char *string);
00123 
00124         bool operator*=(const char *string);
00125 
00126         operator bool()
00127             {return object != NULL;}
00128 
00129         bool operator!()
00130             {return object == NULL;}
00131     };
00132 
00133     class __EXPORT cstring : public CountedObject
00134     {
00135     public:
00136 #pragma pack(1)
00137         strsize_t max;  
00138         strsize_t len;  
00139         char fill;      
00140         char text[1];   
00141 #pragma pack()
00142 
00148         cstring(strsize_t size);
00149 
00157         cstring(strsize_t size, char fill);
00158 
00166         void clear(strsize_t offset, strsize_t size);
00167 
00174         void set(strsize_t offset, const char *text, strsize_t size);
00175 
00180         void set(const char *text);
00181 
00186         void add(const char *text);
00187 
00192         void add(char character);
00193 
00197         void fix(void);
00198 
00203         void unfix(void);
00204 
00210         void inc(strsize_t number);
00211 
00217         void dec(strsize_t number);
00218     };
00219 
00220 protected:
00221     cstring *str;  
00229     cstring *create(strsize_t size, char fill = 0) const;
00230 
00231 public:
00239     virtual int compare(const char *string) const;
00240 
00241     inline int collate(const char *string) const
00242         {return compare(string);};
00243 
00244 protected:
00250     bool equal(const char *string) const;
00251 
00256     virtual void retain(void);
00257 
00262     virtual void release(void);
00263 
00268     virtual cstring *c_copy(void) const;
00269 
00276     virtual void cow(strsize_t size = 0);
00277 
00278     strsize_t getStringSize(void);
00279 
00280 public:
00284 #if _MSC_VER > 1400        // windows broken dll linkage issue...
00285     const static strsize_t npos = ((strsize_t)-1);
00286 #else
00287     static const strsize_t npos;
00288 #endif
00289 
00290 
00294     String();
00295 
00300     String(long value);
00301 
00306     String(double value);
00307 
00312     String(strsize_t size);
00313 
00319     String(strsize_t size, char fill);
00320 
00328     String(strsize_t size, const char *format, ...) __PRINTF(3, 4);
00329 
00330 
00335     String(const char *text);
00336 
00343     String(const char *text, strsize_t size);
00344 
00351     String(const char *text, const char *end);
00352 
00358     String(const String& existing);
00359 
00364     virtual ~String();
00365 
00372     String get(strsize_t offset, strsize_t size = 0) const;
00373 
00379     int scanf(const char *format, ...) __SCANF(2, 3);
00380 
00387     int vscanf(const char *format, va_list args) __SCANF(2, 0);
00388 
00394     strsize_t printf(const char *format, ...) __PRINTF(2, 3);
00395 
00402     strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
00403 
00408     char *c_mem(void) const;
00409 
00414     const char *c_str(void) const;
00415 
00421     virtual bool resize(strsize_t size);
00422 
00427     void set(const char *text);
00428 
00436     void set(strsize_t offset, const char *text, strsize_t size = 0);
00437 
00445     void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00446 
00454     void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00455 
00460     void add(const char *text);
00461 
00466     void add(char character);
00467 
00472     void trim(const char *list);
00473 
00478     inline void trim(strsize_t count = 1)
00479         {operator+=(count);};
00480 
00485     void chop(const char *list);
00486 
00491     inline void chop(strsize_t count = 1)
00492         {operator-=(count);};
00493 
00498     void strip(const char *list);
00499 
00505     bool unquote(const char *quote);
00506 
00512     void cut(strsize_t offset, strsize_t size = 0);
00513 
00520     void paste(strsize_t offset, const char *text, strsize_t size = 0);
00521 
00527     void clear(strsize_t offset, strsize_t size = 0);
00528 
00532     void clear(void);
00533 
00537     void upper(void);
00538 
00542     void lower(void);
00543 
00547     void erase(void);
00548 
00554     strsize_t ccount(const char *list) const;
00555 
00560     strsize_t count(void) const;
00561 
00566     strsize_t size(void) const;
00567 
00577     strsize_t offset(const char *pointer) const;
00578 
00584     char at(int position) const;
00585 
00590     const char *begin(void) const;
00591 
00596     const char *end(void) const;
00597 
00604     const char *skip(const char *list, strsize_t offset = 0) const;
00605 
00613     const char *rskip(const char *list, strsize_t offset = npos) const;
00614 
00620     const char *search(const char *string, unsigned instance = 0, unsigned flags = 0) const;
00621 
00622     const char *search(regex& expr, unsigned instance = 0, unsigned flags = 0) const;
00623 
00624     unsigned replace(const char *string, const char *text = NULL, unsigned flags = 0);
00625 
00626     unsigned replace(regex& expr, const char *text = NULL, unsigned flags = 0);
00627 
00634     const char *find(const char *list, strsize_t offset = 0) const;
00635 
00642     const char *rfind(const char *list, strsize_t offset = npos) const;
00643 
00649     void split(const char *pointer);
00650 
00656     void split(strsize_t offset);
00657 
00663     void rsplit(const char *pointer);
00664 
00670     void rsplit(strsize_t offset);
00671 
00677     const char *chr(char character) const;
00678 
00685     const char *rchr(char character) const;
00686 
00691     strsize_t len(void) const;
00692 
00697     char fill(void);
00698 
00703     inline operator const char *() const
00704         {return c_str();};
00705 
00710     inline const char *operator*() const
00711         {return c_str();};
00712 
00717     bool full(void) const;
00718 
00725     String operator()(int offset, strsize_t size) const;
00726 
00732     inline String left(strsize_t size) const
00733         {return operator()(0, size);}
00734 
00740     inline String right(strsize_t offset) const
00741         {return operator()(-((int)offset), 0);}
00742 
00749     inline String copy(strsize_t offset, strsize_t size) const
00750         {return operator()((int)offset, size);}
00751 
00759     const char *operator()(int offset) const;
00760 
00766     const char operator[](int offset) const;
00767 
00772     bool operator!() const;
00773 
00778     operator bool() const;
00779 
00785     String& operator^=(const String& object);
00786 
00791     String& operator|=(const char *text);
00792 
00793     String& operator&=(const char *text);
00794 
00800     String& operator+=(const char *text);
00801 
00807     String& operator^=(const char *text);
00808 
00813     String operator+(const char *text);
00814 
00821     String& operator|(const char *text);
00822 
00829     String& operator&(const char *text);
00830 
00837     String& operator=(const String& object);
00838 
00839     bool operator*=(const char *substring);
00840 
00841     bool operator*=(regex& expr);
00842 
00847     String& operator=(const char *text);
00848 
00852     String& operator++(void);
00853 
00858     String& operator+=(strsize_t number);
00859 
00863     String& operator--(void);
00864 
00869     String& operator-=(strsize_t number);
00870 
00875     String& operator*=(strsize_t number);
00876 
00882     bool operator==(const char *text) const;
00883 
00889     bool operator!=(const char *text) const;
00890 
00896     bool operator<(const char *text) const;
00897 
00903     bool operator<=(const char *text) const;
00904 
00910     bool operator>(const char *text) const;
00911 
00917     bool operator>=(const char *text) const;
00918 
00919     inline String& operator<<(const char *text)
00920         {add(text); return *this;}
00921 
00922     inline String& operator<<(char code)
00923         {add(code); return *this;}
00924 
00930     String &operator%(short& value);
00931 
00937     String &operator%(unsigned short& value);
00938 
00944     String &operator%(long& value);
00945 
00951     String &operator%(unsigned long& value);
00952 
00958     String &operator%(double& value);
00959 
00965     String &operator%(const char *text);
00966 
00972     static void swap(String& object1, String& object2);
00973 
00978     static void fix(String& object);
00979 
00984     static void erase(char *text);
00985 
00990     static void lower(char *text);
00991 
00996     static void upper(char *text);
00997 
01011     static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
01012 
01019     static char *skip(char *text, const char *list);
01020 
01027     static char *rskip(char *text, const char *list);
01028 
01036     static char *unquote(char *text, const char *quote);
01037 
01045     static char *rset(char *buffer, size_t size, const char *text);
01046 
01055     static char *set(char *buffer, size_t size, const char *text);
01056 
01066     static char *set(char *buffer, size_t size, const char *text, size_t max);
01067 
01077     static char *add(char *buffer, size_t size, const char *text);
01078 
01089     static char *add(char *buffer, size_t size, const char *text, size_t max);
01090 
01098     static const char *ifind(const char *text, const char *key, const char *optional);
01099 
01107     static const char *find(const char *text, const char *key, const char *optional);
01108 
01114     static size_t count(const char *text);
01115 
01122     static int compare(const char *text1, const char *text2);
01123 
01124     static inline int collate(const char *text1, const char *text2)
01125         {return compare(text1, text2);};
01126 
01133     static bool equal(const char *text1, const char *text2);
01134 
01142     static int compare(const char *text1, const char *text2, size_t size);
01143 
01151     static bool equal(const char *text1, const char *text2, size_t size);
01152 
01159     static int case_compare(const char *text1, const char *text2);
01160 
01167     static bool eq_case(const char *text1, const char *text2);
01168 
01176     static int case_compare(const char *text1, const char *text2, size_t size);
01177 
01185     static bool eq_case(const char *text1, const char *text2, size_t size);
01186 
01194     static char *trim(char *text, const char *list);
01195 
01203     static char *chop(char *text, const char *list);
01204 
01212     static char *strip(char *text, const char *list);
01213 
01222     static char *fill(char *text, size_t size, char character);
01223 
01230     static unsigned ccount(const char *text, const char *list);
01231 
01238     static char *find(char *text, const char *list);
01239 
01246     static size_t seek(char *text, const char *list);
01247 
01254     static char *rfind(char *text, const char *list);
01255 
01261     static char *dup(const char *text);
01262 
01269     static char *left(const char *text, size_t size);
01270 
01277     static const char *pos(const char *text, ssize_t offset);
01278 
01279     inline static char *right(const char *text, size_t size)
01280         {return dup(pos(text, -(signed)size));}
01281 
01282     inline static char *copy(const char *text, size_t offset, size_t len)
01283         {return left(pos(text, offset), len);}
01284 
01285     static void cut(char *text, size_t offset, size_t len);
01286 
01287     static void paste(char *text, size_t max, size_t offset, const char *data, size_t len = 0);
01288 
01301     inline char *token(char **last, const char *list, const char *quote = NULL, const char *end = NULL)
01302         {return token(c_mem(), last, list, quote, end);};
01303 
01310     inline double tod(char **pointer = NULL)
01311         {return strtod(c_mem(), pointer);}
01312 
01319     inline long tol(char **pointer = NULL)
01320         {return strtol(c_mem(), pointer, 0);}
01321 
01328     inline static double tod(const char *text, char **pointer = NULL)
01329         {return strtod(text, pointer);}
01330 
01337     inline static long tol(const char *text, char **pointer = NULL)
01338         {return strtol(text, pointer, 0);}
01339 
01348     static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
01349 
01357     static size_t b64decode(uint8_t *binary, const char *string, size_t size);
01358 
01365     static uint32_t crc24(uint8_t *binary, size_t size);
01366 
01373     static uint16_t crc16(uint8_t *binary, size_t size);
01374 
01382     static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
01383 
01391     static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
01392 
01393     static unsigned hexsize(const char *format);
01394 };
01395 
01403 class __EXPORT memstring : public String
01404 {
01405 public:
01406 #if _MSC_VER > 1400        // windows broken dll linkage issue...
01407     const static size_t header = sizeof(string::cstring);
01408 #else
01409     static const size_t header;
01410 #endif
01411 
01412 private:
01413     bool resize(strsize_t size);
01414     void cow(strsize_t adj = 0);
01415     void release(void);
01416 
01417 protected:
01418     cstring *c_copy(void) const;
01419 
01420 public:
01425     inline void operator=(String& object)
01426         {set(object.c_str());};
01427 
01432     inline void operator=(const char *text)
01433         {set(text);};
01434 
01441     memstring(void *memory, strsize_t size, char fill = 0);
01442 
01446     ~memstring();
01447 
01453     static memstring *create(strsize_t size, char fill = 0);
01454 
01461     static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
01462 };
01463 
01471 template<size_t S>
01472 class charbuf
01473 {
01474 private:
01475     char buffer[S];
01476 
01477 public:
01481     inline charbuf()
01482         {buffer[0] = 0;}
01483 
01489     inline charbuf(const char *text)
01490         {String::set(buffer, S, text);}
01491 
01495     inline charbuf(const charbuf& copy)
01496         {String::set(buffer, S, copy.buffer);}
01497 
01502     inline void operator=(const char *text)
01503         {String::set(buffer, S, text);}
01504 
01510     inline void operator+=(const char *text)
01511         {String::add(buffer, S, text);}
01512 
01517     inline operator bool() const
01518         {return buffer[0];}
01519 
01524     inline bool operator!() const
01525         {return buffer[0] == 0;}
01526 
01531     inline operator char *()
01532         {return buffer;};
01533 
01538     inline char *operator*()
01539         {return buffer;};
01540 
01546     inline char& operator[](size_t offset) const
01547         {return buffer[offset];}
01548 
01554     inline char *operator()(size_t offset)
01555         {return buffer + offset;}
01556 
01561     inline size_t size(void) const
01562         {return S;}
01563 
01568     inline size_t len(void) const
01569         {return strlen(buffer);}
01570 };
01571 
01575 typedef String string_t;
01576 
01577 typedef String::regex stringex_t;
01578 
01589 template<strsize_t S>
01590 class stringbuf : public memstring
01591 {
01592 private:
01593     char buffer[sizeof(cstring) + S];
01594 
01595 public:
01599     inline stringbuf() : memstring(buffer, S) {};
01600 
01605     inline stringbuf(const char *text) : memstring(buffer, S) {set(text);};
01606 
01611     inline void operator=(const char *text)
01612         {set(text);};
01613 
01618     inline void operator=(String& object)
01619         {set(object.c_str());};
01620 };
01621 
01622 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
01623 
01630 extern "C" inline int stricmp(const char *string1, const char *string2)
01631     {return String::case_compare(string1, string2);}
01632 
01640 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max)
01641     {return String::case_compare(string1, string2, max);}
01642 
01643 #endif
01644 
01651 inline bool eq(char const *s1, char const *s2)
01652     {return String::equal(s1, s2);}
01653 
01654 inline bool ne(char const *s1, char const *s2)
01655     {return !String::equal(s1, s2);}
01656 
01664 inline bool eq(char const *s1, char const *s2, size_t size)
01665     {return String::equal(s1, s2, size);}
01666 
01667 inline bool ne(char const *s1, char const *s2, size_t size)
01668     {return !String::equal(s1, s2, size);}
01669 
01679 inline bool eq(String &s1, const char *s2)
01680     {return s1.compare(s2) == 0;}
01681 
01682 inline bool ne(String &s1, String &s2)
01683     {return s1.compare(s2) != 0;}
01684 
01685 inline bool lt(String &s1, const char *s2)
01686     {return s1.compare(s2) < 0;}
01687 
01688 inline bool gt(String &s1, const char *s2)
01689     {return s1.compare(s2) > 0;}
01690 
01691 inline bool le(String &s1, const char *s2)
01692     {return s1.compare(s2) <= 0;}
01693 
01694 inline bool ge(String &s1, const char *s2)
01695     {return s1.compare(s2) >= 0;}
01696 
01704 inline bool eq_case(char const *s1, char const *s2)
01705     {return String::eq_case(s1, s2);}
01706 
01707 inline bool ne_case(char const *s1, char const *s2)
01708     {return !String::eq_case(s1, s2);}
01709 
01718 inline bool eq_case(char const *s1, char const *s2, size_t size)
01719     {return String::eq_case(s1, s2, size);}
01720 
01721 inline String str(const char *string)
01722     {return (String)string;}
01723 
01724 inline String str(String& string)
01725     {return (String)string;}
01726 
01727 inline String str(short value)
01728     {String temp(16, "%hd", value); return temp;}
01729 
01730 inline String str(unsigned short value)
01731     {String temp(16, "%hu", value); return temp;}
01732 
01733 inline String str(long value)
01734     {String temp(32, "%ld", value); return temp;}
01735 
01736 inline String str(unsigned long value)
01737     {String temp(32, "%lu", value); return temp;}
01738 
01739 inline String str(double value)
01740     {String temp(40, "%f", value); return temp;}
01741 
01742 String str(CharacterProtocol& cp, strsize_t size);
01743 
01744 template<>
01745 inline void swap<string_t>(string_t& s1, string_t& s2)
01746     {String::swap(s1, s2);}
01747 
01748 class __EXPORT strdup_t
01749 {
01750 private:
01751     char *data;
01752 
01753 public:
01754     inline strdup_t()
01755         {data = NULL;}
01756 
01757     inline strdup_t(char *str)
01758         {data = str;}
01759 
01760     inline ~strdup_t()
01761         {if(data) ::free(data);}
01762 
01763     inline strdup_t& operator=(char *str)
01764         {if(data) ::free(data); data = str; return *this;}
01765 
01766     inline operator bool() const
01767         {return data != NULL;}
01768 
01769     inline bool operator!() const
01770         {return data == NULL;}
01771 
01772     inline operator char*() const
01773         {return data;}
01774 
01775     inline const char *c_str(void) const
01776         {return data;};
01777 
01778     inline const char *operator*() const
01779         {return data;}
01780 
01781     inline char& operator[](int size)
01782         {return data[size];}
01783 
01784     inline char *operator+(size_t size)
01785         {return data + size;}
01786 };
01787 
01788 
01789 END_NAMESPACE
01790 
01791 #endif

Generated on 14 Aug 2013 for UCommon by  doxygen 1.4.7