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 00838 00845 static strsize_t printf(string& object, const char *format, ...) __PRINTF(2, 3); 00846 00852 static void swap(string& object1, string& object2); 00853 00858 static void fix(string& object); 00859 00864 static void lower(char *text); 00865 00870 static void upper(char *text); 00871 00885 static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL); 00886 00893 static char *skip(char *text, const char *list); 00894 00901 static char *rskip(char *text, const char *list); 00902 00910 static char *unquote(char *text, const char *quote); 00911 00919 static char *rset(char *buffer, size_t size, const char *text); 00920 00929 static char *set(char *buffer, size_t size, const char *text); 00930 00940 static char *set(char *buffer, size_t size, const char *text, size_t max); 00941 00951 static char *add(char *buffer, size_t size, const char *text); 00952 00963 static char *add(char *buffer, size_t size, const char *text, size_t max); 00964 00972 static const char *ifind(const char *text, const char *key, const char *optional); 00973 00981 static const char *find(const char *text, const char *key, const char *optional); 00982 00988 static size_t count(const char *text); 00989 00996 static int compare(const char *text1, const char *text2); 00997 01004 static bool equal(const char *text1, const char *text2); 01005 01013 static int compare(const char *text1, const char *text2, size_t size); 01014 01022 static bool equal(const char *text1, const char *text2, size_t size); 01023 01030 static int case_compare(const char *text1, const char *text2); 01031 01038 static bool case_equal(const char *text1, const char *text2); 01039 01047 static int case_compare(const char *text1, const char *text2, size_t size); 01048 01056 static bool case_equal(const char *text1, const char *text2, size_t size); 01057 01065 static char *trim(char *text, const char *list); 01066 01074 static char *chop(char *text, const char *list); 01075 01083 static char *strip(char *text, const char *list); 01084 01093 static char *fill(char *text, size_t size, char character); 01094 01101 static unsigned ccount(const char *text, const char *list); 01102 01109 static char *find(char *text, const char *list); 01110 01117 static char *rfind(char *text, const char *list); 01118 01125 static char *first(char *text, const char *list); 01126 01133 static char *last(char *text, const char *list); 01134 01140 static char *dup(const char *text); 01141 01155 inline static char *token(string& object, char **last, const char *list, const char *quote = NULL, const char *end = NULL) 01156 {return token(object.c_mem(), last, list, quote, end);}; 01157 01165 __SCANF(2,0) inline static int vscanf(string& object, const char *format, va_list args) 01166 {return object.vscanf(format, args);} 01167 01175 __PRINTF(2,0) inline static strsize_t vprintf(string& object, const char *format, va_list args) 01176 {return object.vprintf(format, args);} 01177 01183 inline static strsize_t len(string& object) 01184 {return object.len();}; 01185 01191 inline static char *mem(string& object) 01192 {return object.c_mem();}; 01193 01199 inline static strsize_t size(string& object) 01200 {return object.size();}; 01201 01206 inline static void clear(string& object) 01207 {object.clear();}; 01208 01215 inline static unsigned ccount(string& object, const char *list) 01216 {return object.ccount(list);}; 01217 01223 inline static size_t count(string& object) 01224 {return object.count();}; 01225 01230 inline static void upper(string& object) 01231 {object.upper();}; 01232 01237 inline static void lower(string& object) 01238 {object.lower();}; 01239 01246 inline static bool unquote(string& object, const char *quote) 01247 {return object.unquote(quote);}; 01248 01254 inline static void trim(string& object, const char *list) 01255 {object.trim(list);}; 01256 01262 inline static void chop(string& object, const char *list) 01263 {object.trim(list);}; 01264 01270 inline static void strip(string& object, const char *list) 01271 {object.trim(list);}; 01272 01279 inline static const char *find(string& object, const char *list) 01280 {return object.find(list);}; 01281 01288 inline static const char *rfind(string& object, const char *list) 01289 {return object.rfind(list);}; 01290 01297 inline static const char *first(string& object, const char *list) 01298 {return object.first(list);}; 01299 01306 inline static const char *last(string& object, const char *list) 01307 {return object.last(list);}; 01308 01315 inline static double tod(string& object, char **pointer = NULL) 01316 {return strtod(mem(object), pointer);}; 01317 01324 inline static long tol(string& object, char **pointer = NULL) 01325 {return strtol(mem(object), pointer, 0);}; 01326 01333 inline static double tod(const char *text, char **pointer = NULL) 01334 {return strtod(text, pointer);}; 01335 01342 inline static long tol(const char *text, char **pointer = NULL) 01343 {return strtol(text, pointer, 0);}; 01344 01352 static unsigned hexdump(const unsigned char *binary, char *string, const char *format); 01353 01361 static unsigned hexpack(unsigned char *binary, const char *string, const char *format); 01362 01363 static unsigned hexsize(const char *format); 01364 }; 01365 01373 class __EXPORT memstring : public string 01374 { 01375 public: 01376 #if _MSC_VER > 1400 // windows broken dll linkage issue... 01377 const static size_t header = sizeof(string::cstring); 01378 #else 01379 static const size_t header; 01380 #endif 01381 01382 private: 01383 bool resize(strsize_t size); 01384 void cow(strsize_t adj = 0); 01385 void release(void); 01386 01387 protected: 01388 cstring *c_copy(void) const; 01389 01390 public: 01395 inline void operator=(string& object) 01396 {set(object.c_str());}; 01397 01402 inline void operator=(const char *text) 01403 {set(text);}; 01404 01411 memstring(void *memory, strsize_t size, char fill = 0); 01412 01416 ~memstring(); 01417 01423 static memstring *create(strsize_t size, char fill = 0); 01424 01431 static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0); 01432 }; 01433 01441 template<size_t S> 01442 class charbuf 01443 { 01444 private: 01445 char buffer[S]; 01446 01447 public: 01451 inline charbuf() 01452 {buffer[0] = 0;}; 01453 01459 inline charbuf(const char *text) 01460 {string::set(buffer, S, text);}; 01461 01466 inline void operator=(const char *text) 01467 {string::set(buffer, S, text);}; 01468 01474 inline void operator+=(const char *text) 01475 {string::add(buffer, S, text);}; 01476 01481 inline operator bool() const 01482 {return buffer[0];}; 01483 01488 inline bool operator!() const 01489 {return buffer[0] == 0;}; 01490 01495 inline operator char *() 01496 {return buffer;}; 01497 01502 inline char *operator*() 01503 {return buffer;}; 01504 01510 inline char operator[](size_t offset) const 01511 {return buffer[offset];}; 01512 01518 inline char *operator()(size_t offset) 01519 {return buffer + offset;}; 01520 01525 inline size_t size(void) const 01526 {return S;}; 01527 }; 01528 01532 typedef string string_t; 01533 01538 typedef string String; 01539 01550 template<strsize_t S> 01551 class stringbuf : public memstring 01552 { 01553 private: 01554 char buffer[sizeof(cstring) + S]; 01555 01556 public: 01560 inline stringbuf() : memstring(buffer, S) {}; 01561 01566 inline stringbuf(const char *text) : memstring(buffer, S) {set(text);}; 01567 01572 inline void operator=(const char *text) 01573 {set(text);}; 01574 01579 inline void operator=(string& object) 01580 {set(object.c_str());}; 01581 }; 01582 01583 #if !defined(_MSWINDOWS_) && !defined(__QNX__) 01584 01591 extern "C" inline int stricmp(const char *string1, const char *string2) 01592 {return string::case_compare(string1, string2);} 01593 01601 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max) 01602 {return string::case_compare(string1, string2, max);} 01603 01604 #endif 01605 01612 inline bool eq(char const *s1, char const *s2) 01613 {return String::equal(s1, s2);} 01614 01622 inline bool eq(char const *s1, char const *s2, size_t size) 01623 {return String::equal(s1, s2, size);} 01624 01631 inline bool eq(String &s1, String &s2) 01632 {return String::equal(s1.c_str(), s2.c_str());} 01633 01641 inline bool ieq(char const *s1, char const *s2) 01642 {return String::case_equal(s1, s2);} 01643 01652 inline bool ieq(char const *s1, char const *s2, size_t size) 01653 {return String::case_equal(s1, s2, size);} 01654 01662 inline bool ieq(String &s1, String &s2) 01663 {return String::case_equal(s1.c_str(), s2.c_str());} 01664 01665 inline String str(const char *string) 01666 {return (String)string;} 01667 01668 inline String str(String& string) 01669 {return (String)string;} 01670 01671 inline String str(short value) 01672 {String temp(16, "%hd", value); return temp;} 01673 01674 inline String str(unsigned short value) 01675 {String temp(16, "%hu", value); return temp;} 01676 01677 inline String str(long value) 01678 {String temp(32, "%ld", value); return temp;} 01679 01680 inline String str(unsigned long value) 01681 {String temp(32, "%lu", value); return temp;} 01682 01683 inline String str(double value) 01684 {String temp(40, "%f", value); return temp;} 01685 01686 String str(CharacterProtocol& cp, strsize_t size); 01687 01688 END_NAMESPACE 01689 01690 #endif