ucommon
string.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 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 size = 1);
111  regex(size_t size = 1);
112  ~regex();
113 
114  size_t offset(unsigned member);
115  size_t size(unsigned member);
116 
117  inline size_t members(void) const
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() const
127  {return object != NULL;}
128 
129  bool operator!() const
130  {return object == NULL;}
131  };
132 
133  class __EXPORT cstring : public CountedObject
134  {
135  protected:
136  void dealloc(void);
137 
138  public:
139 #pragma pack(1)
140  strsize_t max;
141  strsize_t len;
142  char fill;
143  char text[1];
144 #pragma pack()
145 
151  cstring(strsize_t size);
152 
160  cstring(strsize_t size, char fill);
161 
169  void clear(strsize_t offset, strsize_t size);
170 
177  void set(strsize_t offset, const char *text, strsize_t size);
178 
183  void set(const char *text);
184 
189  void add(const char *text);
190 
195  void add(char character);
196 
200  void fix(void);
201 
206  void unfix(void);
207 
213  void inc(strsize_t number);
214 
220  void dec(strsize_t number);
221  };
222 
223 protected:
224  cstring *str;
232  cstring *create(strsize_t size, char fill = 0) const;
233 
234 public:
242  virtual int compare(const char *string) const;
243 
244  inline int collate(const char *string) const
245  {return compare(string);}
246 
247 protected:
253  bool equal(const char *string) const;
254 
259  virtual void retain(void);
260 
265  virtual void release(void);
266 
271  virtual cstring *c_copy(void) const;
272 
279  virtual void cow(strsize_t size = 0);
280 
281  strsize_t getStringSize(void) const;
282 
283 public:
287 #if _MSC_VER > 1400 // windows broken dll linkage issue...
288  const static strsize_t npos = ((strsize_t)-1);
289 #else
290  static const strsize_t npos;
291 #endif
292 
293 
297  String();
298 
303  String(long value);
304 
309  String(double value);
310 
315  String(strsize_t size);
316 
322  String(strsize_t size, char fill);
323 
331  String(strsize_t size, const char *format, ...) __PRINTF(3, 4);
332 
333 
338  String(const char *text);
339 
346  String(const char *text, strsize_t size);
347 
354  String(const char *text, const char *end);
355 
361  String(const String& existing);
362 
367  virtual ~String();
368 
375  String get(strsize_t offset, strsize_t size = 0) const;
376 
382  int scanf(const char *format, ...) __SCANF(2, 3);
383 
390  int vscanf(const char *format, va_list args) __SCANF(2, 0);
391 
397  strsize_t printf(const char *format, ...) __PRINTF(2, 3);
398 
405  strsize_t vprintf(const char *format, va_list args) __PRINTF(2, 0);
406 
411  char *c_mem(void) const;
412 
417  const char *c_str(void) const;
418 
424  virtual bool resize(strsize_t size);
425 
430  void set(const char *text);
431 
439  void set(strsize_t offset, const char *text, strsize_t size = 0);
440 
448  void set(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
449 
457  void rset(const char *text, char overflow, strsize_t offset, strsize_t size = 0);
458 
463  void add(const char *text);
464 
469  void add(char character);
470 
475  void trim(const char *list);
476 
481  inline void trim(strsize_t count = 1)
482  {operator+=(count);}
483 
488  void chop(const char *list);
489 
494  inline void chop(strsize_t count = 1)
495  {operator-=(count);}
496 
501  void strip(const char *list);
502 
508  bool unquote(const char *quote);
509 
515  void cut(strsize_t offset, strsize_t size = 0);
516 
523  void paste(strsize_t offset, const char *text, strsize_t size = 0);
524 
530  void clear(strsize_t offset, strsize_t size = 0);
531 
535  void clear(void);
536 
540  void upper(void);
541 
545  void lower(void);
546 
550  void erase(void);
551 
557  strsize_t ccount(const char *list) const;
558 
563  strsize_t count(void) const;
564 
569  strsize_t size(void) const;
570 
580  strsize_t offset(const char *pointer) const;
581 
587  char at(int position) const;
588 
593  const char *begin(void) const;
594 
599  const char *end(void) const;
600 
607  const char *skip(const char *list, strsize_t offset = 0) const;
608 
616  const char *rskip(const char *list, strsize_t offset = npos) const;
617 
623  const char *search(const char *string, unsigned instance = 0, unsigned flags = 0) const;
624 
625  const char *search(regex& expr, unsigned instance = 0, unsigned flags = 0) const;
626 
627  unsigned replace(const char *string, const char *text = NULL, unsigned flags = 0);
628 
629  unsigned replace(regex& expr, const char *text = NULL, unsigned flags = 0);
630 
637  const char *find(const char *list, strsize_t offset = 0) const;
638 
645  const char *rfind(const char *list, strsize_t offset = npos) const;
646 
652  void split(const char *pointer);
653 
659  void split(strsize_t offset);
660 
666  void rsplit(const char *pointer);
667 
673  void rsplit(strsize_t offset);
674 
680  const char *chr(char character) const;
681 
688  const char *rchr(char character) const;
689 
694  strsize_t len(void) const;
695 
700  char fill(void);
701 
706  inline operator const char *() const
707  {return c_str();}
708 
713  inline const char *operator*() const
714  {return c_str();}
715 
720  bool full(void) const;
721 
728  String operator()(int offset, strsize_t size) const;
729 
735  inline String left(strsize_t size) const
736  {return operator()(0, size);}
737 
743  inline String right(strsize_t offset) const
744  {return operator()(-((int)offset), 0);}
745 
752  inline String copy(strsize_t offset, strsize_t size) const
753  {return operator()((int)offset, size);}
754 
762  const char *operator()(int offset) const;
763 
769  const char operator[](int offset) const;
770 
775  bool operator!() const;
776 
781  operator bool() const;
782 
788  String& operator^=(const String& object);
789 
794  String& operator|=(const char *text);
795 
796  String& operator&=(const char *text);
797 
803  String& operator+=(const char *text);
804 
810  String& operator^=(const char *text);
811 
816  String operator+(const char *text);
817 
824  String& operator|(const char *text);
825 
832  String& operator&(const char *text);
833 
840  String& operator=(const String& object);
841 
842  bool operator*=(const char *substring);
843 
844  bool operator*=(regex& expr);
845 
850  String& operator=(const char *text);
851 
855  String& operator++(void);
856 
861  String& operator+=(strsize_t number);
862 
866  String& operator--(void);
867 
872  String& operator-=(strsize_t number);
873 
878  String& operator*=(strsize_t number);
879 
885  bool operator==(const char *text) const;
886 
892  bool operator!=(const char *text) const;
893 
899  bool operator<(const char *text) const;
900 
906  bool operator<=(const char *text) const;
907 
913  bool operator>(const char *text) const;
914 
920  bool operator>=(const char *text) const;
921 
922  inline String& operator<<(const char *text)
923  {add(text); return *this;}
924 
925  inline String& operator<<(char code)
926  {add(code); return *this;}
927 
933  String &operator%(short& value);
934 
940  String &operator%(unsigned short& value);
941 
947  String &operator%(long& value);
948 
954  String &operator%(unsigned long& value);
955 
961  String &operator%(double& value);
962 
968  String &operator%(const char *text);
969 
975  static void swap(String& object1, String& object2);
976 
981  static void fix(String& object);
982 
987  static void erase(char *text);
988 
993  static void lower(char *text);
994 
999  static void upper(char *text);
1000 
1014  static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
1015 
1022  static char *skip(char *text, const char *list);
1023 
1030  static char *rskip(char *text, const char *list);
1031 
1039  static char *unquote(char *text, const char *quote);
1040 
1048  static char *rset(char *buffer, size_t size, const char *text);
1049 
1058  static char *set(char *buffer, size_t size, const char *text);
1059 
1069  static char *set(char *buffer, size_t size, const char *text, size_t max);
1070 
1080  static char *add(char *buffer, size_t size, const char *text);
1081 
1092  static char *add(char *buffer, size_t size, const char *text, size_t max);
1093 
1101  static const char *ifind(const char *text, const char *key, const char *optional);
1102 
1110  static const char *find(const char *text, const char *key, const char *optional);
1111 
1117  static size_t count(const char *text);
1118 
1125  static int compare(const char *text1, const char *text2);
1126 
1127  static inline int collate(const char *text1, const char *text2)
1128  {return compare(text1, text2);}
1129 
1136  static bool equal(const char *text1, const char *text2);
1137 
1145  static int compare(const char *text1, const char *text2, size_t size);
1146 
1154  static bool equal(const char *text1, const char *text2, size_t size);
1155 
1162  static int case_compare(const char *text1, const char *text2);
1163 
1170  static bool eq_case(const char *text1, const char *text2);
1171 
1179  static int case_compare(const char *text1, const char *text2, size_t size);
1180 
1188  static bool eq_case(const char *text1, const char *text2, size_t size);
1189 
1197  static char *trim(char *text, const char *list);
1198 
1206  static char *chop(char *text, const char *list);
1207 
1215  static char *strip(char *text, const char *list);
1216 
1225  static char *fill(char *text, size_t size, char character);
1226 
1233  static unsigned ccount(const char *text, const char *list);
1234 
1241  static char *find(char *text, const char *list);
1242 
1249  static size_t seek(char *text, const char *list);
1250 
1257  static char *rfind(char *text, const char *list);
1258 
1264  static char *dup(const char *text);
1265 
1272  static char *left(const char *text, size_t size);
1273 
1280  static const char *pos(const char *text, ssize_t offset);
1281 
1282  inline static char *right(const char *text, size_t size)
1283  {return dup(pos(text, -(signed)size));}
1284 
1285  inline static char *copy(const char *text, size_t offset, size_t len)
1286  {return left(pos(text, offset), len);}
1287 
1288  static void cut(char *text, size_t offset, size_t len);
1289 
1290  static void paste(char *text, size_t max, size_t offset, const char *data, size_t len = 0);
1291 
1304  inline char *token(char **last, const char *list, const char *quote = NULL, const char *end = NULL)
1305  {return token(c_mem(), last, list, quote, end);}
1306 
1313  inline double tod(char **pointer = NULL)
1314  {return strtod(c_mem(), pointer);}
1315 
1322  inline long tol(char **pointer = NULL)
1323  {return strtol(c_mem(), pointer, 0);}
1324 
1331  inline static double tod(const char *text, char **pointer = NULL)
1332  {return strtod(text, pointer);}
1333 
1340  inline static long tol(const char *text, char **pointer = NULL)
1341  {return strtol(text, pointer, 0);}
1342 
1351  static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
1352 
1360  static size_t b64decode(uint8_t *binary, const char *string, size_t size);
1361 
1368  static uint32_t crc24(uint8_t *binary, size_t size);
1369 
1376  static uint16_t crc16(uint8_t *binary, size_t size);
1377 
1385  static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
1386 
1394  static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
1395 
1396  static unsigned hexsize(const char *format);
1397 };
1398 
1406 class __EXPORT memstring : public String
1407 {
1408 public:
1409 #if _MSC_VER > 1400 // windows broken dll linkage issue...
1410  const static size_t header = sizeof(String::cstring);
1411 #else
1412  static const size_t header;
1413 #endif
1414 
1415 private:
1416  bool resize(strsize_t size);
1417  void cow(strsize_t adj = 0);
1418  void release(void);
1419 
1420 protected:
1421  cstring *c_copy(void) const;
1422 
1423 public:
1428  inline void operator=(String& object)
1429  {set(object.c_str());}
1430 
1435  inline void operator=(const char *text)
1436  {set(text);}
1437 
1444  memstring(void *memory, strsize_t size, char fill = 0);
1445 
1449  ~memstring();
1450 
1456  static memstring *create(strsize_t size, char fill = 0);
1457 
1464  static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
1465 };
1466 
1474 template<size_t S>
1475 class charbuf
1476 {
1477 private:
1478  char buffer[S];
1479 
1480 public:
1484  inline charbuf()
1485  {buffer[0] = 0;}
1486 
1492  inline charbuf(const char *text)
1493  {String::set(buffer, S, text);}
1494 
1498  inline charbuf(const charbuf& copy)
1499  {String::set(buffer, S, copy.buffer);}
1500 
1505  inline void operator=(const char *text)
1506  {String::set(buffer, S, text);}
1507 
1513  inline void operator+=(const char *text)
1514  {String::add(buffer, S, text);}
1515 
1520  inline operator bool() const
1521  {return buffer[0];}
1522 
1527  inline bool operator!() const
1528  {return buffer[0] == 0;}
1529 
1534  inline operator char *()
1535  {return buffer;}
1536 
1541  inline char *operator*()
1542  {return buffer;}
1543 
1549  inline char& operator[](size_t offset) const
1550  {return buffer[offset];}
1551 
1557  inline char *operator()(size_t offset)
1558  {return buffer + offset;}
1559 
1564  inline size_t size(void) const
1565  {return S;}
1566 
1571  inline size_t len(void) const
1572  {return strlen(buffer);}
1573 };
1574 
1579 
1580 typedef String::regex stringex_t;
1581 
1592 template<strsize_t S>
1593 class stringbuf : public memstring
1594 {
1595 private:
1596  char buffer[sizeof(cstring) + S];
1597 
1598 public:
1602  inline stringbuf() : memstring(buffer, S) {}
1603 
1608  inline stringbuf(const char *text) : memstring(buffer, S) {set(text);}
1609 
1614  inline void operator=(const char *text)
1615  {set(text);}
1616 
1621  inline void operator=(String& object)
1622  {set(object.c_str());}
1623 };
1624 
1625 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
1626 
1627 #ifndef stricmp
1628 #define stricmp(x,y) String::case_compare(x,y)
1629 #endif
1630 
1631 #ifndef strnicmp
1632 #define strnicmp(x,y,z) String::case_compare(x,y,z)
1633 #endif
1634 
1635 #endif
1636 
1643 inline bool eq(char const *s1, char const *s2)
1644  {return String::equal(s1, s2);}
1645 
1646 inline bool ne(char const *s1, char const *s2)
1647  {return !String::equal(s1, s2);}
1648 
1656 inline bool eq(char const *s1, char const *s2, size_t size)
1657  {return String::equal(s1, s2, size);}
1658 
1659 inline bool ne(char const *s1, char const *s2, size_t size)
1660  {return !String::equal(s1, s2, size);}
1661 
1671 inline bool eq(String &s1, const char *s2)
1672  {return s1.compare(s2) == 0;}
1673 
1674 inline bool ne(String &s1, String &s2)
1675  {return s1.compare(s2) != 0;}
1676 
1677 inline bool lt(String &s1, const char *s2)
1678  {return s1.compare(s2) < 0;}
1679 
1680 inline bool gt(String &s1, const char *s2)
1681  {return s1.compare(s2) > 0;}
1682 
1683 inline bool le(String &s1, const char *s2)
1684  {return s1.compare(s2) <= 0;}
1685 
1686 inline bool ge(String &s1, const char *s2)
1687  {return s1.compare(s2) >= 0;}
1688 
1696 inline bool eq_case(char const *s1, char const *s2)
1697  {return String::eq_case(s1, s2);}
1698 
1699 inline bool ne_case(char const *s1, char const *s2)
1700  {return !String::eq_case(s1, s2);}
1701 
1710 inline bool eq_case(char const *s1, char const *s2, size_t size)
1711  {return String::eq_case(s1, s2, size);}
1712 
1713 inline String str(const char *string)
1714  {return (String)string;}
1715 
1716 inline String str(String& string)
1717  {return (String)string;}
1718 
1719 inline String str(short value)
1720  {String temp(16, "%hd", value); return temp;}
1721 
1722 inline String str(unsigned short value)
1723  {String temp(16, "%hu", value); return temp;}
1724 
1725 inline String str(long value)
1726  {String temp(32, "%ld", value); return temp;}
1727 
1728 inline String str(unsigned long value)
1729  {String temp(32, "%lu", value); return temp;}
1730 
1731 inline String str(double value)
1732  {String temp(40, "%f", value); return temp;}
1733 
1734 String str(CharacterProtocol& cp, strsize_t size);
1735 
1736 template<>
1737 inline void swap<string_t>(string_t& s1, string_t& s2)
1738  {String::swap(s1, s2);}
1739 
1740 class __EXPORT strdup_t
1741 {
1742 private:
1743  char *data;
1744 
1745 public:
1746  inline strdup_t()
1747  {data = NULL;}
1748 
1749  inline strdup_t(char *str)
1750  {data = str;}
1751 
1752  inline ~strdup_t()
1753  {if(data) ::free(data);}
1754 
1755  inline strdup_t& operator=(char *str)
1756  {if(data) ::free(data); data = str; return *this;}
1757 
1758  inline operator bool() const
1759  {return data != NULL;}
1760 
1761  inline bool operator!() const
1762  {return data == NULL;}
1763 
1764  inline operator char*() const
1765  {return data;}
1766 
1767  inline const char *c_str(void) const
1768  {return data;}
1769 
1770  inline const char *operator*() const
1771  {return data;}
1772 
1773  inline char& operator[](int size)
1774  {return data[size];}
1775 
1776  inline char *operator+(size_t size)
1777  {return data + size;}
1778 };
1779 
1780 } // namespace ucommon
1781 
1782 #endif
void operator=(String &object)
Assign a string buffer from another string object.
Definition: string.h:1621
A common base class for all managed objects.
Definition: protocols.h:544
A base class for reference counted objects.
Definition: object.h:55
String left(strsize_t size) const
Convenience method for left of string.
Definition: string.h:735
charbuf(const charbuf &copy)
Copy constructor.
Definition: string.h:1498
A common object base class with auto-pointer support.
void swap(T &o1, T &o2)
Convenience function to swap objects.
Definition: generics.h:530
void release(SharedAccess &object)
Convenience function to unlock shared object through it's protocol.
Definition: access.h:260
void operator+=(const char *text)
Concatenate text into the object.
Definition: string.h:1513
bool equal(const char *string) const
Test if two string values are equal.
virtual int compare(const char *string) const
Compare the values of two string.
A copy-on-write string class that operates by reference count.
Definition: string.h:82
Common namespace for all ucommon objects.
Definition: access.h:46
static bool eq_case(const char *text1, const char *text2)
Simple case insensitive equal test for strings.
String string_t
A convenience type for string.
Definition: string.h:1578
void retain(ObjectProtocol *object)
Convenience function to access object retention.
Definition: object.h:465
charbuf(const char *text)
Create a character buffer with assigned text.
Definition: string.h:1492
static void swap(String &object1, String &object2)
Swap the cstring references between two strings.
static long tol(const char *text, char **pointer=((void *) 0))
Convert text to a long value.
Definition: string.h:1340
stringbuf()
Create an empty instance of a string buffer.
Definition: string.h:1602
Generic smart pointer class.
Definition: generics.h:53
void operator=(String &object)
Assign the text of a string to our object.
Definition: string.h:1428
Mempager managed type factory for pager pool objects.
Definition: memory.h:1259
const char * c_str(void) const
Get character text buffer of string object.
char * operator*()
Get text by object pointer reference.
Definition: string.h:1541
Runtime functions.
void set(const char *text)
Set string object to text of a null terminated string.
size_t len(void) const
Get current length of string.
Definition: string.h:1571
void chop(strsize_t count=1)
Chop trailing characters from text.
Definition: string.h:494
A common string class and character string support functions.
String right(strsize_t offset) const
Convenience method for right of string.
Definition: string.h:743
size_t size(void) const
Get allocated size of the object.
Definition: string.h:1564
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:540
Abstract interfaces and support.
const char * operator*() const
Reference raw text buffer by pointer operator.
Definition: string.h:713
static const strsize_t npos
A constant for an invalid position value.
Definition: string.h:290
void operator=(const char *text)
Assign a string buffer from a null terminated string.
Definition: string.h:1614
A template to create a character array that can be manipulated as a string.
Definition: string.h:1475
A string class that uses a cstring buffer that is fixed in memory.
Definition: string.h:1406
void add(const char *text)
Append null terminated text to our string buffer.
static double tod(const char *text, char **pointer=((void *) 0))
Convert text to a double value.
Definition: string.h:1331
String copy(strsize_t offset, strsize_t size) const
Convenience method for substring extraction.
Definition: string.h:752
unsigned short strsize_t
A convenience class for size of strings.
Definition: string.h:70
ObjectProtocol * copy(ObjectProtocol *object)
Convenience function to access object copy.
Definition: object.h:479
charbuf()
Create a new character buffer with an empty string.
Definition: string.h:1484
char * operator()(size_t offset)
Get a pointer to an offset in the object by expression operator.
Definition: string.h:1557
bool operator!() const
Test if the object is empty.
Definition: string.h:1527
void operator=(const char *text)
Assign null terminated text to our object.
Definition: string.h:1435
bool eq(const struct sockaddr *s1, const struct sockaddr *s2)
Compare two socket addresses to see if equal.
Definition: socket.h:1998
double tod(char **pointer=((void *) 0))
Convert string to a double value.
Definition: string.h:1313
stringbuf(const char *text)
Create a string buffer from a null terminated string.
Definition: string.h:1608
cstring * str
cstring instance our object references.
Definition: string.h:224
Generic templates for C++.
long tol(char **pointer=((void *) 0))
Convert string to a long value.
Definition: string.h:1322
char * token(char **last, const char *list, const char *quote=((void *) 0), const char *end=((void *) 0))
A thread-safe token parsing routine for strings objects.
Definition: string.h:1304
T * dup(const T &object)
Convenience function to duplicate object pointer to heap.
Definition: generics.h:475
char & operator[](size_t offset) const
Array operator to get a character from the object.
Definition: string.h:1549
bool eq_case(char const *s1, char const *s2)
Compare two null terminated strings if equal ignoring case.
Definition: string.h:1696
void operator=(const char *text)
Assign null terminated text to the object.
Definition: string.h:1505
A string class that has a predefined string buffer.
Definition: string.h:1593