UCommon
string.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This file is part of GNU uCommon C++.
5 //
6 // GNU uCommon C++ is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GNU uCommon C++ is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18 
36 #ifndef _UCOMMON_STRING_H_
37 #define _UCOMMON_STRING_H_
38 
39 #ifndef _UCOMMON_CPR_H_
40 #include <ucommon/cpr.h>
41 #endif
42 
43 #ifndef _UCOMMON_GENERICS_H_
44 #include <ucommon/generics.h>
45 #endif
46 
47 #ifndef _UCOMMON_PROTOCOLS_H_
48 #include <ucommon/protocols.h>
49 #endif
50 
51 #ifndef _UCOMMON_OBJECT_H_
52 #include <ucommon/object.h>
53 #endif
54 
55 #include <stdio.h>
56 #include <string.h>
57 #include <stdarg.h>
58 
59 #ifdef HAVE_DIRENT_H
60 #include <dirent.h>
61 #endif
62 
63 #define PGP_B64_WIDTH 64
64 #define MIME_B64_WIDTH 76
65 
66 namespace ucommon {
67 
78 class __EXPORT String : public __PROTOCOL ObjectProtocol
79 {
80 protected:
92 public:
93  enum {
94  SENSITIVE = 0x00,
95  INSENSITIVE = 0x01
96  };
97 
98  class __EXPORT regex
99  {
100  private:
101  void *object;
102  void *results;
103  size_t count;
104 
105  __DELETE_COPY(regex);
106 
107  public:
108  regex(const char *pattern, size_t size = 1);
109  regex(size_t size = 1);
110  ~regex();
111 
112  size_t offset(unsigned member);
113  size_t size(unsigned member);
114 
115  inline size_t members(void) const {
116  return count;
117  }
118 
119  bool match(const char *text, unsigned flags = 0);
120 
121  regex& operator=(const char *string);
122 
123  bool operator*=(const char *string);
124 
125  operator bool() const {
126  return object != NULL;
127  }
128 
129  bool operator!() const {
130  return object == NULL;
131  }
132  };
133 
134  class __EXPORT cstring : public CountedObject
135  {
136  private:
137  __DELETE_COPY(cstring);
138 
139  protected:
140  virtual void dealloc(void) __OVERRIDE;
141 
142  public:
143 #pragma pack(1)
144  size_t max;
145  size_t len;
146  char text[1];
147 #pragma pack()
148 
154  cstring(size_t size);
155 
160  void clear(size_t offset);
161 
168  void set(size_t offset, const char *text, size_t size);
169 
174  void set(const char *text);
175 
180  void add(const char *text);
181 
186  void add(char character);
187 
191  void fix(void);
192 
198  void inc(size_t number);
199 
205  void dec(size_t number);
206  };
207 
208 protected:
209  cstring *str;
216  cstring *create(size_t size) const;
217 
218 public:
226  virtual int compare(const char *string) const;
227 
228 protected:
234  bool equal(const char *string) const;
235 
240  virtual void retain(void) __OVERRIDE;
241 
246  virtual void release(void) __OVERRIDE;
247 
252  virtual cstring *c_copy(void) const;
253 
260  virtual void cow(size_t size = 0);
261 
262  size_t getStringSize(void) const;
263 
264 public:
265  const static size_t npos = ((size_t)-1);
266  const static char eos = '\0';
267 
271  String();
272 
277  String(size_t size);
278 
286  String(size_t size, const char *format, ...);
287 
288 
293  String(const char *text);
294 
301  String(const char *text, size_t size);
302 
309  String(const char *text, const char *end);
310 
316  String(const String& existing);
317 
322  virtual ~String();
323 
330  String get(size_t offset, size_t size = 0) const;
331 
337  int scanf(const char *format, ...) __SCANF(2, 3);
338 
345  int vscanf(const char *format, va_list args) __SCANF(2, 0);
346 
352  size_t printf(const char *format, ...) __PRINTF(2, 3);
353 
360  size_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
361 
366  char *data(void);
367 
368  inline char *c_mem() {
369  return data();
370  }
371 
376  const char *c_str(void) const;
377 
383  virtual bool resize(size_t size);
384 
389  void set(const char *text);
390 
398  void set(size_t offset, const char *text, size_t size = 0);
399 
407  void set(const char *text, char overflow, size_t offset, size_t size = 0);
408 
416  void rset(const char *text, char overflow, size_t offset, size_t size = 0);
417 
422  void add(const char *text);
423 
428  void add(char character);
429 
434  void trim(const char *list);
435 
440  inline void trim(size_t count = 1) {
441  operator+=(count);
442  }
443 
448  void chop(const char *list);
449 
454  inline void chop(size_t count = 1) {
455  operator-=(count);
456  }
457 
462  void strip(const char *list);
463 
469  bool unquote(const char *quote);
470 
476  void cut(size_t offset, size_t size = 0);
477 
484  void paste(size_t offset, const char *text, size_t size = 0);
485 
490  void clear(size_t offset);
491 
495  void clear(void);
496 
500  void upper(void);
501 
505  void lower(void);
506 
510  void erase(void);
511 
517  size_t ccount(const char *list) const;
518 
523  size_t count(void) const;
524 
529  size_t size(void) const;
530 
540  size_t offset(const char *pointer) const;
541 
547  char at(int position) const;
548 
553  const char *begin(void) const;
554 
559  const char *end(void) const;
560 
567  const char *skip(const char *list, size_t offset = 0) const;
568 
576  const char *rskip(const char *list, size_t offset = npos) const;
577 
583  const char *search(const char *string, unsigned instance = 0, unsigned flags = 0) const;
584 
585  const char *search(regex& expr, unsigned instance = 0, unsigned flags = 0) const;
586 
587  unsigned replace(const char *string, const char *text = NULL, unsigned flags = 0);
588 
589  unsigned replace(regex& expr, const char *text = NULL, unsigned flags = 0);
590 
597  const char *find(const char *list, size_t offset = 0) const;
598 
605  const char *rfind(const char *list, size_t offset = npos) const;
606 
612  void split(const char *pointer);
613 
619  void split(size_t offset);
620 
621  void fill(size_t size, char fill);
622 
628  void rsplit(const char *pointer);
629 
635  void rsplit(size_t offset);
636 
642  const char *chr(char character) const;
643 
650  const char *rchr(char character) const;
651 
656  size_t len(void) const;
657 
662  inline operator const char *() const {
663  return c_str();
664  }
665 
670  inline const char *operator*() const {
671  return c_str();
672  }
673 
678  bool full(void) const;
679 
686  String operator()(int offset, size_t size) const;
687 
693  inline String left(size_t size) const {
694  return operator()(0, size);
695  }
696 
702  inline String right(size_t offset) const {
703  return operator()(-((int)offset), 0);
704  }
705 
712  inline String copy(size_t offset, size_t size) const {
713  return operator()((int)offset, size);
714  }
715 
723  const char *operator()(int offset) const;
724 
730  const char operator[](int offset) const;
731 
736  bool operator!() const;
737 
742  operator bool() const;
743 
749  String& operator^=(const String& object);
750 
755  String& operator|=(const char *text);
756 
757  String& operator&=(const char *text);
758 
764  String& operator+=(const char *text);
765 
771  String& operator^=(const char *text);
772 
777  const String operator+(const char *text) const;
778 
785  String& operator|(const char *text);
786 
793  String& operator&(const char *text);
794 
801  String& operator=(const String& object);
802 
803  bool operator*=(const char *substring);
804 
805  bool operator*=(regex& expr);
806 
811  String& operator=(const char *text);
812 
816  String& operator++(void);
817 
822  String& operator+=(size_t number);
823 
827  String& operator--(void);
828 
833  String& operator-=(size_t number);
834 
839  String& operator*=(size_t number);
840 
846  bool operator==(const char *text) const;
847 
853  bool operator!=(const char *text) const;
854 
860  bool operator<(const char *text) const;
861 
867  bool operator<=(const char *text) const;
868 
874  bool operator>(const char *text) const;
875 
881  bool operator>=(const char *text) const;
882 
883  inline String& operator<<(const char *text) {
884  add(text); return *this;
885  }
886 
887  inline String& operator<<(char code) {
888  add(code); return *this;
889  }
890 
896  String &operator%(short& value);
897 
903  String &operator%(unsigned short& value);
904 
910  String &operator%(long& value);
911 
917  String &operator%(unsigned long& value);
918 
924  String &operator%(double& value);
925 
931  String &operator%(const char *text);
932 
938  static void swap(String& object1, String& object2);
939 
944  static void fix(String& object);
945 
953  static bool check(const char *string, size_t maximum, size_t minimum = 0);
954 
959  static void erase(char *text);
960 
965  static void lower(char *text);
966 
971  static void upper(char *text);
972 
986  static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
987 
994  static char *skip(char *text, const char *list);
995 
1002  static char *rskip(char *text, const char *list);
1003 
1011  static char *unquote(char *text, const char *quote);
1012 
1020  static char *rset(char *buffer, size_t size, const char *text);
1021 
1030  static char *set(char *buffer, size_t size, const char *text);
1031 
1041  static char *set(char *buffer, size_t size, const char *text, size_t max);
1042 
1052  static char *add(char *buffer, size_t size, const char *text);
1053 
1064  static char *add(char *buffer, size_t size, const char *text, size_t max);
1065 
1073  static const char *ifind(const char *text, const char *key, const char *optional);
1074 
1082  static const char *find(const char *text, const char *key, const char *optional);
1083 
1089  static size_t count(const char *text);
1090 
1097  static int compare(const char *text1, const char *text2);
1098 
1099  inline static int collate(const char *text1, const char *text2) {
1100  return compare(text1, text2);
1101  }
1102 
1109  static bool equal(const char *text1, const char *text2);
1110 
1118  static int compare(const char *text1, const char *text2, size_t size);
1119 
1127  static bool equal(const char *text1, const char *text2, size_t size);
1128 
1135  static bool eq_case(const char *text1, const char *text2);
1136 
1144  static bool eq_case(const char *text1, const char *text2, size_t size);
1145 
1153  static char *trim(char *text, const char *list);
1154 
1162  static char *chop(char *text, const char *list);
1163 
1171  static char *strip(char *text, const char *list);
1172 
1181  static char *fill(char *text, size_t size, char character);
1182 
1189  static unsigned ccount(const char *text, const char *list);
1190 
1197  static char *find(char *text, const char *list);
1198 
1205  static size_t seek(char *text, const char *list);
1206 
1213  static char *rfind(char *text, const char *list);
1214 
1220  static char *dup(const char *text);
1221 
1228  static char *left(const char *text, size_t size);
1229 
1236  static const char *pos(const char *text, ssize_t offset);
1237 
1238  inline static char *right(const char *text, size_t size) {
1239  return dup(pos(text, -(ssize_t)size));
1240  }
1241 
1242  inline static char *copy(const char *text, size_t offset, size_t len) {
1243  return left(pos(text, (ssize_t)offset), len);
1244  }
1245 
1246  static void cut(char *text, size_t offset, size_t len);
1247 
1248  static void paste(char *text, size_t max, size_t offset, const char *data, size_t len = 0);
1249 
1262  inline char *token(char **last, const char *list, const char *quote = NULL, const char *end = NULL) {
1263  return token(data(), last, list, quote, end);
1264  }
1265 
1272  inline double tod(char **pointer = NULL) {
1273  return strtod(data(), pointer);
1274  }
1275 
1282  inline long tol(char **pointer = NULL) {
1283  return strtol(data(), pointer, 0);
1284  }
1285 
1292  inline static double tod(const char *text, char **pointer = NULL) {
1293  return strtod(text, pointer);
1294  }
1295 
1302  inline static long tol(const char *text, char **pointer = NULL) {
1303  return strtol(text, pointer, 0);
1304  }
1305 
1312  static String b64(const uint8_t *binary, size_t size);
1313 
1314  static size_t b64size(size_t size);
1315 
1324  static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
1325 
1334  static size_t b64decode(uint8_t *binary, const char *string, size_t size, bool ws = false);
1335 
1336  static size_t b64count(const char *str, bool ws = false);
1337 
1344  static uint32_t crc24(uint8_t *binary, size_t size);
1345 
1352  static uint16_t crc16(uint8_t *binary, size_t size);
1353 
1360  static String hex(const uint8_t *binary, size_t size);
1361 
1369  static size_t hexdump(const uint8_t *binary, char *string, const char *format);
1370 
1379  static size_t hexpack(uint8_t *binary, const char *string, const char *format);
1380 
1381  static size_t hex2bin(const char *string, uint8_t *binary, size_t maxsize, bool wsflag = false);
1382 
1383  static size_t hexsize(const char *format);
1384 
1385  static size_t hexcount(const char *str, bool ws = false);
1386 };
1387 
1395 class __EXPORT memstring : public String
1396 {
1397 public:
1398  const static size_t header = sizeof(String::cstring);
1399 
1400 private:
1401  bool resize(size_t size) __FINAL;
1402  void cow(size_t adj = 0) __FINAL;
1403  void release(void) __FINAL;
1404 
1405 protected:
1406  cstring *c_copy(void) const __OVERRIDE;
1407 
1408 public:
1413  inline void operator=(String& object) {
1414  set(object.c_str());
1415  }
1416 
1421  inline void operator=(const char *text) {
1422  set(text);
1423  }
1424 
1430  memstring(void *memory, size_t size);
1431 
1435  ~memstring();
1436 
1441  static memstring *create(size_t size);
1442 
1448  static memstring *create(MemoryProtocol *pager, size_t size);
1449 };
1450 
1458 template<size_t S>
1459 class charbuf
1460 {
1461 private:
1462  char buffer[S];
1463 
1464 public:
1468  inline charbuf() {
1469  buffer[0] = 0;
1470  }
1471 
1477  inline charbuf(const char *text) {
1478  String::set(buffer, S, text);
1479  }
1480 
1484  inline charbuf(const charbuf& copy) {
1485  String::set(buffer, S, copy.buffer);
1486  }
1487 
1492  inline void operator=(const char *text) {
1493  String::set(buffer, S, text);
1494  }
1495 
1501  inline void operator+=(const char *text) {
1502  String::add(buffer, S, text);
1503  }
1504 
1509  inline operator bool() const {
1510  return buffer[0];
1511  }
1512 
1517  inline bool operator!() const {
1518  return buffer[0] == 0;
1519  }
1520 
1525  inline operator char *() {
1526  return buffer;
1527  }
1528 
1533  inline char *operator*() {
1534  return buffer;
1535  }
1536 
1542  inline char& operator[](size_t offset) const {
1543  if(offset >= S)
1544  __THROW_RANGE("charbuf offset");
1545  return buffer[offset];
1546  }
1547 
1553  inline char *operator()(size_t offset) {
1554  if(offset >= S)
1555  __THROW_RANGE("charbuf range");
1556  return buffer + offset;
1557  }
1558 
1563  inline size_t size(void) const {
1564  return S;
1565  }
1566 
1571  inline size_t len(void) const {
1572  return strlen(buffer);
1573  }
1574 };
1575 
1580 
1581 typedef String::regex stringex_t;
1582 
1593 template<size_t S>
1594 class stringbuf : public memstring
1595 {
1596 private:
1597  char buffer[sizeof(cstring) + S];
1598 
1599 public:
1603  inline stringbuf() : memstring(buffer, S) {}
1604 
1609  inline stringbuf(const char *text) : memstring(buffer, S) {
1610  set(text);
1611  }
1612 
1617  inline void operator=(const char *text) {
1618  set(text);
1619  }
1620 
1625  inline void operator=(String& object) {
1626  set(object.c_str());
1627  }
1628 };
1629 
1636 inline bool eq(char const *s1, char const *s2) {
1637  return String::equal(s1, s2);
1638 }
1639 
1640 inline bool ne(char const *s1, char const *s2) {
1641  return !String::equal(s1, s2);
1642 }
1643 
1651 inline bool eq(char const *s1, char const *s2, size_t size) {
1652  return String::equal(s1, s2, size);
1653 }
1654 
1655 inline bool ne(char const *s1, char const *s2, size_t size) {
1656  return !String::equal(s1, s2, size);
1657 }
1658 
1668 inline bool eq(String &s1, const char *s2) {
1669  return s1.compare(s2) == 0;
1670 }
1671 
1672 inline bool ne(String &s1, String &s2) {
1673  return s1.compare(s2) != 0;
1674 }
1675 
1676 inline bool lt(String &s1, const char *s2) {
1677  return s1.compare(s2) < 0;
1678 }
1679 
1680 inline bool gt(String &s1, const char *s2) {
1681  return s1.compare(s2) > 0;
1682 }
1683 
1684 inline bool le(String &s1, const char *s2) {
1685  return s1.compare(s2) <= 0;
1686 }
1687 
1688 inline bool ge(String &s1, const char *s2) {
1689  return s1.compare(s2) >= 0;
1690 }
1691 
1699 inline bool eq_case(char const *s1, char const *s2)
1700  {return String::eq_case(s1, s2);}
1701 
1702 inline bool ne_case(char const *s1, char const *s2)
1703  {return !String::eq_case(s1, s2);}
1704 
1713 inline bool eq_case(char const *s1, char const *s2, size_t size) {
1714  return String::eq_case(s1, s2, size);
1715 }
1716 
1717 inline String str(const char *string) {
1718  return (String)string;
1719 }
1720 
1721 inline String str(String& string) {
1722  return (String)string;
1723 }
1724 
1725 inline String str(short value) {
1726  String temp(16, "%hd", value); return temp;
1727 }
1728 
1729 inline String str(unsigned short value) {
1730  String temp(16, "%hu", value); return temp;
1731 }
1732 
1733 inline String str(long value) {
1734  String temp(32, "%ld", value); return temp;
1735 }
1736 
1737 inline String str(unsigned long value) {
1738  String temp(32, "%lu", value); return temp;
1739 }
1740 
1741 inline String str(double value) {
1742  String temp(40, "%f", value); return temp;
1743 }
1744 
1745 template<>
1746 inline void swap<string_t>(string_t& s1, string_t& s2) {
1747  String::swap(s1, s2);
1748 }
1749 
1750 class __EXPORT strdup_t
1751 {
1752 private:
1753  char *data;
1754 
1755 public:
1756  inline strdup_t() {
1757  data = NULL;
1758  }
1759 
1760  inline strdup_t(char *str) {
1761  data = str;
1762  }
1763 
1764  inline ~strdup_t() {
1765  if(data)
1766  ::free(data);
1767  }
1768 
1769  inline strdup_t& operator=(char *str) {
1770  if(data)
1771  ::free(data);
1772  data = str;
1773  return *this;
1774  }
1775 
1776  inline operator bool() const {
1777  return data != nullptr;
1778  }
1779 
1780  inline bool operator!() const {
1781  return data == nullptr;
1782  }
1783 
1784  inline operator char*() const {
1785  return data;
1786  }
1787 
1788  inline const char *c_str(void) const {
1789  return data;
1790  }
1791 
1792  inline const char *operator*() const {
1793  return data;
1794  }
1795 
1796  inline char& operator[](int size) {
1797  return data[size];
1798  }
1799 
1800  inline char *operator+(size_t size) {
1801  return data + size;
1802  }
1803 };
1804 
1805 } // namespace ucommon
1806 
1807 #endif
A common base class for all managed objects.
Definition: protocols.h:173
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:445
String string_t
A convenience type for string.
Definition: string.h:1579
Mempager managed type factory for pager pool objects.
Definition: memory.h:853
char & operator[](size_t offset) const
Array operator to get a character from the object.
Definition: string.h:1542
virtual int compare(const char *string) const
Compare the values of two string.
char * operator *()
Get text by object pointer reference.
Definition: string.h:1533
A string class that uses a cstring buffer that is fixed in memory.
Definition: string.h:1395
char * token(char **last, const char *list, const char *quote=NULL, const char *end=NULL)
A thread-safe token parsing routine for strings objects.
Definition: string.h:1262
String copy(size_t offset, size_t size) const
Convenience method for substring extraction.
Definition: string.h:712
bool eq(const struct sockaddr *s1, const struct sockaddr *s2)
Compare two socket addresses to see if equal.
Definition: socket.h:2100
A copy-on-write string class that operates by reference count.
Definition: string.h:78
bool operator!() const
Test if the object is empty.
Definition: string.h:1517
void operator=(const char *text)
Assign a string buffer from a null terminated string.
Definition: string.h:1617
void trim(size_t count=1)
Trim lead characters from text.
Definition: string.h:440
A string class that has a predefined string buffer.
Definition: string.h:1594
size_t len(void) const
Get current length of string.
Definition: string.h:1571
A common string class and character string support functions.
void operator=(String &object)
Assign a string buffer from another string object.
Definition: string.h:1625
stringbuf(const char *text)
Create a string buffer from a null terminated string.
Definition: string.h:1609
bool equal(const char *string) const
Test if two string values are equal.
A common object base class with auto-pointer support.
char * operator()(size_t offset)
Get a pointer to an offset in the object by expression operator.
Definition: string.h:1553
size_t size(void) const
Get allocated size of the object.
Definition: string.h:1563
String left(size_t size) const
Convenience method for left of string.
Definition: string.h:693
charbuf()
Create a new character buffer with an empty string.
Definition: string.h:1468
charbuf(const charbuf &copy)
Copy constructor.
Definition: string.h:1484
stringbuf()
Create an empty instance of a string buffer.
Definition: string.h:1603
static long tol(const char *text, char **pointer=NULL)
Convert text to a long value.
Definition: string.h:1302
void operator+=(const char *text)
Concatenate text into the object.
Definition: string.h:1501
static void swap(String &object1, String &object2)
Swap the cstring references between two strings.
void add(const char *text)
Append null terminated text to our string buffer.
void set(const char *text)
Set string object to text of a null terminated string.
Common namespace for all ucommon objects.
Definition: access.h:47
T * dup(const T &object)
Convenience function to duplicate object pointer to heap.
Definition: generics.h:324
T copy(const T &src)
Convenience function to copy objects.
Definition: generics.h:395
Abstract interfaces and support.
bool eq_case(char const *s1, char const *s2)
Compare two null terminated strings if equal ignoring case.
Definition: string.h:1699
static bool eq_case(const char *text1, const char *text2)
Simple case insensitive equal test for strings.
double tod(char **pointer=NULL)
Convert string to a double value.
Definition: string.h:1272
void operator=(const char *text)
Assign null terminated text to our object.
Definition: string.h:1421
void swap(T &o1, T &o2)
Convenience function to swap objects.
Definition: generics.h:387
long tol(char **pointer=NULL)
Convert string to a long value.
Definition: string.h:1282
void operator=(const char *text)
Assign null terminated text to the object.
Definition: string.h:1492
void operator=(String &object)
Assign the text of a string to our object.
Definition: string.h:1413
A base class for reference counted objects.
Definition: object.h:56
Generic templates for C++.
static double tod(const char *text, char **pointer=NULL)
Convert text to a double value.
Definition: string.h:1292
A template to create a character array that can be manipulated as a string.
Definition: string.h:1459
const char * c_str(void) const
Get character text buffer of string object.
Runtime functions.
Generic smart pointer class.
Definition: generics.h:54
void chop(size_t count=1)
Chop trailing characters from text.
Definition: string.h:454
String right(size_t offset) const
Convenience method for right of string.
Definition: string.h:702
cstring * str
cstring instance our object references.
Definition: string.h:209
charbuf(const char *text)
Create a character buffer with assigned text.
Definition: string.h:1477