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 
547  void erase(void);
548 
554  strsize_t ccount(const char *list) const;
555 
560  strsize_t count(void) const;
561 
566  strsize_t size(void) const;
567 
577  strsize_t offset(const char *pointer) const;
578 
584  char at(int position) const;
585 
590  const char *begin(void) const;
591 
596  const char *end(void) const;
597 
604  const char *skip(const char *list, strsize_t offset = 0) const;
605 
613  const char *rskip(const char *list, strsize_t offset = npos) const;
614 
620  const char *search(const char *string, unsigned instance = 0, unsigned flags = 0) const;
621 
622  const char *search(regex& expr, unsigned instance = 0, unsigned flags = 0) const;
623 
624  unsigned replace(const char *string, const char *text = NULL, unsigned flags = 0);
625 
626  unsigned replace(regex& expr, const char *text = NULL, unsigned flags = 0);
627 
634  const char *find(const char *list, strsize_t offset = 0) const;
635 
642  const char *rfind(const char *list, strsize_t offset = npos) const;
643 
649  void split(const char *pointer);
650 
656  void split(strsize_t offset);
657 
663  void rsplit(const char *pointer);
664 
670  void rsplit(strsize_t offset);
671 
677  const char *chr(char character) const;
678 
685  const char *rchr(char character) const;
686 
691  strsize_t len(void) const;
692 
697  char fill(void);
698 
703  inline operator const char *() const
704  {return c_str();};
705 
710  inline const char *operator*() const
711  {return c_str();};
712 
717  bool full(void) const;
718 
725  String operator()(int offset, strsize_t size) const;
726 
732  inline String left(strsize_t size) const
733  {return operator()(0, size);}
734 
740  inline String right(strsize_t offset) const
741  {return operator()(-((int)offset), 0);}
742 
749  inline String copy(strsize_t offset, strsize_t size) const
750  {return operator()((int)offset, size);}
751 
759  const char *operator()(int offset) const;
760 
766  const char operator[](int offset) const;
767 
772  bool operator!() const;
773 
778  operator bool() const;
779 
785  String& operator^=(const String& object);
786 
791  String& operator|=(const char *text);
792 
793  String& operator&=(const char *text);
794 
800  String& operator+=(const char *text);
801 
807  String& operator^=(const char *text);
808 
813  String operator+(const char *text);
814 
821  String& operator|(const char *text);
822 
829  String& operator&(const char *text);
830 
837  String& operator=(const String& object);
838 
839  bool operator*=(const char *substring);
840 
841  bool operator*=(regex& expr);
842 
847  String& operator=(const char *text);
848 
852  String& operator++(void);
853 
858  String& operator+=(strsize_t number);
859 
863  String& operator--(void);
864 
869  String& operator-=(strsize_t number);
870 
875  String& operator*=(strsize_t number);
876 
882  bool operator==(const char *text) const;
883 
889  bool operator!=(const char *text) const;
890 
896  bool operator<(const char *text) const;
897 
903  bool operator<=(const char *text) const;
904 
910  bool operator>(const char *text) const;
911 
917  bool operator>=(const char *text) const;
918 
919  inline String& operator<<(const char *text)
920  {add(text); return *this;}
921 
922  inline String& operator<<(char code)
923  {add(code); return *this;}
924 
930  String &operator%(short& value);
931 
937  String &operator%(unsigned short& value);
938 
944  String &operator%(long& value);
945 
951  String &operator%(unsigned long& value);
952 
958  String &operator%(double& value);
959 
965  String &operator%(const char *text);
966 
972  static void swap(String& object1, String& object2);
973 
978  static void fix(String& object);
979 
984  static void erase(char *text);
985 
990  static void lower(char *text);
991 
996  static void upper(char *text);
997 
1011  static char *token(char *text, char **last, const char *list, const char *quote = NULL, const char *end = NULL);
1012 
1019  static char *skip(char *text, const char *list);
1020 
1027  static char *rskip(char *text, const char *list);
1028 
1036  static char *unquote(char *text, const char *quote);
1037 
1045  static char *rset(char *buffer, size_t size, const char *text);
1046 
1055  static char *set(char *buffer, size_t size, const char *text);
1056 
1066  static char *set(char *buffer, size_t size, const char *text, size_t max);
1067 
1077  static char *add(char *buffer, size_t size, const char *text);
1078 
1089  static char *add(char *buffer, size_t size, const char *text, size_t max);
1090 
1098  static const char *ifind(const char *text, const char *key, const char *optional);
1099 
1107  static const char *find(const char *text, const char *key, const char *optional);
1108 
1114  static size_t count(const char *text);
1115 
1122  static int compare(const char *text1, const char *text2);
1123 
1124  static inline int collate(const char *text1, const char *text2)
1125  {return compare(text1, text2);};
1126 
1133  static bool equal(const char *text1, const char *text2);
1134 
1142  static int compare(const char *text1, const char *text2, size_t size);
1143 
1151  static bool equal(const char *text1, const char *text2, size_t size);
1152 
1159  static int case_compare(const char *text1, const char *text2);
1160 
1167  static bool eq_case(const char *text1, const char *text2);
1168 
1176  static int case_compare(const char *text1, const char *text2, size_t size);
1177 
1185  static bool eq_case(const char *text1, const char *text2, size_t size);
1186 
1194  static char *trim(char *text, const char *list);
1195 
1203  static char *chop(char *text, const char *list);
1204 
1212  static char *strip(char *text, const char *list);
1213 
1222  static char *fill(char *text, size_t size, char character);
1223 
1230  static unsigned ccount(const char *text, const char *list);
1231 
1238  static char *find(char *text, const char *list);
1239 
1246  static size_t seek(char *text, const char *list);
1247 
1254  static char *rfind(char *text, const char *list);
1255 
1261  static char *dup(const char *text);
1262 
1269  static char *left(const char *text, size_t size);
1270 
1277  static const char *pos(const char *text, ssize_t offset);
1278 
1279  inline static char *right(const char *text, size_t size)
1280  {return dup(pos(text, -(signed)size));}
1281 
1282  inline static char *copy(const char *text, size_t offset, size_t len)
1283  {return left(pos(text, offset), len);}
1284 
1285  static void cut(char *text, size_t offset, size_t len);
1286 
1287  static void paste(char *text, size_t max, size_t offset, const char *data, size_t len = 0);
1288 
1301  inline char *token(char **last, const char *list, const char *quote = NULL, const char *end = NULL)
1302  {return token(c_mem(), last, list, quote, end);};
1303 
1310  inline double tod(char **pointer = NULL)
1311  {return strtod(c_mem(), pointer);}
1312 
1319  inline long tol(char **pointer = NULL)
1320  {return strtol(c_mem(), pointer, 0);}
1321 
1328  inline static double tod(const char *text, char **pointer = NULL)
1329  {return strtod(text, pointer);}
1330 
1337  inline static long tol(const char *text, char **pointer = NULL)
1338  {return strtol(text, pointer, 0);}
1339 
1348  static size_t b64encode(char *string, const uint8_t *binary, size_t size, size_t width = 0);
1349 
1357  static size_t b64decode(uint8_t *binary, const char *string, size_t size);
1358 
1365  static uint32_t crc24(uint8_t *binary, size_t size);
1366 
1373  static uint16_t crc16(uint8_t *binary, size_t size);
1374 
1382  static unsigned hexdump(const unsigned char *binary, char *string, const char *format);
1383 
1391  static unsigned hexpack(unsigned char *binary, const char *string, const char *format);
1392 
1393  static unsigned hexsize(const char *format);
1394 };
1395 
1403 class __EXPORT memstring : public String
1404 {
1405 public:
1406 #if _MSC_VER > 1400 // windows broken dll linkage issue...
1407  const static size_t header = sizeof(string::cstring);
1408 #else
1409  static const size_t header;
1410 #endif
1411 
1412 private:
1413  bool resize(strsize_t size);
1414  void cow(strsize_t adj = 0);
1415  void release(void);
1416 
1417 protected:
1418  cstring *c_copy(void) const;
1419 
1420 public:
1425  inline void operator=(String& object)
1426  {set(object.c_str());};
1427 
1432  inline void operator=(const char *text)
1433  {set(text);};
1434 
1441  memstring(void *memory, strsize_t size, char fill = 0);
1442 
1446  ~memstring();
1447 
1453  static memstring *create(strsize_t size, char fill = 0);
1454 
1461  static memstring *create(MemoryProtocol *pager, strsize_t size, char fill = 0);
1462 };
1463 
1471 template<size_t S>
1472 class charbuf
1473 {
1474 private:
1475  char buffer[S];
1476 
1477 public:
1481  inline charbuf()
1482  {buffer[0] = 0;}
1483 
1489  inline charbuf(const char *text)
1490  {String::set(buffer, S, text);}
1491 
1495  inline charbuf(const charbuf& copy)
1496  {String::set(buffer, S, copy.buffer);}
1497 
1502  inline void operator=(const char *text)
1503  {String::set(buffer, S, text);}
1504 
1510  inline void operator+=(const char *text)
1511  {String::add(buffer, S, text);}
1512 
1517  inline operator bool() const
1518  {return buffer[0];}
1519 
1524  inline bool operator!() const
1525  {return buffer[0] == 0;}
1526 
1531  inline operator char *()
1532  {return buffer;};
1533 
1538  inline char *operator*()
1539  {return buffer;};
1540 
1546  inline char& operator[](size_t offset) const
1547  {return buffer[offset];}
1548 
1554  inline char *operator()(size_t offset)
1555  {return buffer + offset;}
1556 
1561  inline size_t size(void) const
1562  {return S;}
1563 
1568  inline size_t len(void) const
1569  {return strlen(buffer);}
1570 };
1571 
1576 
1577 typedef String::regex stringex_t;
1578 
1589 template<strsize_t S>
1590 class stringbuf : public memstring
1591 {
1592 private:
1593  char buffer[sizeof(cstring) + S];
1594 
1595 public:
1599  inline stringbuf() : memstring(buffer, S) {};
1600 
1605  inline stringbuf(const char *text) : memstring(buffer, S) {set(text);};
1606 
1611  inline void operator=(const char *text)
1612  {set(text);};
1613 
1618  inline void operator=(String& object)
1619  {set(object.c_str());};
1620 };
1621 
1622 #if !defined(_MSWINDOWS_) && !defined(__QNX__)
1623 
1630 extern "C" inline int stricmp(const char *string1, const char *string2)
1631  {return String::case_compare(string1, string2);}
1632 
1640 extern "C" inline int strnicmp(const char *string1, const char *string2, size_t max)
1641  {return String::case_compare(string1, string2, max);}
1642 
1643 #endif
1644 
1651 inline bool eq(char const *s1, char const *s2)
1652  {return String::equal(s1, s2);}
1653 
1654 inline bool ne(char const *s1, char const *s2)
1655  {return !String::equal(s1, s2);}
1656 
1664 inline bool eq(char const *s1, char const *s2, size_t size)
1665  {return String::equal(s1, s2, size);}
1666 
1667 inline bool ne(char const *s1, char const *s2, size_t size)
1668  {return !String::equal(s1, s2, size);}
1669 
1679 inline bool eq(String &s1, const char *s2)
1680  {return s1.compare(s2) == 0;}
1681 
1682 inline bool ne(String &s1, String &s2)
1683  {return s1.compare(s2) != 0;}
1684 
1685 inline bool lt(String &s1, const char *s2)
1686  {return s1.compare(s2) < 0;}
1687 
1688 inline bool gt(String &s1, const char *s2)
1689  {return s1.compare(s2) > 0;}
1690 
1691 inline bool le(String &s1, const char *s2)
1692  {return s1.compare(s2) <= 0;}
1693 
1694 inline bool ge(String &s1, const char *s2)
1695  {return s1.compare(s2) >= 0;}
1696 
1704 inline bool eq_case(char const *s1, char const *s2)
1705  {return String::eq_case(s1, s2);}
1706 
1707 inline bool ne_case(char const *s1, char const *s2)
1708  {return !String::eq_case(s1, s2);}
1709 
1718 inline bool eq_case(char const *s1, char const *s2, size_t size)
1719  {return String::eq_case(s1, s2, size);}
1720 
1721 inline String str(const char *string)
1722  {return (String)string;}
1723 
1724 inline String str(String& string)
1725  {return (String)string;}
1726 
1727 inline String str(short value)
1728  {String temp(16, "%hd", value); return temp;}
1729 
1730 inline String str(unsigned short value)
1731  {String temp(16, "%hu", value); return temp;}
1732 
1733 inline String str(long value)
1734  {String temp(32, "%ld", value); return temp;}
1735 
1736 inline String str(unsigned long value)
1737  {String temp(32, "%lu", value); return temp;}
1738 
1739 inline String str(double value)
1740  {String temp(40, "%f", value); return temp;}
1741 
1742 String str(CharacterProtocol& cp, strsize_t size);
1743 
1744 template<>
1745 inline void swap<string_t>(string_t& s1, string_t& s2)
1746  {String::swap(s1, s2);}
1747 
1748 class __EXPORT strdup_t
1749 {
1750 private:
1751  char *data;
1752 
1753 public:
1754  inline strdup_t()
1755  {data = NULL;}
1756 
1757  inline strdup_t(char *str)
1758  {data = str;}
1759 
1760  inline ~strdup_t()
1761  {if(data) ::free(data);}
1762 
1763  inline strdup_t& operator=(char *str)
1764  {if(data) ::free(data); data = str; return *this;}
1765 
1766  inline operator bool() const
1767  {return data != NULL;}
1768 
1769  inline bool operator!() const
1770  {return data == NULL;}
1771 
1772  inline operator char*() const
1773  {return data;}
1774 
1775  inline const char *c_str(void) const
1776  {return data;};
1777 
1778  inline const char *operator*() const
1779  {return data;}
1780 
1781  inline char& operator[](int size)
1782  {return data[size];}
1783 
1784  inline char *operator+(size_t size)
1785  {return data + size;}
1786 };
1787 
1788 
1789 END_NAMESPACE
1790 
1791 #endif
Abstract interfaces and support.
String string_t
A convenience type for string.
Definition: string.h:1575
T * dup(const T &object)
Convenience function to duplicate object pointer to heap.
Definition: generics.h:478
A common base class for all managed objects.
Definition: protocols.h:544
int strnicmp(const char *string1, const char *string2, size_t max)
Convenience function for case insensitive null terminated string compare.
Definition: string.h:1640
void operator=(const char *text)
Assign null terminated text to our object.
Definition: string.h:1432
const char * c_str(void) const
Get character text buffer of string object.
static long tol(const char *text, char **pointer=((void *) 0))
Convert text to a long value.
Definition: string.h:1337
bool eq_case(char const *s1, char const *s2)
Compare two null terminated strings if equal ignoring case.
Definition: string.h:1704
virtual cstring * c_copy(void) const
Return cstring to use in copy constructors.
Generic smart pointer class.
Definition: generics.h:56
Generic templates for C++.
String copy(strsize_t offset, strsize_t size) const
Convenience method for substring extraction.
Definition: string.h:749
A copy-on-write string class that operates by reference count.
Definition: string.h:82
const char * operator*() const
Reference raw text buffer by pointer operator.
Definition: string.h:710
void operator--(void)
Decrease retention operator.
Definition: protocols.h:576
ObjectProtocol * copy(void)
Retain (increase retention of) object when copying.
String right(strsize_t offset) const
Convenience method for right of string.
Definition: string.h:740
void chop(strsize_t count=1)
Chop trailing characters from text.
Definition: string.h:491
Mempager managed type factory for pager pool objects.
Definition: memory.h:1259
charbuf()
Create a new character buffer with an empty string.
Definition: string.h:1481
char & operator[](size_t offset) const
Array operator to get a character from the object.
Definition: string.h:1546
size_t len(void) const
Get current length of string.
Definition: string.h:1568
Runtime functions.
void operator=(const char *text)
Assign null terminated text to the object.
Definition: string.h:1502
double tod(char **pointer=((void *) 0))
Convert string to a double value.
Definition: string.h:1310
void operator=(const char *text)
Assign a string buffer from a null terminated string.
Definition: string.h:1611
long tol(char **pointer=((void *) 0))
Convert string to a long value.
Definition: string.h:1319
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:1301
virtual bool resize(strsize_t size)
Resize and re-allocate string memory.
String left(strsize_t size) const
Convenience method for left of string.
Definition: string.h:732
cstring * create(strsize_t size, char fill=0) const
Factory create a cstring object of specified size.
charbuf(const charbuf &copy)
Copy constructor.
Definition: string.h:1495
void operator+=(const char *text)
Concatenate text into the object.
Definition: string.h:1510
unsigned short strsize_t
A convenience class for size of strings.
Definition: string.h:70
static const strsize_t npos
A constant for an invalid position value.
Definition: string.h:287
void set(const char *text)
Set string object to text of a null terminated string.
stringbuf()
Create an empty instance of a string buffer.
Definition: string.h:1599
void operator++(void)
Increase retention operator.
Definition: protocols.h:570
virtual void cow(strsize_t size=0)
Copy on write operation for cstring.
char * operator()(size_t offset)
Get a pointer to an offset in the object by expression operator.
Definition: string.h:1554
int stricmp(const char *string1, const char *string2)
Convenience function for case insensitive null terminated string compare.
Definition: string.h:1630
cstring * str
cstring instance our object references.
Definition: string.h:221
void operator=(String &object)
Assign the text of a string to our object.
Definition: string.h:1425
void release(void)
Decrease reference count when released.
A base class for reference counted objects.
Definition: object.h:55
size_t size(void) const
Get allocated size of the object.
Definition: string.h:1561
void retain(void)
Increase reference count when retained.
charbuf(const char *text)
Create a character buffer with assigned text.
Definition: string.h:1489
A template to create a character array that can be manipulated as a string.
Definition: string.h:1472
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:543
A string class that has a predefined string buffer.
Definition: string.h:1590
virtual int compare(const char *string) const
Compare the values of two string.
virtual void release(void)
Decrease retention of our reference counted cstring.
static double tod(const char *text, char **pointer=((void *) 0))
Convert text to a double value.
Definition: string.h:1328
char * operator*()
Get text by object pointer reference.
Definition: string.h:1538
void operator=(String &object)
Assign a string buffer from another string object.
Definition: string.h:1618
A common string class and character string support functions.
bool operator!() const
Test if the object is empty.
Definition: string.h:1524
stringbuf(const char *text)
Create a string buffer from a null terminated string.
Definition: string.h:1605
ObjectProtocol * copy(ObjectProtocol *object)
Convenience function to access object copy.
Definition: object.h:479
void swap(T &o1, T &o2)
Convenience function to swap objects.
Definition: generics.h:533
A string class that uses a cstring buffer that is fixed in memory.
Definition: string.h:1403
bool eq(const struct sockaddr *s1, const struct sockaddr *s2)
Compare two socket addresses to see if equal.
Definition: socket.h:1806
A common object base class with auto-pointer support.