UCommon
|
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_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