UCommon
string.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU uCommon C++.
4 //
5 // GNU uCommon C++ is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU uCommon C++ is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17 
35 #ifndef _UCOMMON_STRING_H_
36 #define _UCOMMON_STRING_H_
37 
38 #ifndef _UCOMMON_CPR_H_
39 #include <ucommon/cpr.h>
40 #endif
41 
42 #ifndef _UCOMMON_GENERICS_H_
43 #include <ucommon/generics.h>
44 #endif
45 
46 #ifndef _UCOMMON_PROTOCOLS_H_
47 #include <ucommon/protocols.h>
48 #endif
49 
50 #ifndef _UCOMMON_OBJECT_H_
51 #include <ucommon/object.h>
52 #endif
53 
54 #include <stdio.h>
55 #include <string.h>
56 #include <stdarg.h>
57 
58 #ifdef HAVE_DIRENT_H
59 #include <dirent.h>
60 #endif
61 
62 #define PGP_B64_WIDTH 64
63 #define MIME_B64_WIDTH 76
64 
65 NAMESPACE_UCOMMON
66 
70 typedef unsigned short strsize_t;
71 
82 class __EXPORT string : public ObjectProtocol
83 {
84 protected:
96 public:
97  enum {
98  SENSITIVE = 0x00,
99  INSENSITIVE = 0x01
100  };
101 
102  class __EXPORT regex
103  {
104  private:
105  void *object;
106  void *results;
107  size_t count;
108 
109  public:
110  regex(const char *pattern, size_t slots = 1);
111  regex(size_t slots = 1);
112  ~regex();
113 
114  size_t offset(unsigned member);
115  size_t size(unsigned member);
116 
117  inline size_t members(void)
118  {return count;};
119 
120  bool match(const char *text, unsigned flags = 0);
121 
122  regex& operator=(const char *string);
123 
124  bool operator*=(const char *string);
125 
126  operator bool()
127  {return object != NULL;}
128 
129  bool operator!()
130  {return object == NULL;}
131  };
132 
133  class __EXPORT cstring : public CountedObject
134  {
135  public:
136 #pragma pack(1)
137  strsize_t max;
138  strsize_t len;
139  char fill;
140  char text[1];
141 #pragma pack()
142 
148  cstring(strsize_t size);
149 
157  cstring(strsize_t size, char fill);
158 
166  void clear(strsize_t offset, strsize_t size);
167 
174  void set(strsize_t offset, const char *text, strsize_t size);
175 
180  void set(const char *text);
181 
186  void add(const char *text);
187 
192  void add(char character);
193 
197  void fix(void);
198 
203  void unfix(void);
204 
210  void inc(strsize_t number);
211 
217  void dec(strsize_t number);
218  };
219 
220 protected:
221  cstring *str;
229  cstring *create(strsize_t size, char fill = 0) const;
230 
231 public:
239  virtual int compare(const char *string) const;
240 
241  inline int collate(const char *string) const
242  {return compare(string);};
243 
244 protected:
250  bool equal(const char *string) const;
251 
256  virtual void retain(void);
257 
262  virtual void release(void);
263 
268  virtual cstring *c_copy(void) const;
269 
276  virtual void cow(strsize_t size = 0);
277 
278  strsize_t getStringSize(void);
279 
280 public:
284 #if _MSC_VER > 1400 // windows broken dll linkage issue...
285  const static strsize_t npos = ((strsize_t)-1);
286 #else
287  static const strsize_t npos;
288 #endif
289 
290 
294  string();
295 
300  string(long value);
301 
306  string(double value);
307 
312  string(strsize_t size);
313 
319  string(strsize_t size, char fill);
320 
328  string(strsize_t size, const char *format, ...) __PRINTF(3, 4);
329 
330 
335  string(const char *text);
336 
343  string(const char *text, strsize_t size);
344 
351  string(const char *text, const char *end);
352 
358  string(const string& existing);
359 
364  virtual ~string();
365 
372  string get(strsize_t offset, strsize_t size = 0) const;
373 
379  int scanf(const char *format, ...) __SCANF(2, 3);
380 
387  int vscanf(const char *format, va_list args) __SCANF(2, 0);
388 
394  strsize_t printf(const char *format, ...) __PRINTF(2, 3);
395 
402  strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
403 
408  char *c_mem(void) const;
409 
414  const char *c_str(void) const;
415 
421  virtual bool resize(strsize_t size);
422 
427  void set(const char *text);
428 
436  void set(strsize_t offset, const char *text, strsize_t size = 0);
437 
445  void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
446 
454  void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
455 
460  void add(const char *text);
461 
466  void add(char character);
467 
472  void trim(const char *list);
473 
478  inline void trim(strsize_t count = 1)
479  {operator+=(count);};
480 
485  void chop(const char *list);
486 
491  inline void chop(strsize_t count = 1)
492  {operator-=(count);};
493 
498  void strip(const char *list);
499 
505  bool unquote(const char *quote);
506 
512  void cut(strsize_t offset, strsize_t size = 0);
513 
520  void paste(strsize_t offset, const char *text, strsize_t size = 0);
521 
527  void clear(strsize_t offset, strsize_t size = 0);
528 
532  void clear(void);
533 
537  void upper(void);
538 
542  void lower(void);
543 
549  strsize_t ccount(const char *list) const;
550 
555  strsize_t count(void) const;
556 
561  strsize_t size(void) const;
562 
572  strsize_t offset(const char *pointer) const;
573 
579  char at(int position) const;
580 
585  const char *begin(void) const;
586 
591  const char *end(void) const;
592 
599  const char *skip(const char *list, strsize_t offset = 0) const;
600 
608  const char *rskip(const char *list, strsize_t offset = npos) const;
609 
615  const char *search(const char *string, unsigned instance = 0, unsigned flags = 0) const;
616 
617  const char *search(regex& expr, unsigned instance = 0, unsigned flags = 0) const;
618 
619  unsigned replace(const char *string, const char *text = NULL, unsigned flags = 0);
620 
621  unsigned replace(regex& expr, const char *text = NULL, unsigned flags = 0);
622 
629  const char *find(const char *list, strsize_t offset = 0) const;
630 
637  const char *rfind(const char *list, strsize_t offset = npos) const;
638 
644  void split(const char *pointer);
645 
651  void split(strsize_t offset);
652 
658  void rsplit(const char *pointer);
659 
665  void rsplit(strsize_t offset);
666 
672  const char *chr(char character) const;
673 
680  const char *rchr(char character) const;
681 
686  strsize_t len(void);
687 
692  char fill(void);
693 
698  inline operator const char *() const
699  {return c_str();};
700 
705  inline const char *operator*() const
706  {return c_str();};
707 
712  bool full(void) const;
713 
720  string operator()(int offset, strsize_t size) const;
721 
727  inline string left(strsize_t size) const
728  {return operator()(0, size);}
729 
735  inline string right(strsize_t offset) const
736  {return operator()(-((int)offset), 0);}
737 
744  inline string copy(strsize_t offset, strsize_t size) const
745  {return operator()((int)offset, size);}
746 
754  const char *operator()(int offset) const;
755 
761  const char operator[](int offset) const;
762 
767  bool operator!() const;
768 
773  operator bool() const;
774 
780  string& operator^=(const string& object);
781 
786  string& operator|=(const char *text);
787 
788  string& operator&=(const char *text);
789 
795  string& operator+=(const char *text);
796 
802  string& operator^=(const char *text);
803 
810  string& operator+(const char *text);
811 
818  string& operator|(const char *text);
819 
824  string operator^(const char *text);
825 
826 
833  string& operator&(const char *text);
834 
841  string& operator=(const string& object);
842 
843  bool operator*=(const char *substring);
844 
845  bool operator*=(regex& expr);
846 
851  string& operator=(const char *text);
852 
856  string& operator++(void);
857 
862  string& operator+=(strsize_t number);
863 
867  string& operator--(void);
868 
873  string& operator-=(strsize_t number);
874 
879  string& operator*=(strsize_t number);
880 
886  bool operator==(const char *text) const;
887 
893  bool operator!=(const char *text) const;
894 
900  bool operator<(const char *text) const;
901 
907  bool operator<=(const char *text) const;
908 
914  bool operator>(const char *text) const;
915 
921  bool operator>=(const char *text) const;
922 
923  inline string& operator<<(const char *text)
924  {add(text); return *this;}
925 
926  inline string& operator<<(char code)
927  {add(code); return *this;}
928 
934  string &operator%(short& value);
935 
941  string &operator%(unsigned short& value);
942 
948  string &operator%(long& value);
949 
955  string &operator%(unsigned long& value);
956 
962  string &operator%(double& value);
963 
969  string &operator%(const char *text);
970 
977  static int scanf(string& object, const char *format, ...) __SCANF(2, 3);
978 
985  static strsize_t printf(string& object, const char *format, ...) __PRINTF(2, 3);
986 
992  static void swap(string& object1, string& object2);
993 
998  static void fix(string& object);
999 
1004  static void lower(char *text);
1005 
1010  static void upper(char *text);
1011 
1025  static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
1026 
1033  static char *skip(char *text, const char *list);
1034 
1041  static char *rskip(char *text, const char *list);
1042 
1050  static char *unquote(char *text, const char *quote);
1051 
1059  static char *rset(char *buffer, size_t size, const char *text);
1060 
1069  static char *set(char *buffer, size_t size, const char *text);
1070 
1080  static char *set(char *buffer, size_t size, const char *text, size_t max);
1081 
1091  static char *add(char *buffer, size_t size, const char *text);
1092 
1103  static char *add(char *buffer, size_t size, const char *text, size_t max);
1104 
1112  static const char *ifind(const char *text, const char *key, const char *optional);
1113 
1121  static const char *find(const char *text, const char *key, const char *optional);
1122 
1128  static size_t count(const char *text);
1129 
1136  static int compare(const char *text1, const char *text2);
1137 
1138  static inline int collate(const char *text1, const char *text2)
1139  {return compare(text1, text2);};
1140 
1147  static bool equal(const char *text1, const char *text2);
1148 
1156  static int compare(const char *text1, const char *text2, size_t size);
1157 
1165  static bool equal(const char *text1, const char *text2, size_t size);
1166 
1173  static int case_compare(const char *text1, const char *text2);
1174 
1181  static bool case_equal(const char *text1, const char *text2);
1182 
1190  static int case_compare(const char *text1, const char *text2, size_t size);
1191 
1199  static bool case_equal(const char *text1, const char *text2, size_t size);
1200 
1208  static char *trim(char *text, const char *list);
1209 
1217  static char *chop(char *text, const char *list);
1218 
1226  static char *strip(char *text, const char *list);
1227 
1236  static char *fill(char *text, size_t size, char character);
1237 
1244  static unsigned ccount(const char *text, const char *list);
1245 
1252  static char *find(char *text, const char *list);
1253 
1260  static size_t seek(char *text, const char *list);
1261 
1268  static char *rfind(char *text, const char *list);
1269 
1275  static char *dup(const char *text);
1276 
1283  static char *left(const char *text, size_t size);
1284 
1291  static const char *pos(const char *text, ssize_t offset);
1292 
1293  inline static char *right(const char *text, size_t size)
1294  {return dup(pos(text, -(signed)size));}
1295 
1296  inline static char *copy(const char *text, size_t offset, size_t len)
1297  {return left(pos(text, offset), len);}
1298 
1299  static void cut(char *text, size_t offset, size_t len);
1300 
1301  static void paste(char *text, size_t max, size_t offset, const char *data, size_t len = 0);
1302 
1316  inline static char *token(string& object, char **last, const char *list, const char *quote = NULL, const char *end = NULL)
1317  {return token(object.c_mem(), last, list, quote, end);};
1318 
1326  __SCANF(2,0) inline static int vscanf(string& object, const char *format, va_list args)
1327  {return object.vscanf(format, args);}
1328 
1336  __PRINTF(2,0) inline static strsize_t vprintf(string& object, const char *format, va_list args)
1337  {return object.vprintf(format, args);}
1338 
1344  inline static strsize_t len(string& object)
1345  {return object.len();};
1346 
1352  inline static char *mem(string& object)
1353  {return object.c_mem();};
1354 
1360  inline static strsize_t size(string& object)
1361  {return object.size();};
1362 
1367  inline static void clear(string& object)
1368  {object.clear();};
1369 
1376  inline static unsigned ccount(string& object, const char *list)
1377  {return object.ccount(list);};
1378 
1384  inline static size_t count(string& object)
1385  {return object.count();}
1386 
1387  inline static string copy(string& object, strsize_t offset, strsize_t size)
1388  {return object.copy(offset, size);}
1389 
1390  inline static string left(string& object, strsize_t size)
1391  {return object.left(size);}
1392 
1393  inline static string right(string& object, strsize_t offset)
1394  {return object.right(offset);}
1395 
1396  inline static void cut(string& object, strsize_t offset, strsize_t size)
1397  {object.cut(offset, size);}
1398 
1399  inline static void paste(string& object, strsize_t offset, const char *text, strsize_t size = 0)
1400  {object.paste(offset, text, size);}
1401 
1406  inline static void upper(string& object)
1407  {object.upper();}
1408 
1413  inline static void lower(string& object)
1414  {object.lower();}
1415 
1422  inline static bool unquote(string& object, const char *quote)
1423  {return object.unquote(quote);}
1424 
1430  inline static void trim(string& object, const char *list)
1431  {object.trim(list);}
1432 
1438  inline static void trim(string& object, strsize_t count = 1)
1439  {object.trim(count);}
1440 
1446  inline static void chop(string& object, const char *list)
1447  {object.chop(list);}
1448 
1454  inline static void chop(string& object, strsize_t count = 1)
1455  {object.chop(count);}
1456 
1462  inline static void strip(string& object, const char *list)
1463  {object.strip(list);}
1464 
1471  inline static const char *find(string& object, const char *list)
1472  {return object.find(list);}
1473 
1474  inline static const char *search(string& object, const char *substring, unsigned instance = 0, unsigned flags = 0)
1475  {return object.search(substring, instance, flags);}
1476 
1477  inline static const char *search(string& object, regex& expr, unsigned instance = 0, unsigned flags = 0)
1478  {return object.search(expr, instance, flags);}
1479 
1480  inline static unsigned replace(string& object, regex& expr, const char *text, unsigned flags = 0)
1481  {return object.replace(expr, text, flags);}
1482 
1483  inline static unsigned replace(string& object, const char *match, const char *text, bool flag = false)
1484  {return object.replace(match, text, flag);}
1485 
1486  inline static bool search(regex& expr, const char *text, unsigned flags = 0)
1487  {return expr.match(text, flags);}
1488 
1495  inline static const char *rfind(string& object, const char *list)
1496  {return object.rfind(list);}
1497 
1504  inline static double tod(string& object, char **pointer = NULL)
1505  {return strtod(mem(object), pointer);}
1506 
1513  inline static long tol(string& object, char **pointer = NULL)
1514  {return strtol(mem(object), pointer, 0);}
1515 
1522  inline static double tod(const char *text, char **pointer = NULL)
1523  {return strtod(text, pointer);}
1524 
1531  inline static long tol(const char *text, char **pointer = NULL)
1532  {return strtol(text, pointer, 0);}
1533 
1542  static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
1543 
1551  static size_t b64decode(uint8_t *binary, const char *string, size_t size);
1552 
1559  static uint32_t crc24(uint8_t *binary, size_t size);
1560 
1567  static uint16_t crc16(uint8_t *binary, size_t size);
1568 
1576  static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
1577 
1585  static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
1586 
1587  static unsigned hexsize(const char *format);
1588 };
1589 
1597 class __EXPORT memstring : public string
1598 {
1599 public:
1600 #if _MSC_VER > 1400 // windows broken dll linkage issue...
1601  const static size_t header = sizeof(string::cstring);
1602 #else
1603  static const size_t header;
1604 #endif
1605 
1606 private:
1607  bool resize(strsize_t size);
1608  void cow(strsize_t adj = 0);
1609  void release(void);
1610 
1611 protected:
1612  cstring *c_copy(void) const;
1613 
1614 public:
1619  inline void operator=(string& object)
1620  {set(object.c_str());};
1621 
1626  inline void operator=(const char *text)
1627  {set(text);};
1628 
1635  memstring(void *memory, strsize_t size, char fill = 0);
1636 
1640  ~memstring();
1641 
1647  static memstring *create(strsize_t size, char fill = 0);
1648 
1655  static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
1656 };
1657 
1665 template<size_t S>
1666 class charbuf
1667 {
1668 private:
1669  char buffer[S];
1670 
1671 public:
1675  inline charbuf()
1676  {buffer[0] = 0;};
1677 
1683  inline charbuf(const char *text)
1684  {string::set(buffer, S, text);};
1685 
1690  inline void operator=(const char *text)
1691  {string::set(buffer, S, text);};
1692 
1698  inline void operator+=(const char *text)
1699  {string::add(buffer, S, text);};
1700 
1705  inline operator bool() const
1706  {return buffer[0];};
1707 
1712  inline bool operator!() const
1713  {return buffer[0] == 0;};
1714 
1719  inline operator char *()
1720  {return buffer;};
1721 
1726  inline char *operator*()
1727  {return buffer;};
1728 
1734  inline char operator[](size_t offset) const
1735  {return buffer[offset];};
1736 
1742  inline char *operator()(size_t offset)
1743  {return buffer + offset;};
1744 
1749  inline size_t size(void) const
1750  {return S;};
1751 };
1752 
1756 typedef string string_t;
1757 
1758 typedef string::regex stringex_t;
1759 
1764 typedef string String;
1765 
1776 template<strsize_t S>
1777 class stringbuf : public memstring
1778 {
1779 private:
1780  char buffer[sizeof(cstring) + S];
1781 
1782 public:
1786  inline stringbuf() : memstring(buffer, S) {};
1787 
1792  inline stringbuf(const char *text) : memstring(buffer, S) {set(text);};
1793 
1798  inline void operator=(const char *text)
1799  {set(text);};
1800 
1805  inline void operator=(string& object)
1806  {set(object.c_str());};
1807 };
1808 
1809 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
1810 
1817 extern "C" inline int stricmp(const char *string1, const char *string2)
1818  {return string::case_compare(string1, string2);}
1819 
1827 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max)
1828  {return string::case_compare(string1, string2, max);}
1829 
1830 #endif
1831 
1838 inline bool eq(char const *s1, char const *s2)
1839  {return String::equal(s1, s2);}
1840 
1841 inline bool ne(char const *s1, char const *s2)
1842  {return !String::equal(s1, s2);}
1843 
1851 inline bool eq(char const *s1, char const *s2, size_t size)
1852  {return String::equal(s1, s2, size);}
1853 
1854 inline bool ne(char const *s1, char const *s2, size_t size)
1855  {return !String::equal(s1, s2, size);}
1856 
1866 inline bool eq(String &s1, const char *s2)
1867  {return s1.compare(s2) == 0;}
1868 
1869 inline bool ne(String &s1, String &s2)
1870  {return s1.compare(s2) != 0;}
1871 
1872 inline bool lt(String &s1, const char *s2)
1873  {return s1.compare(s2) < 0;}
1874 
1875 inline bool gt(String &s1, const char *s2)
1876  {return s1.compare(s2) > 0;}
1877 
1878 inline bool le(String &s1, const char *s2)
1879  {return s1.compare(s2) <= 0;}
1880 
1881 inline bool ge(String &s1, const char *s2)
1882  {return s1.compare(s2) >= 0;}
1883 
1891 inline bool case_eq(char const *s1, char const *s2)
1892  {return String::case_equal(s1, s2);}
1893 
1894 inline bool case_ne(char const *s1, char const *s2)
1895  {return !String::case_equal(s1, s2);}
1896 
1897 // to be depreciated...
1898 inline bool ieq(char const *s1, char const *s2)
1899  {return String::case_equal(s1, s2);}
1900 
1909 inline bool case_eq(char const *s1, char const *s2, size_t size)
1910  {return String::case_equal(s1, s2, size);}
1911 
1912 inline bool ieq(char const *s1, char const *s2, size_t size)
1913  {return String::case_equal(s1, s2, size);}
1914 
1915 inline String str(const char *string)
1916  {return (String)string;}
1917 
1918 inline String str(String& string)
1919  {return (String)string;}
1920 
1921 inline String str(short value)
1922  {String temp(16, "%hd", value); return temp;}
1923 
1924 inline String str(unsigned short value)
1925  {String temp(16, "%hu", value); return temp;}
1926 
1927 inline String str(long value)
1928  {String temp(32, "%ld", value); return temp;}
1929 
1930 inline String str(unsigned long value)
1931  {String temp(32, "%lu", value); return temp;}
1932 
1933 inline String str(double value)
1934  {String temp(40, "%f", value); return temp;}
1935 
1936 String str(CharacterProtocol& cp, strsize_t size);
1937 
1938 template<>
1939 inline void swap<string_t>(string_t& s1, string_t& s2)
1940  {String::swap(s1, s2);}
1941 
1942 class __EXPORT strdup_t
1943 {
1944 private:
1945  char *data;
1946 
1947 public:
1948  inline strdup_t()
1949  {data = NULL;}
1950 
1951  inline strdup_t(char *str)
1952  {data = str;}
1953 
1954  inline ~strdup_t()
1955  {if(data) ::free(data);}
1956 
1957  inline strdup_t& operator=(char *str)
1958  {if(data) ::free(data); data = str; return *this;}
1959 
1960  inline operator bool() const
1961  {return data != NULL;}
1962 
1963  inline bool operator!() const
1964  {return data == NULL;}
1965 
1966  inline operator char*() const
1967  {return data;}
1968 
1969  inline const char *c_str(void) const
1970  {return data;};
1971 
1972  inline const char *operator*() const
1973  {return data;}
1974 
1975  inline char& operator[](int size)
1976  {return data[size];}
1977 
1978  inline char *operator+(size_t size)
1979  {return data + size;}
1980 };
1981 
1982 
1983 END_NAMESPACE
1984 
1985 #endif