00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 slots = 1);
00111 regex(size_t slots = 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
01630 extern "C" inline int stricmp(const char *string1, const char *string2)
01631 {return String::case_compare(string1, string2);}
01632
01640 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max)
01641 {return String::case_compare(string1, string2, max);}
01642
01643 #endif
01644
01651 inline bool eq(char const *s1, char const *s2)
01652 {return String::equal(s1, s2);}
01653
01654 inline bool ne(char const *s1, char const *s2)
01655 {return !String::equal(s1, s2);}
01656
01664 inline bool eq(char const *s1, char const *s2, size_t size)
01665 {return String::equal(s1, s2, size);}
01666
01667 inline bool ne(char const *s1, char const *s2, size_t size)
01668 {return !String::equal(s1, s2, size);}
01669
01679 inline bool eq(String &s1, const char *s2)
01680 {return s1.compare(s2) == 0;}
01681
01682 inline bool ne(String &s1, String &s2)
01683 {return s1.compare(s2) != 0;}
01684
01685 inline bool lt(String &s1, const char *s2)
01686 {return s1.compare(s2) < 0;}
01687
01688 inline bool gt(String &s1, const char *s2)
01689 {return s1.compare(s2) > 0;}
01690
01691 inline bool le(String &s1, const char *s2)
01692 {return s1.compare(s2) <= 0;}
01693
01694 inline bool ge(String &s1, const char *s2)
01695 {return s1.compare(s2) >= 0;}
01696
01704 inline bool eq_case(char const *s1, char const *s2)
01705 {return String::eq_case(s1, s2);}
01706
01707 inline bool ne_case(char const *s1, char const *s2)
01708 {return !String::eq_case(s1, s2);}
01709
01718 inline bool eq_case(char const *s1, char const *s2, size_t size)
01719 {return String::eq_case(s1, s2, size);}
01720
01721 inline String str(const char *string)
01722 {return (String)string;}
01723
01724 inline String str(String& string)
01725 {return (String)string;}
01726
01727 inline String str(short value)
01728 {String temp(16, "%hd", value); return temp;}
01729
01730 inline String str(unsigned short value)
01731 {String temp(16, "%hu", value); return temp;}
01732
01733 inline String str(long value)
01734 {String temp(32, "%ld", value); return temp;}
01735
01736 inline String str(unsigned long value)
01737 {String temp(32, "%lu", value); return temp;}
01738
01739 inline String str(double value)
01740 {String temp(40, "%f", value); return temp;}
01741
01742 String str(CharacterProtocol& cp, strsize_t size);
01743
01744 template<>
01745 inline void swap<string_t>(string_t& s1, string_t& s2)
01746 {String::swap(s1, s2);}
01747
01748 class __EXPORT strdup_t
01749 {
01750 private:
01751 char *data;
01752
01753 public:
01754 inline strdup_t()
01755 {data = NULL;}
01756
01757 inline strdup_t(char *str)
01758 {data = str;}
01759
01760 inline ~strdup_t()
01761 {if(data) ::free(data);}
01762
01763 inline strdup_t& operator=(char *str)
01764 {if(data) ::free(data); data = str; return *this;}
01765
01766 inline operator bool() const
01767 {return data != NULL;}
01768
01769 inline bool operator!() const
01770 {return data == NULL;}
01771
01772 inline operator char*() const
01773 {return data;}
01774
01775 inline const char *c_str(void) const
01776 {return data;};
01777
01778 inline const char *operator*() const
01779 {return data;}
01780
01781 inline char& operator[](int size)
01782 {return data[size];}
01783
01784 inline char *operator+(size_t size)
01785 {return data + size;}
01786 };
01787
01788
01789 END_NAMESPACE
01790
01791 #endif