ucommon
|
00001 // Copyright (C) 2006-2014 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 enum { 00098 SENSITIVE = 0x00, 00099 INSENSITIVE = 0x01 00100 }; 00101 00102 class __EXPORT regex 00103 { 00104 private: 00105 void *object; 00106 void *results; 00107 size_t count; 00108 00109 public: 00110 regex(const char *pattern, size_t size = 1); 00111 regex(size_t size = 1); 00112 ~regex(); 00113 00114 size_t offset(unsigned member); 00115 size_t size(unsigned member); 00116 00117 inline size_t members(void) 00118 {return count;} 00119 00120 bool match(const char *text, unsigned flags = 0); 00121 00122 regex& operator=(const char *string); 00123 00124 bool operator*=(const char *string); 00125 00126 operator bool() 00127 {return object != NULL;} 00128 00129 bool operator!() 00130 {return object == NULL;} 00131 }; 00132 00133 class __EXPORT cstring : public CountedObject 00134 { 00135 public: 00136 #pragma pack(1) 00137 strsize_t max; 00138 strsize_t len; 00139 char fill; 00140 char text[1]; 00141 #pragma pack() 00142 00148 cstring(strsize_t size); 00149 00157 cstring(strsize_t size, char fill); 00158 00166 void clear(strsize_t offset, strsize_t size); 00167 00174 void set(strsize_t offset, const char *text, strsize_t size); 00175 00180 void set(const char *text); 00181 00186 void add(const char *text); 00187 00192 void add(char character); 00193 00197 void fix(void); 00198 00203 void unfix(void); 00204 00210 void inc(strsize_t number); 00211 00217 void dec(strsize_t number); 00218 }; 00219 00220 protected: 00221 cstring *str; 00229 cstring *create(strsize_t size, char fill = 0) const; 00230 00231 public: 00239 virtual int compare(const char *string) const; 00240 00241 inline int collate(const char *string) const 00242 {return compare(string);} 00243 00244 protected: 00250 bool equal(const char *string) const; 00251 00256 virtual void retain(void); 00257 00262 virtual void release(void); 00263 00268 virtual cstring *c_copy(void) const; 00269 00276 virtual void cow(strsize_t size = 0); 00277 00278 strsize_t getStringSize(void); 00279 00280 public: 00284 #if _MSC_VER > 1400 // windows broken dll linkage issue... 00285 const static strsize_t npos = ((strsize_t)-1); 00286 #else 00287 static const strsize_t npos; 00288 #endif 00289 00290 00294 String(); 00295 00300 String(long value); 00301 00306 String(double value); 00307 00312 String(strsize_t size); 00313 00319 String(strsize_t size, char fill); 00320 00328 String(strsize_t size, const char *format, ...) __PRINTF(3, 4); 00329 00330 00335 String(const char *text); 00336 00343 String(const char *text, strsize_t size); 00344 00351 String(const char *text, const char *end); 00352 00358 String(const String& existing); 00359 00364 virtual ~String(); 00365 00372 String get(strsize_t offset, strsize_t size = 0) const; 00373 00379 int scanf(const char *format, ...) __SCANF(2, 3); 00380 00387 int vscanf(const char *format, va_list args) __SCANF(2, 0); 00388 00394 strsize_t printf(const char *format, ...) __PRINTF(2, 3); 00395 00402 strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0); 00403 00408 char *c_mem(void) const; 00409 00414 const char *c_str(void) const; 00415 00421 virtual bool resize(strsize_t size); 00422 00427 void set(const char *text); 00428 00436 void set(strsize_t offset, const char *text, strsize_t size = 0); 00437 00445 void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0); 00446 00454 void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0); 00455 00460 void add(const char *text); 00461 00466 void add(char character); 00467 00472 void trim(const char *list); 00473 00478 inline void trim(strsize_t count = 1) 00479 {operator+=(count);} 00480 00485 void chop(const char *list); 00486 00491 inline void chop(strsize_t count = 1) 00492 {operator-=(count);} 00493 00498 void strip(const char *list); 00499 00505 bool unquote(const char *quote); 00506 00512 void cut(strsize_t offset, strsize_t size = 0); 00513 00520 void paste(strsize_t offset, const char *text, strsize_t size = 0); 00521 00527 void clear(strsize_t offset, strsize_t size = 0); 00528 00532 void clear(void); 00533 00537 void upper(void); 00538 00542 void lower(void); 00543 00547 void erase(void); 00548 00554 strsize_t ccount(const char *list) const; 00555 00560 strsize_t count(void) const; 00561 00566 strsize_t size(void) const; 00567 00577 strsize_t offset(const char *pointer) const; 00578 00584 char at(int position) const; 00585 00590 const char *begin(void) const; 00591 00596 const char *end(void) const; 00597 00604 const char *skip(const char *list, strsize_t offset = 0) const; 00605 00613 const char *rskip(const char *list, strsize_t offset = npos) const; 00614 00620 const char *search(const char *string, unsigned instance = 0, unsigned flags = 0) const; 00621 00622 const char *search(regex& expr, unsigned instance = 0, unsigned flags = 0) const; 00623 00624 unsigned replace(const char *string, const char *text = NULL, unsigned flags = 0); 00625 00626 unsigned replace(regex& expr, const char *text = NULL, unsigned flags = 0); 00627 00634 const char *find(const char *list, strsize_t offset = 0) const; 00635 00642 const char *rfind(const char *list, strsize_t offset = npos) const; 00643 00649 void split(const char *pointer); 00650 00656 void split(strsize_t offset); 00657 00663 void rsplit(const char *pointer); 00664 00670 void rsplit(strsize_t offset); 00671 00677 const char *chr(char character) const; 00678 00685 const char *rchr(char character) const; 00686 00691 strsize_t len(void) const; 00692 00697 char fill(void); 00698 00703 inline operator const char *() const 00704 {return c_str();} 00705 00710 inline const char *operator*() const 00711 {return c_str();} 00712 00717 bool full(void) const; 00718 00725 String operator()(int offset, strsize_t size) const; 00726 00732 inline String left(strsize_t size) const 00733 {return operator()(0, size);} 00734 00740 inline String right(strsize_t offset) const 00741 {return operator()(-((int)offset), 0);} 00742 00749 inline String copy(strsize_t offset, strsize_t size) const 00750 {return operator()((int)offset, size);} 00751 00759 const char *operator()(int offset) const; 00760 00766 const char operator[](int offset) const; 00767 00772 bool operator!() const; 00773 00778 operator bool() const; 00779 00785 String& operator^=(const String& object); 00786 00791 String& operator|=(const char *text); 00792 00793 String& operator&=(const char *text); 00794 00800 String& operator+=(const char *text); 00801 00807 String& operator^=(const char *text); 00808 00813 String operator+(const char *text); 00814 00821 String& operator|(const char *text); 00822 00829 String& operator&(const char *text); 00830 00837 String& operator=(const String& object); 00838 00839 bool operator*=(const char *substring); 00840 00841 bool operator*=(regex& expr); 00842 00847 String& operator=(const char *text); 00848 00852 String& operator++(void); 00853 00858 String& operator+=(strsize_t number); 00859 00863 String& operator--(void); 00864 00869 String& operator-=(strsize_t number); 00870 00875 String& operator*=(strsize_t number); 00876 00882 bool operator==(const char *text) const; 00883 00889 bool operator!=(const char *text) const; 00890 00896 bool operator<(const char *text) const; 00897 00903 bool operator<=(const char *text) const; 00904 00910 bool operator>(const char *text) const; 00911 00917 bool operator>=(const char *text) const; 00918 00919 inline String& operator<<(const char *text) 00920 {add(text); return *this;} 00921 00922 inline String& operator<<(char code) 00923 {add(code); return *this;} 00924 00930 String &operator%(short& value); 00931 00937 String &operator%(unsigned short& value); 00938 00944 String &operator%(long& value); 00945 00951 String &operator%(unsigned long& value); 00952 00958 String &operator%(double& value); 00959 00965 String &operator%(const char *text); 00966 00972 static void swap(String& object1, String& object2); 00973 00978 static void fix(String& object); 00979 00984 static void erase(char *text); 00985 00990 static void lower(char *text); 00991 00996 static void upper(char *text); 00997 01011 static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL); 01012 01019 static char *skip(char *text, const char *list); 01020 01027 static char *rskip(char *text, const char *list); 01028 01036 static char *unquote(char *text, const char *quote); 01037 01045 static char *rset(char *buffer, size_t size, const char *text); 01046 01055 static char *set(char *buffer, size_t size, const char *text); 01056 01066 static char *set(char *buffer, size_t size, const char *text, size_t max); 01067 01077 static char *add(char *buffer, size_t size, const char *text); 01078 01089 static char *add(char *buffer, size_t size, const char *text, size_t max); 01090 01098 static const char *ifind(const char *text, const char *key, const char *optional); 01099 01107 static const char *find(const char *text, const char *key, const char *optional); 01108 01114 static size_t count(const char *text); 01115 01122 static int compare(const char *text1, const char *text2); 01123 01124 static inline int collate(const char *text1, const char *text2) 01125 {return compare(text1, text2);} 01126 01133 static bool equal(const char *text1, const char *text2); 01134 01142 static int compare(const char *text1, const char *text2, size_t size); 01143 01151 static bool equal(const char *text1, const char *text2, size_t size); 01152 01159 static int case_compare(const char *text1, const char *text2); 01160 01167 static bool eq_case(const char *text1, const char *text2); 01168 01176 static int case_compare(const char *text1, const char *text2, size_t size); 01177 01185 static bool eq_case(const char *text1, const char *text2, size_t size); 01186 01194 static char *trim(char *text, const char *list); 01195 01203 static char *chop(char *text, const char *list); 01204 01212 static char *strip(char *text, const char *list); 01213 01222 static char *fill(char *text, size_t size, char character); 01223 01230 static unsigned ccount(const char *text, const char *list); 01231 01238 static char *find(char *text, const char *list); 01239 01246 static size_t seek(char *text, const char *list); 01247 01254 static char *rfind(char *text, const char *list); 01255 01261 static char *dup(const char *text); 01262 01269 static char *left(const char *text, size_t size); 01270 01277 static const char *pos(const char *text, ssize_t offset); 01278 01279 inline static char *right(const char *text, size_t size) 01280 {return dup(pos(text, -(signed)size));} 01281 01282 inline static char *copy(const char *text, size_t offset, size_t len) 01283 {return left(pos(text, offset), len);} 01284 01285 static void cut(char *text, size_t offset, size_t len); 01286 01287 static void paste(char *text, size_t max, size_t offset, const char *data, size_t len = 0); 01288 01301 inline char *token(char **last, const char *list, const char *quote = NULL, const char *end = NULL) 01302 {return token(c_mem(), last, list, quote, end);} 01303 01310 inline double tod(char **pointer = NULL) 01311 {return strtod(c_mem(), pointer);} 01312 01319 inline long tol(char **pointer = NULL) 01320 {return strtol(c_mem(), 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 01348 static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0); 01349 01357 static size_t b64decode(uint8_t *binary, const char *string, size_t size); 01358 01365 static uint32_t crc24(uint8_t *binary, size_t size); 01366 01373 static uint16_t crc16(uint8_t *binary, size_t size); 01374 01382 static unsigned hexdump(const unsigned char *binary, char *string, const char *format); 01383 01391 static unsigned hexpack(unsigned char *binary, const char *string, const char *format); 01392 01393 static unsigned hexsize(const char *format); 01394 }; 01395 01403 class __EXPORT memstring : public String 01404 { 01405 public: 01406 #if _MSC_VER > 1400 // windows broken dll linkage issue... 01407 const static size_t header = sizeof(String::cstring); 01408 #else 01409 static const size_t header; 01410 #endif 01411 01412 private: 01413 bool resize(strsize_t size); 01414 void cow(strsize_t adj = 0); 01415 void release(void); 01416 01417 protected: 01418 cstring *c_copy(void) const; 01419 01420 public: 01425 inline void operator=(String& object) 01426 {set(object.c_str());} 01427 01432 inline void operator=(const char *text) 01433 {set(text);} 01434 01441 memstring(void *memory, strsize_t size, char fill = 0); 01442 01446 ~memstring(); 01447 01453 static memstring *create(strsize_t size, char fill = 0); 01454 01461 static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0); 01462 }; 01463 01471 template<size_t S> 01472 class charbuf 01473 { 01474 private: 01475 char buffer[S]; 01476 01477 public: 01481 inline charbuf() 01482 {buffer[0] = 0;} 01483 01489 inline charbuf(const char *text) 01490 {String::set(buffer, S, text);} 01491 01495 inline charbuf(const charbuf& copy) 01496 {String::set(buffer, S, copy.buffer);} 01497 01502 inline void operator=(const char *text) 01503 {String::set(buffer, S, text);} 01504 01510 inline void operator+=(const char *text) 01511 {String::add(buffer, S, text);} 01512 01517 inline operator bool() const 01518 {return buffer[0];} 01519 01524 inline bool operator!() const 01525 {return buffer[0] == 0;} 01526 01531 inline operator char *() 01532 {return buffer;} 01533 01538 inline char *operator*() 01539 {return buffer;} 01540 01546 inline char& operator[](size_t offset) const 01547 {return buffer[offset];} 01548 01554 inline char *operator()(size_t offset) 01555 {return buffer + offset;} 01556 01561 inline size_t size(void) const 01562 {return S;} 01563 01568 inline size_t len(void) const 01569 {return strlen(buffer);} 01570 }; 01571 01575 typedef String string_t; 01576 01577 typedef String::regex stringex_t; 01578 01589 template<strsize_t S> 01590 class stringbuf : public memstring 01591 { 01592 private: 01593 char buffer[sizeof(cstring) + S]; 01594 01595 public: 01599 inline stringbuf() : memstring(buffer, S) {} 01600 01605 inline stringbuf(const char *text) : memstring(buffer, S) {set(text);} 01606 01611 inline void operator=(const char *text) 01612 {set(text);} 01613 01618 inline void operator=(String& object) 01619 {set(object.c_str());} 01620 }; 01621 01622 #if !defined(_MSWINDOWS_) && !defined(__QNX__) 01623 01624 #ifndef stricmp 01625 #define stricmp(x,y) String::case_compare(x,y) 01626 #endif 01627 01628 #ifndef strnicmp 01629 #define strnicmp(x,y,z) String::case_compare(x,y,z) 01630 #endif 01631 01632 #endif 01633 01640 inline bool eq(char const *s1, char const *s2) 01641 {return String::equal(s1, s2);} 01642 01643 inline bool ne(char const *s1, char const *s2) 01644 {return !String::equal(s1, s2);} 01645 01653 inline bool eq(char const *s1, char const *s2, size_t size) 01654 {return String::equal(s1, s2, size);} 01655 01656 inline bool ne(char const *s1, char const *s2, size_t size) 01657 {return !String::equal(s1, s2, size);} 01658 01668 inline bool eq(String &s1, const char *s2) 01669 {return s1.compare(s2) == 0;} 01670 01671 inline bool ne(String &s1, String &s2) 01672 {return s1.compare(s2) != 0;} 01673 01674 inline bool lt(String &s1, const char *s2) 01675 {return s1.compare(s2) < 0;} 01676 01677 inline bool gt(String &s1, const char *s2) 01678 {return s1.compare(s2) > 0;} 01679 01680 inline bool le(String &s1, const char *s2) 01681 {return s1.compare(s2) <= 0;} 01682 01683 inline bool ge(String &s1, const char *s2) 01684 {return s1.compare(s2) >= 0;} 01685 01693 inline bool eq_case(char const *s1, char const *s2) 01694 {return String::eq_case(s1, s2);} 01695 01696 inline bool ne_case(char const *s1, char const *s2) 01697 {return !String::eq_case(s1, s2);} 01698 01707 inline bool eq_case(char const *s1, char const *s2, size_t size) 01708 {return String::eq_case(s1, s2, size);} 01709 01710 inline String str(const char *string) 01711 {return (String)string;} 01712 01713 inline String str(String& string) 01714 {return (String)string;} 01715 01716 inline String str(short value) 01717 {String temp(16, "%hd", value); return temp;} 01718 01719 inline String str(unsigned short value) 01720 {String temp(16, "%hu", value); return temp;} 01721 01722 inline String str(long value) 01723 {String temp(32, "%ld", value); return temp;} 01724 01725 inline String str(unsigned long value) 01726 {String temp(32, "%lu", value); return temp;} 01727 01728 inline String str(double value) 01729 {String temp(40, "%f", value); return temp;} 01730 01731 String str(CharacterProtocol& cp, strsize_t size); 01732 01733 template<> 01734 inline void swap<string_t>(string_t& s1, string_t& s2) 01735 {String::swap(s1, s2);} 01736 01737 class __EXPORT strdup_t 01738 { 01739 private: 01740 char *data; 01741 01742 public: 01743 inline strdup_t() 01744 {data = NULL;} 01745 01746 inline strdup_t(char *str) 01747 {data = str;} 01748 01749 inline ~strdup_t() 01750 {if(data) ::free(data);} 01751 01752 inline strdup_t& operator=(char *str) 01753 {if(data) ::free(data); data = str; return *this;} 01754 01755 inline operator bool() const 01756 {return data != NULL;} 01757 01758 inline bool operator!() const 01759 {return data == NULL;} 01760 01761 inline operator char*() const 01762 {return data;} 01763 01764 inline const char *c_str(void) const 01765 {return data;} 01766 01767 inline const char *operator*() const 01768 {return data;} 01769 01770 inline char& operator[](int size) 01771 {return data[size];} 01772 01773 inline char *operator+(size_t size) 01774 {return data + size;} 01775 }; 01776 01777 } // namespace ucommon 01778 01779 #endif