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_CONFIG_H_
00039 #include <ucommon/platform.h>
00040 #endif
00041 
00042 #ifndef _UCOMMON_PROTOCOLS_H_
00043 #include <ucommon/protocols.h>
00044 #endif
00045 
00046 #ifndef _UCOMMON_OBJECT_H_
00047 #include <ucommon/object.h>
00048 #endif
00049 
00050 #include <stdio.h>
00051 #include <string.h>
00052 #include <stdarg.h>
00053 
00054 #ifdef  HAVE_DIRENT_H
00055 #include <dirent.h>
00056 #endif
00057 
00058 NAMESPACE_UCOMMON
00059 
00063 typedef unsigned short strsize_t;
00064 
00075 class __EXPORT string : public Object
00076 {
00077 protected:
00089 public:
00090     class __EXPORT cstring : public CountedObject
00091     {
00092     public:
00093 #pragma pack(1)
00094         strsize_t max;  
00095         strsize_t len;  
00096         char fill;      
00097         char text[1];   
00098 #pragma pack()
00099 
00105         cstring(strsize_t size);
00106 
00114         cstring(strsize_t size, char fill);
00115 
00123         void clear(strsize_t offset, strsize_t size);
00124 
00131         void set(strsize_t offset, const char *text, strsize_t size);
00132 
00137         void set(const char *text);
00138 
00143         void add(const char *text);
00144 
00149         void add(char character);
00150 
00154         void fix(void);
00155 
00160         void unfix(void);
00161 
00167         void inc(strsize_t number);
00168 
00174         void dec(strsize_t number);
00175     };
00176 
00177 protected:
00178     cstring *str;  
00186     cstring *create(strsize_t size, char fill = 0) const;
00187 
00195     virtual int compare(const char *string) const;
00196 
00202     bool equal(const char *string) const;
00203 
00208     virtual void retain(void);
00209 
00214     virtual void release(void);
00215 
00220     virtual cstring *c_copy(void) const;
00221 
00228     virtual void cow(strsize_t size = 0);
00229 
00230     strsize_t getStringSize(void);
00231 
00232 public:
00236     static const strsize_t npos;
00237 
00241     string();
00242 
00247     string(long value);
00248 
00253     string(double value);
00254 
00259     string(strsize_t size);
00260 
00266     string(strsize_t size, char fill);
00267 
00275     string(strsize_t size, const char *format, ...) __PRINTF(3, 4);
00276 
00277 
00282     string(const char *text);
00283 
00290     string(const char *text, strsize_t size);
00291 
00298     string(const char *text, const char *end);
00299 
00305     string(const string& existing);
00306 
00311     virtual ~string();
00312 
00319     string get(strsize_t offset, strsize_t size = 0) const;
00320 
00326     int scanf(const char *format, ...) __SCANF(2, 3);
00327 
00334     int vscanf(const char *format, va_list args) __SCANF(2, 0);
00335 
00341     strsize_t printf(const char *format, ...) __PRINTF(2, 3);
00342 
00349     strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
00350 
00355     char *c_mem(void) const;
00356 
00361     const char *c_str(void) const;
00362 
00368     virtual bool resize(strsize_t size);
00369 
00374     void set(const char *text);
00375 
00383     void set(strsize_t offset, const char *text, strsize_t size = 0);
00384 
00392     void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00393 
00401     void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00402 
00407     void add(const char *text);
00408 
00413     void add(char character);
00414 
00419     void trim(const char *list);
00420 
00425     void chop(const char *list);
00426 
00431     void strip(const char *list);
00432 
00438     bool unquote(const char *quote);
00439 
00445     void cut(strsize_t offset, strsize_t size = 0);
00446 
00452     void clear(strsize_t offset, strsize_t size = 0);
00453 
00457     void clear(void);
00458 
00462     void upper(void);
00463 
00467     void lower(void);
00468 
00474     strsize_t ccount(const char *list) const;
00475 
00480     strsize_t count(void) const;
00481 
00486     strsize_t size(void) const;
00487 
00497     strsize_t offset(const char *pointer) const;
00498 
00504     char at(int position) const;
00505 
00511     const char *last(const char *list) const;
00512 
00518     const char *first(const char *list) const;
00519 
00524     const char *begin(void) const;
00525 
00530     const char *end(void) const;
00531 
00538     const char *skip(const char *list, strsize_t offset = 0) const;
00539 
00547     const char *rskip(const char *list, strsize_t offset = npos) const;
00548 
00555     const char *find(const char *list, strsize_t offset = 0) const;
00556 
00563     const char *rfind(const char *list, strsize_t offset = npos) const;
00564 
00570     void split(const char *pointer);
00571 
00577     void split(strsize_t offset);
00578 
00584     void rsplit(const char *pointer);
00585 
00591     void rsplit(strsize_t offset);
00592 
00598     const char *chr(char character) const;
00599 
00606     const char *rchr(char character) const;
00607 
00612     strsize_t len(void);
00613 
00618     char fill(void);
00619 
00624     inline operator const char *() const
00625         {return c_str();};
00626 
00631     inline const char *operator*() const
00632         {return c_str();};
00633 
00638     bool full(void) const;
00639 
00646     string operator()(int offset, strsize_t size) const;
00647 
00655     const char *operator()(int offset) const;
00656 
00662     const char operator[](int offset) const;
00663 
00668     bool operator!() const;
00669 
00674     operator bool() const;
00675 
00681     string& operator^=(const string& object);
00682 
00688     string& operator^=(const char *text);
00689 
00695     string& operator+(const char *text);
00696 
00703     string& operator&(const char *text);
00704 
00711     string& operator=(const string& object);
00712 
00717     string& operator=(const char *text);
00718 
00722     string& operator++(void);
00723 
00728     string& operator+=(strsize_t number);
00729 
00733     string& operator--(void);
00734 
00739     string& operator-=(strsize_t number);
00740 
00746     bool operator==(const char *text) const;
00747 
00753     bool operator!=(const char *text) const;
00754 
00760     bool operator<(const char *text) const;
00761 
00767     bool operator<=(const char *text) const;
00768 
00774     bool operator>(const char *text) const;
00775 
00781     bool operator>=(const char *text) const;
00782 
00788     string &operator%(short& value);
00789 
00795     string &operator%(unsigned short& value);
00796 
00802     string &operator%(long& value);
00803 
00809     string &operator%(unsigned long& value);
00810 
00816     string &operator%(double& value);
00817 
00823     string &operator%(const char *text);
00824 
00831     static int scanf(string& object, const char *format, ...) __SCANF(2, 3);
00832 
00833 
00840     static strsize_t printf(string& object, const char *format, ...) __PRINTF(2, 3);
00841 
00847     static void swap(string& object1, string& object2);
00848     
00853     static void fix(string& object);
00854 
00859     static void lower(char *text);
00860     
00865     static void upper(char *text);
00866 
00880     static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
00881 
00888     static char *skip(char *text, const char *list);
00889 
00896     static char *rskip(char *text, const char *list);
00897 
00905     static char *unquote(char *text, const char *quote);
00906 
00914     static char *rset(char *buffer, size_t size, const char *text);
00915     
00924     static char *set(char *buffer, size_t size, const char *text);
00925     
00935     static char *set(char *buffer, size_t size, const char *text, size_t max);
00936 
00946     static char *add(char *buffer, size_t size, const char *text); 
00947 
00958     static char *add(char *buffer, size_t size, const char *text, size_t max);
00959     
00967     static const char *ifind(const char *text, const char *key, const char *optional);
00968 
00976     static const char *find(const char *text, const char *key, const char *optional);
00977 
00983     static size_t count(const char *text);
00984 
00991     static int compare(const char *text1, const char *text2);
00992 
00999     static bool equal(const char *text1, const char *text2);
01000 
01008     static int compare(const char *text1, const char *text2, size_t size);
01009 
01017     static bool equal(const char *text1, const char *text2, size_t size);
01018 
01025     static int case_compare(const char *text1, const char *text2);
01026 
01033     static bool case_equal(const char *text1, const char *text2);
01034 
01042     static int case_compare(const char *text1, const char *text2, size_t size);
01043 
01051     static bool case_equal(const char *text1, const char *text2, size_t size);
01052 
01060     static char *trim(char *text, const char *list); 
01061 
01069     static char *chop(char *text, const char *list); 
01070 
01078     static char *strip(char *text, const char *list);
01079 
01088     static char *fill(char *text, size_t size, char character);
01089 
01096     static unsigned ccount(const char *text, const char *list);
01097 
01104     static char *find(char *text, const char *list);
01105 
01112     static char *rfind(char *text, const char *list);
01113 
01120     static char *first(char *text, const char *list);
01121 
01128     static char *last(char *text, const char *list);
01129 
01135     static char *dup(const char *text);
01136 
01150     inline static char *token(string& object, char **last, const char *list, const char *quote = NULL, const char *end = NULL)
01151         {return token(object.c_mem(), last, list, quote, end);};
01152 
01160     __SCANF(2,0) inline static int vscanf(string& object, const char *format, va_list args)
01161         {return object.vscanf(format, args);}
01162 
01170     __PRINTF(2,0) inline static strsize_t vprintf(string& object, const char *format, va_list args)
01171         {return object.vprintf(format, args);}
01172 
01178     inline static strsize_t len(string& object)
01179         {return object.len();};
01180 
01186     inline static char *mem(string& object)
01187         {return object.c_mem();};
01188 
01194     inline static strsize_t size(string& object)
01195         {return object.size();};
01196 
01201     inline static void clear(string& object)
01202         {object.clear();};
01203 
01210     inline static unsigned ccount(string& object, const char *list)
01211         {return object.ccount(list);};
01212 
01218     inline static size_t count(string& object)
01219         {return object.count();};
01220 
01225     inline static void upper(string& object)
01226         {object.upper();};
01227 
01232     inline static void lower(string& object)
01233         {object.lower();};
01234 
01241     inline static bool unquote(string& object, const char *quote)
01242         {return object.unquote(quote);};
01243 
01249     inline static void trim(string& object, const char *list)
01250         {object.trim(list);};
01251 
01257     inline static void chop(string& object, const char *list)
01258         {object.trim(list);};
01259 
01265     inline static void strip(string& object, const char *list)
01266         {object.trim(list);};
01267 
01274     inline static const char *find(string& object, const char *list)
01275         {return object.find(list);};
01276 
01283     inline static const char *rfind(string& object, const char *list)
01284         {return object.rfind(list);};
01285 
01292     inline static const char *first(string& object, const char *list)
01293         {return object.first(list);};
01294 
01301     inline static const char *last(string& object, const char *list)
01302         {return object.last(list);};
01303 
01310     inline static double tod(string& object, char **pointer = NULL)
01311         {return strtod(mem(object), pointer);};
01312 
01319     inline static long tol(string& object, char **pointer = NULL)
01320         {return strtol(mem(object), 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 
01347     static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
01348 
01356     static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
01357 
01358     static unsigned hexsize(const char *format);
01359 };
01360 
01368 class __EXPORT memstring : public string
01369 {
01370 public:
01371     static const size_t header;
01372 
01373 private:
01374     bool resize(strsize_t size);
01375     void cow(strsize_t adj = 0);
01376     void release(void);
01377 
01378 protected:
01379     cstring *c_copy(void) const;
01380 
01381 public:
01386     inline void operator=(string& object)
01387         {set(object.c_str());};
01388 
01393     inline void operator=(const char *text)
01394         {set(text);};
01395 
01402     memstring(void *memory, strsize_t size, char fill = 0);
01403 
01407     ~memstring();
01408 
01414     static memstring *create(strsize_t size, char fill = 0);
01415 
01422     static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
01423 };
01424 
01432 template<size_t S>
01433 class charbuf
01434 {
01435 private:
01436     char buffer[S];
01437 
01438 public:
01442     inline charbuf() 
01443         {buffer[0] = 0;};
01444 
01450     inline charbuf(const char *text) 
01451         {string::set(buffer, S, text);};
01452 
01457     inline void operator=(const char *text)
01458         {string::set(buffer, S, text);};
01459 
01465     inline void operator+=(const char *text)
01466         {string::add(buffer, S, text);};
01467 
01472     inline operator bool() const
01473         {return buffer[0];};
01474 
01479     inline bool operator!() const
01480         {return buffer[0] == 0;};   
01481 
01486     inline operator char *()
01487         {return buffer;};
01488 
01493     inline char *operator*()
01494         {return buffer;};
01495 
01501     inline char operator[](size_t offset) const
01502         {return buffer[offset];};
01503 
01509     inline char *operator()(size_t offset)
01510         {return buffer + offset;};
01511 
01516     inline size_t size(void) const
01517         {return S;};
01518 };
01519 
01523 typedef string string_t;
01524 
01529 typedef string String;
01530 
01541 template<strsize_t S>
01542 class stringbuf : public memstring
01543 {
01544 private:
01545     char buffer[sizeof(cstring) + S];
01546     
01547 public:
01551     inline stringbuf() : memstring(buffer, S) {};
01552 
01557     inline stringbuf(const char *text) : memstring(buffer, S) {set(text);};
01558 
01563     inline void operator=(const char *text)
01564         {set(text);};
01565 
01570     inline void operator=(string& object)
01571         {set(object.c_str());}; 
01572 };
01573 
01574 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
01575 
01582 extern "C" inline int stricmp(const char *string1, const char *string2)
01583     {return string::case_compare(string1, string2);}
01584 
01592 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max)
01593     {return string::case_compare(string1, string2, max);}
01594 
01595 #endif
01596 
01603 inline bool eq(char const *s1, char const *s2)
01604     {return String::equal(s1, s2);}
01605 
01613 inline bool eq(char const *s1, char const *s2, size_t size)
01614     {return String::equal(s1, s2, size);}
01615 
01622 inline bool eq(String &s1, String &s2)
01623     {return String::equal(s1.c_str(), s2.c_str());}
01624 
01632 inline bool ieq(char const *s1, char const *s2)
01633     {return String::case_equal(s1, s2);}
01634 
01643 inline bool ieq(char const *s1, char const *s2, size_t size)
01644     {return String::case_equal(s1, s2, size);}
01645 
01653 inline bool ieq(String &s1, String &s2)
01654     {return String::case_equal(s1.c_str(), s2.c_str());}
01655 
01656 inline String str(const char *string)
01657     {return (String)string;}
01658 
01659 inline String str(String& string)
01660     {return (String)string;}
01661 
01662 inline String str(short value)
01663     {String temp(16, "%hd", value); return temp;}
01664 
01665 inline String str(unsigned short value)
01666     {String temp(16, "%hu", value); return temp;}
01667 
01668 inline String str(long value)
01669     {String temp(32, "%ld", value); return temp;}
01670 
01671 inline String str(unsigned long value)
01672     {String temp(32, "%lu", value); return temp;}
01673 
01674 inline String str(double value)
01675     {String temp(40, "%f", value); return temp;} 
01676 
01677 String str(CharacterProtocol& cp, strsize_t size);
01678 
01679 END_NAMESPACE
01680 
01681 #endif