UCommon
|
00001 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00002 // Copyright (C) 2015 Cherokees of Idaho. 00003 // 00004 // This file is part of GNU uCommon C++. 00005 // 00006 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00007 // it under the terms of the GNU Lesser General Public License as published 00008 // by the Free Software Foundation, either version 3 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // GNU uCommon C++ is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU Lesser General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU Lesser General Public License 00017 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00018 00036 #ifndef _UCOMMON_STRING_H_ 00037 #define _UCOMMON_STRING_H_ 00038 00039 #ifndef _UCOMMON_CPR_H_ 00040 #include <ucommon/cpr.h> 00041 #endif 00042 00043 #ifndef _UCOMMON_GENERICS_H_ 00044 #include <ucommon/generics.h> 00045 #endif 00046 00047 #ifndef _UCOMMON_PROTOCOLS_H_ 00048 #include <ucommon/protocols.h> 00049 #endif 00050 00051 #ifndef _UCOMMON_OBJECT_H_ 00052 #include <ucommon/object.h> 00053 #endif 00054 00055 #include <stdio.h> 00056 #include <string.h> 00057 #include <stdarg.h> 00058 00059 #ifdef HAVE_DIRENT_H 00060 #include <dirent.h> 00061 #endif 00062 00063 #define PGP_B64_WIDTH 64 00064 #define MIME_B64_WIDTH 76 00065 00066 namespace ucommon { 00067 00071 typedef unsigned short strsize_t; 00072 00083 class __EXPORT String : public ObjectProtocol 00084 { 00085 protected: 00097 public: 00098 enum { 00099 SENSITIVE = 0x00, 00100 INSENSITIVE = 0x01 00101 }; 00102 00103 class __EXPORT regex 00104 { 00105 private: 00106 void *object; 00107 void *results; 00108 size_t count; 00109 00110 public: 00111 regex(const char *pattern, size_t size = 1); 00112 regex(size_t size = 1); 00113 ~regex(); 00114 00115 size_t offset(unsigned member); 00116 size_t size(unsigned member); 00117 00118 inline size_t members(void) const 00119 {return count;} 00120 00121 bool match(const char *text, unsigned flags = 0); 00122 00123 regex& operator=(const char *string); 00124 00125 bool operator*=(const char *string); 00126 00127 operator bool() const 00128 {return object != NULL;} 00129 00130 bool operator!() const 00131 {return object == NULL;} 00132 }; 00133 00134 class __EXPORT cstring : public CountedObject 00135 { 00136 protected: 00137 void dealloc(void); 00138 00139 public: 00140 #pragma pack(1) 00141 strsize_t max; 00142 strsize_t len; 00143 char fill; 00144 char text[1]; 00145 #pragma pack() 00146 00152 cstring(strsize_t size); 00153 00161 cstring(strsize_t size, char fill); 00162 00170 void clear(strsize_t offset, strsize_t size); 00171 00178 void set(strsize_t offset, const char *text, strsize_t size); 00179 00184 void set(const char *text); 00185 00190 void add(const char *text); 00191 00196 void add(char character); 00197 00201 void fix(void); 00202 00207 void unfix(void); 00208 00214 void inc(strsize_t number); 00215 00221 void dec(strsize_t number); 00222 }; 00223 00224 protected: 00225 cstring *str; 00233 cstring *create(strsize_t size, char fill = 0) const; 00234 00235 public: 00243 virtual int compare(const char *string) const; 00244 00245 inline int collate(const char *string) const 00246 {return compare(string);} 00247 00248 protected: 00254 bool equal(const char *string) const; 00255 00260 virtual void retain(void); 00261 00266 virtual void release(void); 00267 00272 virtual cstring *c_copy(void) const; 00273 00280 virtual void cow(strsize_t size = 0); 00281 00282 strsize_t getStringSize(void) const; 00283 00284 public: 00285 #if _MSC_VER > 1400 // windows broken dll linkage issue... 00286 const static strsize_t npos = ((strsize_t)-1); 00287 const static char eos = '\0'; 00288 #else 00289 static const strsize_t npos; 00290 static const char eos; 00291 #endif 00292 00293 00297 String(); 00298 00303 String(long value); 00304 00309 String(double value); 00310 00315 String(strsize_t size); 00316 00322 String(strsize_t size, char fill); 00323 00331 String(strsize_t size, const char *format, ...) __PRINTF(3, 4); 00332 00333 00338 String(const char *text); 00339 00346 String(const char *text, strsize_t size); 00347 00354 String(const char *text, const char *end); 00355 00361 String(const String& existing); 00362 00367 virtual ~String(); 00368 00375 String get(strsize_t offset, strsize_t size = 0) const; 00376 00382 int scanf(const char *format, ...) __SCANF(2, 3); 00383 00390 int vscanf(const char *format, va_list args) __SCANF(2, 0); 00391 00397 strsize_t printf(const char *format, ...) __PRINTF(2, 3); 00398 00405 strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0); 00406 00411 char *c_mem(void) const; 00412 00417 const char *c_str(void) const; 00418 00424 virtual bool resize(strsize_t size); 00425 00430 void set(const char *text); 00431 00439 void set(strsize_t offset, const char *text, strsize_t size = 0); 00440 00448 void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0); 00449 00457 void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0); 00458 00463 void add(const char *text); 00464 00469 void add(char character); 00470 00475 void trim(const char *list); 00476 00481 inline void trim(strsize_t count = 1) 00482 {operator+=(count);} 00483 00488 void chop(const char *list); 00489 00494 inline void chop(strsize_t count = 1) 00495 {operator-=(count);} 00496 00501 void strip(const char *list); 00502 00508 bool unquote(const char *quote); 00509 00515 void cut(strsize_t offset, strsize_t size = 0); 00516 00523 void paste(strsize_t offset, const char *text, strsize_t size = 0); 00524 00530 void clear(strsize_t offset, strsize_t size = 0); 00531 00535 void clear(void); 00536 00540 void upper(void); 00541 00545 void lower(void); 00546 00550 void erase(void); 00551 00557 strsize_t ccount(const char *list) const; 00558 00563 strsize_t count(void) const; 00564 00569 strsize_t size(void) const; 00570 00580 strsize_t offset(const char *pointer) const; 00581 00587 char at(int position) const; 00588 00593 const char *begin(void) const; 00594 00599 const char *end(void) const; 00600 00607 const char *skip(const char *list, strsize_t offset = 0) const; 00608 00616 const char *rskip(const char *list, strsize_t offset = npos) const; 00617 00623 const char *search(const char *string, unsigned instance = 0, unsigned flags = 0) const; 00624 00625 const char *search(regex& expr, unsigned instance = 0, unsigned flags = 0) const; 00626 00627 unsigned replace(const char *string, const char *text = NULL, unsigned flags = 0); 00628 00629 unsigned replace(regex& expr, const char *text = NULL, unsigned flags = 0); 00630 00637 const char *find(const char *list, strsize_t offset = 0) const; 00638 00645 const char *rfind(const char *list, strsize_t offset = npos) const; 00646 00652 void split(const char *pointer); 00653 00659 void split(strsize_t offset); 00660 00666 void rsplit(const char *pointer); 00667 00673 void rsplit(strsize_t offset); 00674 00680 const char *chr(char character) const; 00681 00688 const char *rchr(char character) const; 00689 00694 strsize_t len(void) const; 00695 00700 char fill(void); 00701 00706 inline operator const char *() const 00707 {return c_str();} 00708 00713 inline const char *operator*() const 00714 {return c_str();} 00715 00720 bool full(void) const; 00721 00728 String operator()(int offset, strsize_t size) const; 00729 00735 inline String left(strsize_t size) const 00736 {return operator()(0, size);} 00737 00743 inline String right(strsize_t offset) const 00744 {return operator()(-((int)offset), 0);} 00745 00752 inline String copy(strsize_t offset, strsize_t size) const 00753 {return operator()((int)offset, size);} 00754 00762 const char *operator()(int offset) const; 00763 00769 const char operator[](int offset) const; 00770 00775 bool operator!() const; 00776 00781 operator bool() const; 00782 00788 String& operator^=(const String& object); 00789 00794 String& operator|=(const char *text); 00795 00796 String& operator&=(const char *text); 00797 00803 String& operator+=(const char *text); 00804 00810 String& operator^=(const char *text); 00811 00816 String operator+(const char *text); 00817 00824 String& operator|(const char *text); 00825 00832 String& operator&(const char *text); 00833 00840 String& operator=(const String& object); 00841 00842 bool operator*=(const char *substring); 00843 00844 bool operator*=(regex& expr); 00845 00850 String& operator=(const char *text); 00851 00855 String& operator++(void); 00856 00861 String& operator+=(strsize_t number); 00862 00866 String& operator--(void); 00867 00872 String& operator-=(strsize_t number); 00873 00878 String& operator*=(strsize_t number); 00879 00885 bool operator==(const char *text) const; 00886 00892 bool operator!=(const char *text) const; 00893 00899 bool operator<(const char *text) const; 00900 00906 bool operator<=(const char *text) const; 00907 00913 bool operator>(const char *text) const; 00914 00920 bool operator>=(const char *text) const; 00921 00922 inline String& operator<<(const char *text) 00923 {add(text); return *this;} 00924 00925 inline String& operator<<(char code) 00926 {add(code); return *this;} 00927 00933 String &operator%(short& value); 00934 00940 String &operator%(unsigned short& value); 00941 00947 String &operator%(long& value); 00948 00954 String &operator%(unsigned long& value); 00955 00961 String &operator%(double& value); 00962 00968 String &operator%(const char *text); 00969 00975 static void swap(String& object1, String& object2); 00976 00981 static void fix(String& object); 00982 00990 static bool check(const char *string, size_t maximum, size_t minimum = 0); 00991 00996 static void erase(char *text); 00997 01002 static void lower(char *text); 01003 01008 static void upper(char *text); 01009 01023 static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL); 01024 01031 static char *skip(char *text, const char *list); 01032 01039 static char *rskip(char *text, const char *list); 01040 01048 static char *unquote(char *text, const char *quote); 01049 01057 static char *rset(char *buffer, size_t size, const char *text); 01058 01067 static char *set(char *buffer, size_t size, const char *text); 01068 01078 static char *set(char *buffer, size_t size, const char *text, size_t max); 01079 01089 static char *add(char *buffer, size_t size, const char *text); 01090 01101 static char *add(char *buffer, size_t size, const char *text, size_t max); 01102 01110 static const char *ifind(const char *text, const char *key, const char *optional); 01111 01119 static const char *find(const char *text, const char *key, const char *optional); 01120 01126 static size_t count(const char *text); 01127 01134 static int compare(const char *text1, const char *text2); 01135 01136 static inline int collate(const char *text1, const char *text2) 01137 {return compare(text1, text2);} 01138 01145 static bool equal(const char *text1, const char *text2); 01146 01154 static int compare(const char *text1, const char *text2, size_t size); 01155 01163 static bool equal(const char *text1, const char *text2, size_t size); 01164 01171 static int case_compare(const char *text1, const char *text2); 01172 01179 static bool eq_case(const char *text1, const char *text2); 01180 01188 static int case_compare(const char *text1, const char *text2, size_t size); 01189 01197 static bool eq_case(const char *text1, const char *text2, size_t size); 01198 01206 static char *trim(char *text, const char *list); 01207 01215 static char *chop(char *text, const char *list); 01216 01224 static char *strip(char *text, const char *list); 01225 01234 static char *fill(char *text, size_t size, char character); 01235 01242 static unsigned ccount(const char *text, const char *list); 01243 01250 static char *find(char *text, const char *list); 01251 01258 static size_t seek(char *text, const char *list); 01259 01266 static char *rfind(char *text, const char *list); 01267 01273 static char *dup(const char *text); 01274 01281 static char *left(const char *text, size_t size); 01282 01289 static const char *pos(const char *text, ssize_t offset); 01290 01291 inline static char *right(const char *text, size_t size) 01292 {return dup(pos(text, -(signed)size));} 01293 01294 inline static char *copy(const char *text, size_t offset, size_t len) 01295 {return left(pos(text, offset), len);} 01296 01297 static void cut(char *text, size_t offset, size_t len); 01298 01299 static void paste(char *text, size_t max, size_t offset, const char *data, size_t len = 0); 01300 01313 inline char *token(char **last, const char *list, const char *quote = NULL, const char *end = NULL) 01314 {return token(c_mem(), last, list, quote, end);} 01315 01322 inline double tod(char **pointer = NULL) 01323 {return strtod(c_mem(), pointer);} 01324 01331 inline long tol(char **pointer = NULL) 01332 {return strtol(c_mem(), pointer, 0);} 01333 01340 inline static double tod(const char *text, char **pointer = NULL) 01341 {return strtod(text, pointer);} 01342 01349 inline static long tol(const char *text, char **pointer = NULL) 01350 {return strtol(text, pointer, 0);} 01351 01358 static String b64(const uint8_t *binary, size_t size); 01359 01368 static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0); 01369 01377 static size_t b64decode(uint8_t *binary, const char *string, size_t size); 01378 01385 static uint32_t crc24(uint8_t *binary, size_t size); 01386 01393 static uint16_t crc16(uint8_t *binary, size_t size); 01394 01401 static String hex(const unsigned char *binary, size_t size); 01402 01410 static unsigned hexdump(const unsigned char *binary, char *string, const char *format); 01411 01419 static unsigned hexpack(unsigned char *binary, const char *string, const char *format); 01420 01421 static unsigned hexsize(const char *format); 01422 }; 01423 01431 class __EXPORT memstring : public String 01432 { 01433 public: 01434 #if _MSC_VER > 1400 // windows broken dll linkage issue... 01435 const static size_t header = sizeof(String::cstring); 01436 #else 01437 static const size_t header; 01438 #endif 01439 01440 private: 01441 bool resize(strsize_t size); 01442 void cow(strsize_t adj = 0); 01443 void release(void); 01444 01445 protected: 01446 cstring *c_copy(void) const; 01447 01448 public: 01453 inline void operator=(String& object) 01454 {set(object.c_str());} 01455 01460 inline void operator=(const char *text) 01461 {set(text);} 01462 01469 memstring(void *memory, strsize_t size, char fill = 0); 01470 01474 ~memstring(); 01475 01481 static memstring *create(strsize_t size, char fill = 0); 01482 01489 static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0); 01490 }; 01491 01499 template<size_t S> 01500 class charbuf 01501 { 01502 private: 01503 char buffer[S]; 01504 01505 public: 01509 inline charbuf() 01510 {buffer[0] = 0;} 01511 01517 inline charbuf(const char *text) 01518 {String::set(buffer, S, text);} 01519 01523 inline charbuf(const charbuf& copy) 01524 {String::set(buffer, S, copy.buffer);} 01525 01530 inline void operator=(const char *text) 01531 {String::set(buffer, S, text);} 01532 01538 inline void operator+=(const char *text) 01539 {String::add(buffer, S, text);} 01540 01545 inline operator bool() const 01546 {return buffer[0];} 01547 01552 inline bool operator!() const 01553 {return buffer[0] == 0;} 01554 01559 inline operator char *() 01560 {return buffer;} 01561 01566 inline char *operator*() 01567 {return buffer;} 01568 01574 inline char& operator[](size_t offset) const 01575 {return buffer[offset];} 01576 01582 inline char *operator()(size_t offset) 01583 {return buffer + offset;} 01584 01589 inline size_t size(void) const 01590 {return S;} 01591 01596 inline size_t len(void) const 01597 {return strlen(buffer);} 01598 }; 01599 01603 typedef String string_t; 01604 01605 typedef String::regex stringex_t; 01606 01617 template<strsize_t S> 01618 class stringbuf : public memstring 01619 { 01620 private: 01621 char buffer[sizeof(cstring) + S]; 01622 01623 public: 01627 inline stringbuf() : memstring(buffer, S) {} 01628 01633 inline stringbuf(const char *text) : memstring(buffer, S) {set(text);} 01634 01639 inline void operator=(const char *text) 01640 {set(text);} 01641 01646 inline void operator=(String& object) 01647 {set(object.c_str());} 01648 }; 01649 01650 #if !defined(_MSWINDOWS_) && !defined(__QNX__) 01651 01652 #ifndef stricmp 01653 #define stricmp(x,y) String::case_compare(x,y) 01654 #endif 01655 01656 #ifndef strnicmp 01657 #define strnicmp(x,y,z) String::case_compare(x,y,z) 01658 #endif 01659 01660 #endif 01661 01668 inline bool eq(char const *s1, char const *s2) 01669 {return String::equal(s1, s2);} 01670 01671 inline bool ne(char const *s1, char const *s2) 01672 {return !String::equal(s1, s2);} 01673 01681 inline bool eq(char const *s1, char const *s2, size_t size) 01682 {return String::equal(s1, s2, size);} 01683 01684 inline bool ne(char const *s1, char const *s2, size_t size) 01685 {return !String::equal(s1, s2, size);} 01686 01696 inline bool eq(String &s1, const char *s2) 01697 {return s1.compare(s2) == 0;} 01698 01699 inline bool ne(String &s1, String &s2) 01700 {return s1.compare(s2) != 0;} 01701 01702 inline bool lt(String &s1, const char *s2) 01703 {return s1.compare(s2) < 0;} 01704 01705 inline bool gt(String &s1, const char *s2) 01706 {return s1.compare(s2) > 0;} 01707 01708 inline bool le(String &s1, const char *s2) 01709 {return s1.compare(s2) <= 0;} 01710 01711 inline bool ge(String &s1, const char *s2) 01712 {return s1.compare(s2) >= 0;} 01713 01721 inline bool eq_case(char const *s1, char const *s2) 01722 {return String::eq_case(s1, s2);} 01723 01724 inline bool ne_case(char const *s1, char const *s2) 01725 {return !String::eq_case(s1, s2);} 01726 01735 inline bool eq_case(char const *s1, char const *s2, size_t size) 01736 {return String::eq_case(s1, s2, size);} 01737 01738 inline String str(const char *string) 01739 {return (String)string;} 01740 01741 inline String str(String& string) 01742 {return (String)string;} 01743 01744 inline String str(short value) 01745 {String temp(16, "%hd", value); return temp;} 01746 01747 inline String str(unsigned short value) 01748 {String temp(16, "%hu", value); return temp;} 01749 01750 inline String str(long value) 01751 {String temp(32, "%ld", value); return temp;} 01752 01753 inline String str(unsigned long value) 01754 {String temp(32, "%lu", value); return temp;} 01755 01756 inline String str(double value) 01757 {String temp(40, "%f", value); return temp;} 01758 01759 String str(CharacterProtocol& cp, strsize_t size); 01760 01761 template<> 01762 inline void swap<string_t>(string_t& s1, string_t& s2) 01763 {String::swap(s1, s2);} 01764 01765 class __EXPORT strdup_t 01766 { 01767 private: 01768 char *data; 01769 01770 public: 01771 inline strdup_t() 01772 {data = NULL;} 01773 01774 inline strdup_t(char *str) 01775 {data = str;} 01776 01777 inline ~strdup_t() 01778 {if(data) ::free(data);} 01779 01780 inline strdup_t& operator=(char *str) 01781 {if(data) ::free(data); data = str; return *this;} 01782 01783 inline operator bool() const 01784 {return data != NULL;} 01785 01786 inline bool operator!() const 01787 {return data == NULL;} 01788 01789 inline operator char*() const 01790 {return data;} 01791 01792 inline const char *c_str(void) const 01793 {return data;} 01794 01795 inline const char *operator*() const 01796 {return data;} 01797 01798 inline char& operator[](int size) 01799 {return data[size];} 01800 01801 inline char *operator+(size_t size) 01802 {return data + size;} 01803 }; 01804 01805 } // namespace ucommon 01806 01807 #endif