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