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_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 #if _MSC_VER > 1400 // windows broken dll linkage issue... 00237 const static strsize_t npos = ((strsize_t)-1); 00238 #else 00239 static const strsize_t npos; 00240 #endif 00241 00242 00246 string(); 00247 00252 string(long value); 00253 00258 string(double value); 00259 00264 string(strsize_t size); 00265 00271 string(strsize_t size, char fill); 00272 00280 string(strsize_t size, const char *format, ...) __PRINTF(3, 4); 00281 00282 00287 string(const char *text); 00288 00295 string(const char *text, strsize_t size); 00296 00303 string(const char *text, const char *end); 00304 00310 string(const string& existing); 00311 00316 virtual ~string(); 00317 00324 string get(strsize_t offset, strsize_t size = 0) const; 00325 00331 int scanf(const char *format, ...) __SCANF(2, 3); 00332 00339 int vscanf(const char *format, va_list args) __SCANF(2, 0); 00340 00346 strsize_t printf(const char *format, ...) __PRINTF(2, 3); 00347 00354 strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0); 00355 00360 char *c_mem(void) const; 00361 00366 const char *c_str(void) const; 00367 00373 virtual bool resize(strsize_t size); 00374 00379 void set(const char *text); 00380 00388 void set(strsize_t offset, const char *text, strsize_t size = 0); 00389 00397 void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0); 00398 00406 void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0); 00407 00412 void add(const char *text); 00413 00418 void add(char character); 00419 00424 void trim(const char *list); 00425 00430 void chop(const char *list); 00431 00436 void strip(const char *list); 00437 00443 bool unquote(const char *quote); 00444 00450 void cut(strsize_t offset, strsize_t size = 0); 00451 00457 void clear(strsize_t offset, strsize_t size = 0); 00458 00462 void clear(void); 00463 00467 void upper(void); 00468 00472 void lower(void); 00473 00479 strsize_t ccount(const char *list) const; 00480 00485 strsize_t count(void) const; 00486 00491 strsize_t size(void) const; 00492 00502 strsize_t offset(const char *pointer) const; 00503 00509 char at(int position) const; 00510 00516 const char *last(const char *list) const; 00517 00523 const char *first(const char *list) const; 00524 00529 const char *begin(void) const; 00530 00535 const char *end(void) const; 00536 00543 const char *skip(const char *list, strsize_t offset = 0) const; 00544 00552 const char *rskip(const char *list, strsize_t offset = npos) const; 00553 00560 const char *find(const char *list, strsize_t offset = 0) const; 00561 00568 const char *rfind(const char *list, strsize_t offset = npos) const; 00569 00575 void split(const char *pointer); 00576 00582 void split(strsize_t offset); 00583 00589 void rsplit(const char *pointer); 00590 00596 void rsplit(strsize_t offset); 00597 00603 const char *chr(char character) const; 00604 00611 const char *rchr(char character) const; 00612 00617 strsize_t len(void); 00618 00623 char fill(void); 00624 00629 inline operator const char *() const 00630 {return c_str();}; 00631 00636 inline const char *operator*() const 00637 {return c_str();}; 00638 00643 bool full(void) const; 00644 00651 string operator()(int offset, strsize_t size) const; 00652 00660 const char *operator()(int offset) const; 00661 00667 const char operator[](int offset) const; 00668 00673 bool operator!() const; 00674 00679 operator bool() const; 00680 00686 string& operator^=(const string& object); 00687 00693 string& operator^=(const char *text); 00694 00700 string& operator+(const char *text); 00701 00708 string& operator&(const char *text); 00709 00716 string& operator=(const string& object); 00717 00722 string& operator=(const char *text); 00723 00727 string& operator++(void); 00728 00733 string& operator+=(strsize_t number); 00734 00738 string& operator--(void); 00739 00744 string& operator-=(strsize_t number); 00745 00751 bool operator==(const char *text) const; 00752 00758 bool operator!=(const char *text) const; 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 string &operator%(short& value); 00794 00800 string &operator%(unsigned short& value); 00801 00807 string &operator%(long& value); 00808 00814 string &operator%(unsigned long& value); 00815 00821 string &operator%(double& value); 00822 00828 string &operator%(const char *text); 00829 00836 static int scanf(string& object, const char *format, ...) __SCANF(2, 3); 00837 00844 static strsize_t printf(string& object, const char *format, ...) __PRINTF(2, 3); 00845 00851 static void swap(string& object1, string& object2); 00852 00857 static void fix(string& object); 00858 00863 static void lower(char *text); 00864 00869 static void upper(char *text); 00870 00884 static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL); 00885 00892 static char *skip(char *text, const char *list); 00893 00900 static char *rskip(char *text, const char *list); 00901 00909 static char *unquote(char *text, const char *quote); 00910 00918 static char *rset(char *buffer, size_t size, const char *text); 00919 00928 static char *set(char *buffer, size_t size, const char *text); 00929 00939 static char *set(char *buffer, size_t size, const char *text, size_t max); 00940 00950 static char *add(char *buffer, size_t size, const char *text); 00951 00962 static char *add(char *buffer, size_t size, const char *text, size_t max); 00963 00971 static const char *ifind(const char *text, const char *key, const char *optional); 00972 00980 static const char *find(const char *text, const char *key, const char *optional); 00981 00987 static size_t count(const char *text); 00988 00995 static int compare(const char *text1, const char *text2); 00996 01003 static bool equal(const char *text1, const char *text2); 01004 01012 static int compare(const char *text1, const char *text2, size_t size); 01013 01021 static bool equal(const char *text1, const char *text2, size_t size); 01022 01029 static int case_compare(const char *text1, const char *text2); 01030 01037 static bool case_equal(const char *text1, const char *text2); 01038 01046 static int case_compare(const char *text1, const char *text2, size_t size); 01047 01055 static bool case_equal(const char *text1, const char *text2, size_t size); 01056 01064 static char *trim(char *text, const char *list); 01065 01073 static char *chop(char *text, const char *list); 01074 01082 static char *strip(char *text, const char *list); 01083 01092 static char *fill(char *text, size_t size, char character); 01093 01100 static unsigned ccount(const char *text, const char *list); 01101 01108 static char *find(char *text, const char *list); 01109 01116 static char *rfind(char *text, const char *list); 01117 01124 static char *first(char *text, const char *list); 01125 01132 static char *last(char *text, const char *list); 01133 01139 static char *dup(const char *text); 01140 01154 inline static char *token(string& object, char **last, const char *list, const char *quote = NULL, const char *end = NULL) 01155 {return token(object.c_mem(), last, list, quote, end);}; 01156 01164 __SCANF(2,0) inline static int vscanf(string& object, const char *format, va_list args) 01165 {return object.vscanf(format, args);} 01166 01174 __PRINTF(2,0) inline static strsize_t vprintf(string& object, const char *format, va_list args) 01175 {return object.vprintf(format, args);} 01176 01182 inline static strsize_t len(string& object) 01183 {return object.len();}; 01184 01190 inline static char *mem(string& object) 01191 {return object.c_mem();}; 01192 01198 inline static strsize_t size(string& object) 01199 {return object.size();}; 01200 01205 inline static void clear(string& object) 01206 {object.clear();}; 01207 01214 inline static unsigned ccount(string& object, const char *list) 01215 {return object.ccount(list);}; 01216 01222 inline static size_t count(string& object) 01223 {return object.count();}; 01224 01229 inline static void upper(string& object) 01230 {object.upper();}; 01231 01236 inline static void lower(string& object) 01237 {object.lower();}; 01238 01245 inline static bool unquote(string& object, const char *quote) 01246 {return object.unquote(quote);}; 01247 01253 inline static void trim(string& object, const char *list) 01254 {object.trim(list);}; 01255 01261 inline static void chop(string& object, const char *list) 01262 {object.trim(list);}; 01263 01269 inline static void strip(string& object, const char *list) 01270 {object.trim(list);}; 01271 01278 inline static const char *find(string& object, const char *list) 01279 {return object.find(list);}; 01280 01287 inline static const char *rfind(string& object, const char *list) 01288 {return object.rfind(list);}; 01289 01296 inline static const char *first(string& object, const char *list) 01297 {return object.first(list);}; 01298 01305 inline static const char *last(string& object, const char *list) 01306 {return object.last(list);}; 01307 01314 inline static double tod(string& object, char **pointer = NULL) 01315 {return strtod(mem(object), pointer);}; 01316 01323 inline static long tol(string& object, char **pointer = NULL) 01324 {return strtol(mem(object), pointer, 0);}; 01325 01332 inline static double tod(const char *text, char **pointer = NULL) 01333 {return strtod(text, pointer);}; 01334 01341 inline static long tol(const char *text, char **pointer = NULL) 01342 {return strtol(text, pointer, 0);}; 01343 01351 static unsigned hexdump(const unsigned char *binary, char *string, const char *format); 01352 01360 static unsigned hexpack(unsigned char *binary, const char *string, const char *format); 01361 01362 static unsigned hexsize(const char *format); 01363 }; 01364 01372 class __EXPORT memstring : public string 01373 { 01374 public: 01375 #if _MSC_VER > 1400 // windows broken dll linkage issue... 01376 const static size_t header = sizeof(string::cstring); 01377 #else 01378 static const size_t header; 01379 #endif 01380 01381 private: 01382 bool resize(strsize_t size); 01383 void cow(strsize_t adj = 0); 01384 void release(void); 01385 01386 protected: 01387 cstring *c_copy(void) const; 01388 01389 public: 01394 inline void operator=(string& object) 01395 {set(object.c_str());}; 01396 01401 inline void operator=(const char *text) 01402 {set(text);}; 01403 01410 memstring(void *memory, strsize_t size, char fill = 0); 01411 01415 ~memstring(); 01416 01422 static memstring *create(strsize_t size, char fill = 0); 01423 01430 static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0); 01431 }; 01432 01440 template<size_t S> 01441 class charbuf 01442 { 01443 private: 01444 char buffer[S]; 01445 01446 public: 01450 inline charbuf() 01451 {buffer[0] = 0;}; 01452 01458 inline charbuf(const char *text) 01459 {string::set(buffer, S, text);}; 01460 01465 inline void operator=(const char *text) 01466 {string::set(buffer, S, text);}; 01467 01473 inline void operator+=(const char *text) 01474 {string::add(buffer, S, text);}; 01475 01480 inline operator bool() const 01481 {return buffer[0];}; 01482 01487 inline bool operator!() const 01488 {return buffer[0] == 0;}; 01489 01494 inline operator char *() 01495 {return buffer;}; 01496 01501 inline char *operator*() 01502 {return buffer;}; 01503 01509 inline char operator[](size_t offset) const 01510 {return buffer[offset];}; 01511 01517 inline char *operator()(size_t offset) 01518 {return buffer + offset;}; 01519 01524 inline size_t size(void) const 01525 {return S;}; 01526 }; 01527 01531 typedef string string_t; 01532 01537 typedef string String; 01538 01549 template<strsize_t S> 01550 class stringbuf : public memstring 01551 { 01552 private: 01553 char buffer[sizeof(cstring) + S]; 01554 01555 public: 01559 inline stringbuf() : memstring(buffer, S) {}; 01560 01565 inline stringbuf(const char *text) : memstring(buffer, S) {set(text);}; 01566 01571 inline void operator=(const char *text) 01572 {set(text);}; 01573 01578 inline void operator=(string& object) 01579 {set(object.c_str());}; 01580 }; 01581 01582 #if !defined(_MSWINDOWS_) && !defined(__QNX__) 01583 01590 extern "C" inline int stricmp(const char *string1, const char *string2) 01591 {return string::case_compare(string1, string2);} 01592 01600 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max) 01601 {return string::case_compare(string1, string2, max);} 01602 01603 #endif 01604 01611 inline bool eq(char const *s1, char const *s2) 01612 {return String::equal(s1, s2);} 01613 01621 inline bool eq(char const *s1, char const *s2, size_t size) 01622 {return String::equal(s1, s2, size);} 01623 01630 inline bool eq(String &s1, String &s2) 01631 {return String::equal(s1.c_str(), s2.c_str());} 01632 01640 inline bool ieq(char const *s1, char const *s2) 01641 {return String::case_equal(s1, s2);} 01642 01651 inline bool ieq(char const *s1, char const *s2, size_t size) 01652 {return String::case_equal(s1, s2, size);} 01653 01661 inline bool ieq(String &s1, String &s2) 01662 {return String::case_equal(s1.c_str(), s2.c_str());} 01663 01664 inline String str(const char *string) 01665 {return (String)string;} 01666 01667 inline String str(String& string) 01668 {return (String)string;} 01669 01670 inline String str(short value) 01671 {String temp(16, "%hd", value); return temp;} 01672 01673 inline String str(unsigned short value) 01674 {String temp(16, "%hu", value); return temp;} 01675 01676 inline String str(long value) 01677 {String temp(32, "%ld", value); return temp;} 01678 01679 inline String str(unsigned long value) 01680 {String temp(32, "%lu", value); return temp;} 01681 01682 inline String str(double value) 01683 {String temp(40, "%f", value); return temp;} 01684 01685 String str(CharacterProtocol& cp, strsize_t size); 01686 01687 END_NAMESPACE 01688 01689 #endif