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_CONFIG_H_
00039 #include <ucommon/platform.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 class __EXPORT cstring : public CountedObject
00098 {
00099 public:
00100 #pragma pack(1)
00101 strsize_t max;
00102 strsize_t len;
00103 char fill;
00104 char text[1];
00105 #pragma pack()
00106
00112 cstring(strsize_t size);
00113
00121 cstring(strsize_t size, char fill);
00122
00130 void clear(strsize_t offset, strsize_t size);
00131
00138 void set(strsize_t offset, const char *text, strsize_t size);
00139
00144 void set(const char *text);
00145
00150 void add(const char *text);
00151
00156 void add(char character);
00157
00161 void fix(void);
00162
00167 void unfix(void);
00168
00174 void inc(strsize_t number);
00175
00181 void dec(strsize_t number);
00182 };
00183
00184 protected:
00185 cstring *str;
00193 cstring *create(strsize_t size, char fill = 0) const;
00194
00202 virtual int compare(const char *string) const;
00203
00209 bool equal(const char *string) const;
00210
00215 virtual void retain(void);
00216
00221 virtual void release(void);
00222
00227 virtual cstring *c_copy(void) const;
00228
00235 virtual void cow(strsize_t size = 0);
00236
00237 strsize_t getStringSize(void);
00238
00239 public:
00243 #if _MSC_VER > 1400 // windows broken dll linkage issue...
00244 const static strsize_t npos = ((strsize_t)-1);
00245 #else
00246 static const strsize_t npos;
00247 #endif
00248
00249
00253 string();
00254
00259 string(long value);
00260
00265 string(double value);
00266
00271 string(strsize_t size);
00272
00278 string(strsize_t size, char fill);
00279
00287 string(strsize_t size, const char *format, ...) __PRINTF(3, 4);
00288
00289
00294 string(const char *text);
00295
00302 string(const char *text, strsize_t size);
00303
00310 string(const char *text, const char *end);
00311
00317 string(const string& existing);
00318
00323 virtual ~string();
00324
00331 string get(strsize_t offset, strsize_t size = 0) const;
00332
00338 int scanf(const char *format, ...) __SCANF(2, 3);
00339
00346 int vscanf(const char *format, va_list args) __SCANF(2, 0);
00347
00353 strsize_t printf(const char *format, ...) __PRINTF(2, 3);
00354
00361 strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
00362
00367 char *c_mem(void) const;
00368
00373 const char *c_str(void) const;
00374
00380 virtual bool resize(strsize_t size);
00381
00386 void set(const char *text);
00387
00395 void set(strsize_t offset, const char *text, strsize_t size = 0);
00396
00404 void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00405
00413 void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
00414
00419 void add(const char *text);
00420
00425 void add(char character);
00426
00431 void trim(const char *list);
00432
00437 void chop(const char *list);
00438
00443 void strip(const char *list);
00444
00450 bool unquote(const char *quote);
00451
00457 void cut(strsize_t offset, strsize_t size = 0);
00458
00464 void clear(strsize_t offset, strsize_t size = 0);
00465
00469 void clear(void);
00470
00474 void upper(void);
00475
00479 void lower(void);
00480
00486 strsize_t ccount(const char *list) const;
00487
00492 strsize_t count(void) const;
00493
00498 strsize_t size(void) const;
00499
00509 strsize_t offset(const char *pointer) const;
00510
00516 char at(int position) const;
00517
00523 const char *last(const char *list) const;
00524
00530 const char *first(const char *list) const;
00531
00536 const char *begin(void) const;
00537
00542 const char *end(void) const;
00543
00550 const char *skip(const char *list, strsize_t offset = 0) const;
00551
00559 const char *rskip(const char *list, strsize_t offset = npos) const;
00560
00567 const char *find(const char *list, strsize_t offset = 0) const;
00568
00575 const char *rfind(const char *list, strsize_t offset = npos) const;
00576
00582 void split(const char *pointer);
00583
00589 void split(strsize_t offset);
00590
00596 void rsplit(const char *pointer);
00597
00603 void rsplit(strsize_t offset);
00604
00610 const char *chr(char character) const;
00611
00618 const char *rchr(char character) const;
00619
00624 strsize_t len(void);
00625
00630 char fill(void);
00631
00636 inline operator const char *() const
00637 {return c_str();};
00638
00643 inline const char *operator*() const
00644 {return c_str();};
00645
00650 bool full(void) const;
00651
00658 string operator()(int offset, strsize_t size) const;
00659
00667 const char *operator()(int offset) const;
00668
00674 const char operator[](int offset) const;
00675
00680 bool operator!() const;
00681
00686 operator bool() const;
00687
00693 string& operator^=(const string& object);
00694
00700 string& operator+=(const char *text);
00701
00707 string& operator^=(const char *text);
00708
00714 string& operator+(const char *text);
00715
00722 string& operator&(const char *text);
00723
00730 string& operator=(const string& object);
00731
00736 string& operator=(const char *text);
00737
00741 string& operator++(void);
00742
00747 string& operator+=(strsize_t number);
00748
00752 string& operator--(void);
00753
00758 string& operator-=(strsize_t number);
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 bool operator>(const char *text) const;
00794
00800 bool operator>=(const char *text) const;
00801
00807 string &operator%(short& value);
00808
00814 string &operator%(unsigned short& value);
00815
00821 string &operator%(long& value);
00822
00828 string &operator%(unsigned long& value);
00829
00835 string &operator%(double& value);
00836
00842 string &operator%(const char *text);
00843
00850 static int scanf(string& object, const char *format, ...) __SCANF(2, 3);
00851
00858 static strsize_t printf(string& object, const char *format, ...) __PRINTF(2, 3);
00859
00865 static void swap(string& object1, string& object2);
00866
00871 static void fix(string& object);
00872
00877 static void lower(char *text);
00878
00883 static void upper(char *text);
00884
00898 static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
00899
00906 static char *skip(char *text, const char *list);
00907
00914 static char *rskip(char *text, const char *list);
00915
00923 static char *unquote(char *text, const char *quote);
00924
00932 static char *rset(char *buffer, size_t size, const char *text);
00933
00942 static char *set(char *buffer, size_t size, const char *text);
00943
00953 static char *set(char *buffer, size_t size, const char *text, size_t max);
00954
00964 static char *add(char *buffer, size_t size, const char *text);
00965
00976 static char *add(char *buffer, size_t size, const char *text, size_t max);
00977
00985 static const char *ifind(const char *text, const char *key, const char *optional);
00986
00994 static const char *find(const char *text, const char *key, const char *optional);
00995
01001 static size_t count(const char *text);
01002
01009 static int compare(const char *text1, const char *text2);
01010
01017 static bool equal(const char *text1, const char *text2);
01018
01026 static int compare(const char *text1, const char *text2, size_t size);
01027
01035 static bool equal(const char *text1, const char *text2, size_t size);
01036
01043 static int case_compare(const char *text1, const char *text2);
01044
01051 static bool case_equal(const char *text1, const char *text2);
01052
01060 static int case_compare(const char *text1, const char *text2, size_t size);
01061
01069 static bool case_equal(const char *text1, const char *text2, size_t size);
01070
01078 static char *trim(char *text, const char *list);
01079
01087 static char *chop(char *text, const char *list);
01088
01096 static char *strip(char *text, const char *list);
01097
01106 static char *fill(char *text, size_t size, char character);
01107
01114 static unsigned ccount(const char *text, const char *list);
01115
01122 static char *find(char *text, const char *list);
01123
01130 static char *rfind(char *text, const char *list);
01131
01138 static char *first(char *text, const char *list);
01139
01146 static char *last(char *text, const char *list);
01147
01153 static char *dup(const char *text);
01154
01168 inline static char *token(string& object, char **last, const char *list, const char *quote = NULL, const char *end = NULL)
01169 {return token(object.c_mem(), last, list, quote, end);};
01170
01178 __SCANF(2,0) inline static int vscanf(string& object, const char *format, va_list args)
01179 {return object.vscanf(format, args);}
01180
01188 __PRINTF(2,0) inline static strsize_t vprintf(string& object, const char *format, va_list args)
01189 {return object.vprintf(format, args);}
01190
01196 inline static strsize_t len(string& object)
01197 {return object.len();};
01198
01204 inline static char *mem(string& object)
01205 {return object.c_mem();};
01206
01212 inline static strsize_t size(string& object)
01213 {return object.size();};
01214
01219 inline static void clear(string& object)
01220 {object.clear();};
01221
01228 inline static unsigned ccount(string& object, const char *list)
01229 {return object.ccount(list);};
01230
01236 inline static size_t count(string& object)
01237 {return object.count();};
01238
01243 inline static void upper(string& object)
01244 {object.upper();};
01245
01250 inline static void lower(string& object)
01251 {object.lower();};
01252
01259 inline static bool unquote(string& object, const char *quote)
01260 {return object.unquote(quote);};
01261
01267 inline static void trim(string& object, const char *list)
01268 {object.trim(list);};
01269
01275 inline static void chop(string& object, const char *list)
01276 {object.trim(list);};
01277
01283 inline static void strip(string& object, const char *list)
01284 {object.trim(list);};
01285
01292 inline static const char *find(string& object, const char *list)
01293 {return object.find(list);};
01294
01301 inline static const char *rfind(string& object, const char *list)
01302 {return object.rfind(list);};
01303
01310 inline static const char *first(string& object, const char *list)
01311 {return object.first(list);};
01312
01319 inline static const char *last(string& object, const char *list)
01320 {return object.last(list);};
01321
01328 inline static double tod(string& object, char **pointer = NULL)
01329 {return strtod(mem(object), pointer);};
01330
01337 inline static long tol(string& object, char **pointer = NULL)
01338 {return strtol(mem(object), pointer, 0);};
01339
01346 inline static double tod(const char *text, char **pointer = NULL)
01347 {return strtod(text, pointer);};
01348
01355 inline static long tol(const char *text, char **pointer = NULL)
01356 {return strtol(text, pointer, 0);};
01357
01366 static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
01367
01375 static size_t b64decode(uint8_t *binary, const char *string, size_t size);
01376
01383 static uint32_t crc24(uint8_t *binary, size_t size);
01384
01391 static uint16_t crc16(uint8_t *binary, size_t size);
01392
01400 static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
01401
01409 static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
01410
01411 static unsigned hexsize(const char *format);
01412 };
01413
01421 class __EXPORT memstring : public string
01422 {
01423 public:
01424 #if _MSC_VER > 1400 // windows broken dll linkage issue...
01425 const static size_t header = sizeof(string::cstring);
01426 #else
01427 static const size_t header;
01428 #endif
01429
01430 private:
01431 bool resize(strsize_t size);
01432 void cow(strsize_t adj = 0);
01433 void release(void);
01434
01435 protected:
01436 cstring *c_copy(void) const;
01437
01438 public:
01443 inline void operator=(string& object)
01444 {set(object.c_str());};
01445
01450 inline void operator=(const char *text)
01451 {set(text);};
01452
01459 memstring(void *memory, strsize_t size, char fill = 0);
01460
01464 ~memstring();
01465
01471 static memstring *create(strsize_t size, char fill = 0);
01472
01479 static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
01480 };
01481
01489 template<size_t S>
01490 class charbuf
01491 {
01492 private:
01493 char buffer[S];
01494
01495 public:
01499 inline charbuf()
01500 {buffer[0] = 0;};
01501
01507 inline charbuf(const char *text)
01508 {string::set(buffer, S, text);};
01509
01514 inline void operator=(const char *text)
01515 {string::set(buffer, S, text);};
01516
01522 inline void operator+=(const char *text)
01523 {string::add(buffer, S, text);};
01524
01529 inline operator bool() const
01530 {return buffer[0];};
01531
01536 inline bool operator!() const
01537 {return buffer[0] == 0;};
01538
01543 inline operator char *()
01544 {return buffer;};
01545
01550 inline char *operator*()
01551 {return buffer;};
01552
01558 inline char operator[](size_t offset) const
01559 {return buffer[offset];};
01560
01566 inline char *operator()(size_t offset)
01567 {return buffer + offset;};
01568
01573 inline size_t size(void) const
01574 {return S;};
01575 };
01576
01580 typedef string string_t;
01581
01586 typedef string String;
01587
01598 template<strsize_t S>
01599 class stringbuf : public memstring
01600 {
01601 private:
01602 char buffer[sizeof(cstring) + S];
01603
01604 public:
01608 inline stringbuf() : memstring(buffer, S) {};
01609
01614 inline stringbuf(const char *text) : memstring(buffer, S) {set(text);};
01615
01620 inline void operator=(const char *text)
01621 {set(text);};
01622
01627 inline void operator=(string& object)
01628 {set(object.c_str());};
01629 };
01630
01631 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
01632
01639 extern "C" inline int stricmp(const char *string1, const char *string2)
01640 {return string::case_compare(string1, string2);}
01641
01649 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max)
01650 {return string::case_compare(string1, string2, max);}
01651
01652 #endif
01653
01660 inline bool eq(char const *s1, char const *s2)
01661 {return String::equal(s1, s2);}
01662
01670 inline bool eq(char const *s1, char const *s2, size_t size)
01671 {return String::equal(s1, s2, size);}
01672
01679 inline bool eq(String &s1, String &s2)
01680 {return String::equal(s1.c_str(), s2.c_str());}
01681
01689 inline bool case_eq(char const *s1, char const *s2)
01690 {return String::case_equal(s1, s2);}
01691
01692
01693 inline bool ieq(char const *s1, char const *s2)
01694 {return String::case_equal(s1, s2);}
01695
01704 inline bool case_eq(char const *s1, char const *s2, size_t size)
01705 {return String::case_equal(s1, s2, size);}
01706
01707 inline bool ieq(char const *s1, char const *s2, size_t size)
01708 {return String::case_equal(s1, s2, size);}
01709
01717 inline bool ieq(String &s1, String &s2)
01718 {return String::case_equal(s1.c_str(), s2.c_str());}
01719
01720 inline String str(const char *string)
01721 {return (String)string;}
01722
01723 inline String str(String& string)
01724 {return (String)string;}
01725
01726 inline String str(short value)
01727 {String temp(16, "%hd", value); return temp;}
01728
01729 inline String str(unsigned short value)
01730 {String temp(16, "%hu", value); return temp;}
01731
01732 inline String str(long value)
01733 {String temp(32, "%ld", value); return temp;}
01734
01735 inline String str(unsigned long value)
01736 {String temp(32, "%lu", value); return temp;}
01737
01738 inline String str(double value)
01739 {String temp(40, "%f", value); return temp;}
01740
01741 String str(CharacterProtocol& cp, strsize_t size);
01742
01743 template<>
01744 inline void swap<string_t>(string_t& s1, string_t& s2)
01745 {String::swap(s1, s2);}
01746
01747 END_NAMESPACE
01748
01749 #endif