jstring.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #ifndef __JSTRING__
  15. #define __JSTRING__
  16. #include "jexpdef.hpp"
  17. #include "jiface.hpp"
  18. #include "jio.hpp"
  19. #include "jstream.hpp"
  20. #include "jbuff.hpp"
  21. // A Java compatible String and StringBuffer class - useful for dynamic strings.
  22. class String;
  23. interface IAtom;
  24. interface IFile;
  25. class jlib_decl StringBuffer
  26. {
  27. public:
  28. StringBuffer();
  29. StringBuffer(String & value);
  30. StringBuffer(const char *value);
  31. StringBuffer(unsigned len, const char *value);
  32. StringBuffer(const StringBuffer & value);
  33. inline ~StringBuffer() { free(buffer); }
  34. inline size32_t length() const { return curLen; }
  35. inline void Release() const { delete this; } // for consistency even though not link counted
  36. void setLength(unsigned len);
  37. inline void ensureCapacity(unsigned max) { if (maxLen <= curLen + max) _realloc(curLen + max); }
  38. StringBuffer & append(char value);
  39. StringBuffer & append(unsigned char value);
  40. StringBuffer & append(const char * value);
  41. StringBuffer & append(const unsigned char * value);
  42. StringBuffer & append(const IAtom * value);
  43. StringBuffer & append(unsigned len, const char * value);
  44. StringBuffer & append(const char * value, int offset, int len);
  45. // StringBuffer & append(const unsigned char * value, int offset, int len);
  46. StringBuffer & append(double value);
  47. StringBuffer & append(float value);
  48. StringBuffer & append(int value);
  49. StringBuffer & append(unsigned value);
  50. StringBuffer & append(__int64 value);
  51. StringBuffer & append(unsigned __int64 value);
  52. StringBuffer & append(const String & value);
  53. StringBuffer & append(const IStringVal & value);
  54. StringBuffer & append(const IStringVal * value);
  55. StringBuffer & appendN(size32_t count, char fill);
  56. StringBuffer & appendf(const char *format, ...) __attribute__((format(printf, 2, 3)));
  57. StringBuffer & appendLower(unsigned len, const char * value);
  58. StringBuffer & setf(const char* format, ...) __attribute__((format(printf,2,3)));
  59. StringBuffer & limited_valist_appendf(unsigned szLimit, const char *format, va_list args);
  60. inline StringBuffer &valist_appendf(const char *format, va_list args) { return limited_valist_appendf(0, format, args); }
  61. StringBuffer & appendhex(unsigned char value, char lower);
  62. inline char charAt(size32_t pos) { return buffer[pos]; }
  63. inline StringBuffer & clear() { curLen = 0; return *this; }
  64. void kill();
  65. void getChars(int srcBegin, int srcEnd, char * target) const;
  66. StringBuffer & insert(int offset, char value);
  67. StringBuffer & insert(int offset, unsigned char value);
  68. StringBuffer & insert(int offset, const char * value);
  69. StringBuffer & insert(int offset, const unsigned char * value);
  70. StringBuffer & insert(int offset, double value);
  71. StringBuffer & insert(int offset, float value);
  72. StringBuffer & insert(int offset, int value);
  73. StringBuffer & insert(int offset, unsigned value);
  74. StringBuffer & insert(int offset, __int64 value);
  75. StringBuffer & insert(int offset, const String & value);
  76. StringBuffer & insert(int offset, const StringBuffer & value);
  77. StringBuffer & insert(int offset, const IStringVal & value);
  78. StringBuffer & insert(int offset, const IStringVal * value);
  79. StringBuffer & reverse();
  80. void setCharAt(unsigned offset, char value);
  81. //Non-standard functions:
  82. MemoryBuffer & deserialize(MemoryBuffer & in);
  83. MemoryBuffer & serialize(MemoryBuffer & out) const;
  84. StringBuffer & loadFile(const char *fname, bool binaryMode=false);
  85. StringBuffer & loadFile(IFile* f);
  86. StringBuffer & append(const StringBuffer & value);
  87. StringBuffer & newline();
  88. StringBuffer & pad(unsigned count);
  89. StringBuffer & padTo(unsigned count);
  90. inline const char * str() const { return toCharArray(); }
  91. char * detach();
  92. StringBuffer & clip();
  93. StringBuffer & trim();
  94. StringBuffer & trimLeft();
  95. inline StringBuffer & trimRight() { return clip(); }
  96. StringBuffer & remove(unsigned start, unsigned len);
  97. const char * toCharArray() const;
  98. StringBuffer & toLowerCase();
  99. StringBuffer & toUpperCase();
  100. StringBuffer & replace(char oldChar, char newChar);
  101. StringBuffer & replaceString(const char* oldStr, const char* newStr);
  102. char * reserve(size32_t size);
  103. char * reserveTruncate(size32_t size);
  104. void swapWith(StringBuffer &other);
  105. void setBuffer(size32_t buffLen, char * newBuff, size32_t strLen);
  106. inline StringBuffer& set(const char* value) { return clear().append(value); }
  107. inline operator const char* () const { return str(); }
  108. inline StringBuffer& operator=(const char* value)
  109. {
  110. return clear().append(value);
  111. }
  112. inline StringBuffer& operator=(const StringBuffer& value)
  113. {
  114. return clear().append(value.str());
  115. }
  116. StringBuffer & appendlong(long value);
  117. StringBuffer & appendulong(unsigned long value);
  118. private: // long depreciated
  119. StringBuffer & append(long value);
  120. StringBuffer & append(unsigned long value);
  121. StringBuffer & insert(int offset, long value);
  122. protected:
  123. void init()
  124. {
  125. buffer = NULL;
  126. curLen = 0;
  127. maxLen = 0;
  128. }
  129. void _insert(unsigned offset, size32_t insertLen);
  130. void _realloc(size32_t newLen);
  131. private:
  132. mutable char * buffer;
  133. size32_t curLen;
  134. size32_t maxLen;
  135. };
  136. // add a variable-parameter constructor to StringBuffer.
  137. class jlib_decl VStringBuffer : public StringBuffer
  138. {
  139. public:
  140. VStringBuffer(const char* format, ...) __attribute__((format(printf, 2, 3)));
  141. };
  142. class SCMStringBuffer : public CInterface, implements IStringVal
  143. {
  144. public:
  145. IMPLEMENT_IINTERFACE;
  146. StringBuffer s;
  147. virtual const char * str() const { return s.str(); };
  148. virtual void set(const char *val) { s.clear().append(val); };
  149. virtual void clear() { s.clear(); };
  150. virtual void setLen(const char *val, unsigned length) { s.clear().append(length, val); };
  151. virtual unsigned length() const { return s.length(); };
  152. };
  153. class jlib_decl String : public CInterface, implements IInterface
  154. {
  155. public:
  156. IMPLEMENT_IINTERFACE;
  157. String();
  158. // String(byte[]);
  159. // String(byte[], int);
  160. // String(byte[], int, int);
  161. // String(byte[], int, int, int);
  162. // String(byte[], int, int, String);
  163. // String(byte[], String);
  164. String(const char * value);
  165. String(const char * value, int offset, int count);
  166. String(String & value);
  167. String(StringBuffer & value);
  168. ~String();
  169. char charAt(size32_t index) const;
  170. int compareTo(const String & value) const;
  171. int compareTo(const char* value) const;
  172. String * concat(const String & value) const;
  173. bool endsWith(const String & value) const;
  174. bool endsWith(const char* value) const;
  175. bool equals(String & value) const;
  176. bool equalsIgnoreCase(const String & value) const;
  177. void getBytes(int srcBegin, int srcEnd, void * dest, int dstBegin) const;
  178. void getChars(int srcBegin, int srcEnd, void * dest, int dstBegin) const;
  179. int hashCode() const;
  180. int indexOf(int ch) const;
  181. int indexOf(int ch, int from) const;
  182. int indexOf(const String & search) const;
  183. int indexOf(const String & search, int from) const;
  184. int lastIndexOf(int ch) const;
  185. int lastIndexOf(int ch, int from) const;
  186. int lastIndexOf(const String & search) const;
  187. int lastIndexOf(const String & serach, int from) const;
  188. size32_t length() const;
  189. bool startsWith(String & value) const;
  190. bool startsWith(String & value, int offset) const;
  191. bool startsWith(const char* value) const;
  192. String * substring(int beginIndex) const;
  193. String * substring(int beginIndex, int endIndex) const;
  194. const char *toCharArray() const;
  195. String * toLowerCase() const;
  196. String * toString(); // Links this
  197. String * toUpperCase() const;
  198. String * trim() const;
  199. protected:
  200. char * text;
  201. };
  202. //This simple class is useful for storing string member variables
  203. class jlib_decl StringAttr
  204. {
  205. public:
  206. inline StringAttr(void) { text = NULL; }
  207. StringAttr(const char * _text, unsigned _len);
  208. StringAttr(const char * _text);
  209. StringAttr(const StringAttr & src);
  210. inline ~StringAttr(void) { free(text); }
  211. inline operator const char * () const { return text; }
  212. inline void clear() { setown(NULL); }
  213. inline char * detach() { char * ret = text; text = NULL; return ret; }
  214. inline const char * get(void) const { return text; }
  215. inline size32_t length() const { return text ? (size32_t)strlen(text) : 0; }
  216. inline bool isEmpty() { return !text||!*text; } // faster than (length==0)
  217. inline const char * sget(void) const { return text ? text : ""; } // safe form of get (doesn't return NULL)
  218. void set(const char * _text);
  219. void setown(const char * _text);
  220. void set(const char * _text, unsigned _len);
  221. void toUpperCase();
  222. private:
  223. char * text;
  224. private:
  225. StringAttr &operator = (const StringAttr & from);
  226. };
  227. class jlib_decl StringAttrAdaptor : public CInterface, implements IStringVal
  228. {
  229. public:
  230. StringAttrAdaptor(StringAttr & _attr) : attr(_attr) {}
  231. IMPLEMENT_IINTERFACE;
  232. virtual const char * str() const { return attr.get(); };
  233. virtual void set(const char *val) { attr.set(val); };
  234. virtual void clear() { attr.clear(); };
  235. virtual void setLen(const char *val, unsigned length) { attr.set(val, length); };
  236. virtual unsigned length() const { return attr.length(); };
  237. private:
  238. StringAttr & attr;
  239. };
  240. class jlib_decl StringBufferAdaptor : public CInterface, implements IStringVal
  241. {
  242. public:
  243. StringBufferAdaptor(StringBuffer & _buffer) : buffer(_buffer) { initsize=buffer.length(); }
  244. IMPLEMENT_IINTERFACE;
  245. virtual const char * str() const { return buffer.str(); };
  246. virtual void set(const char *val) { clear(); buffer.append(val); };
  247. virtual void clear() { buffer.setLength(initsize); }
  248. virtual void setLen(const char *val, unsigned length) { clear(); buffer.append(length, val); };
  249. virtual unsigned length() const { return buffer.length(); };
  250. private:
  251. size32_t initsize;
  252. StringBuffer & buffer;
  253. };
  254. #ifdef __GNUC__
  255. class jlib_decl GccStringAttrAdaptor
  256. {
  257. public:
  258. GccStringAttrAdaptor(StringAttr & _attr) : adaptor(_attr) {}
  259. inline operator IStringVal & () { return adaptor; }
  260. private:
  261. StringAttrAdaptor adaptor;
  262. };
  263. class jlib_decl GccStringBufferAdaptor
  264. {
  265. public:
  266. GccStringBufferAdaptor(StringBuffer & _buffer) : adaptor(_buffer) {}
  267. inline operator IStringVal & () { return adaptor; }
  268. private:
  269. StringBufferAdaptor adaptor;
  270. };
  271. #define StringAttrAdaptor GccStringAttrAdaptor
  272. #define StringBufferAdaptor GccStringBufferAdaptor
  273. #endif
  274. class jlib_decl StringAttrItem : public CInterface
  275. {
  276. public:
  277. StringAttrItem(void) {}
  278. StringAttrItem(const char * _text) : text(_text) {}
  279. StringAttrItem(const char * _text, unsigned _len);
  280. public:
  281. StringAttr text;
  282. };
  283. // --$appendURL-----------------------------------------------------------------
  284. // appends the URL encoded version of src to dest
  285. // if len is unspecified, then src is assumed to be an NTS
  286. // if lower is TRUE a-f is used for hex numbers, otherwise A-F is used
  287. // -----------------------------------------------------------------------------
  288. #define ENCODE_SPACES 1
  289. #define ENCODE_NEWLINES 2
  290. #define ENCODE_WHITESPACE 3
  291. interface IEntityHelper
  292. {
  293. virtual bool find(const char *entity, StringBuffer &value) = 0;
  294. };
  295. void jlib_decl appendURL(StringBuffer *dest, const char *src, size32_t len = -1, char lower=FALSE);
  296. extern jlib_decl StringBuffer & appendStringAsCPP(StringBuffer &out, unsigned len, const char * src, bool addBreak);
  297. extern jlib_decl StringBuffer & appendStringAsQuotedCPP(StringBuffer &out, unsigned len, const char * src, bool addBreak);
  298. extern jlib_decl StringBuffer & appendDataAsHex(StringBuffer &out, unsigned len, const void * data);
  299. extern jlib_decl StringBuffer & appendStringAsSQL(StringBuffer & out, unsigned len, const char * src);
  300. extern jlib_decl StringBuffer & appendStringAsECL(StringBuffer & out, unsigned len, const char * src);
  301. extern jlib_decl StringBuffer & appendStringAsQuotedECL(StringBuffer &out, unsigned len, const char * src);
  302. extern jlib_decl void extractItem(StringBuffer & res, const char * src, const char * sep, int whichItem, bool caps);
  303. extern jlib_decl const char *encodeXML(const char *x, StringBuffer &ret, unsigned flags=0, unsigned len=(unsigned)-1, bool utf8=false);
  304. extern jlib_decl const char *decodeXML(const char *x, StringBuffer &ret, unsigned len=(unsigned)-1, const char **errMark=NULL, IEntityHelper *entityHelper=NULL);
  305. extern jlib_decl const char *encodeXML(const char *x, IIOStream &out, unsigned flags=0, unsigned len=(unsigned)-1, bool utf8=false);
  306. extern jlib_decl void decodeXML(ISimpleReadStream &in, StringBuffer &out, unsigned len=(unsigned)-1);
  307. inline const char *encodeUtf8XML(const char *x, StringBuffer &ret, unsigned flags=false, unsigned len=(unsigned)-1)
  308. {
  309. return encodeXML(x, ret, flags, len, true);
  310. }
  311. extern jlib_decl void decodeCppEscapeSequence(StringBuffer & out, const char * in, bool errorIfInvalid);
  312. extern jlib_decl bool strToBool(const char * text);
  313. extern jlib_decl bool strToBool(size_t len, const char * text);
  314. extern jlib_decl bool clipStrToBool(size_t len, const char * text);
  315. extern jlib_decl bool clipStrToBool(const char * text);
  316. extern jlib_decl StringBuffer & ncnameEscape(char const * in, StringBuffer & out);
  317. extern jlib_decl StringBuffer & ncnameUnescape(char const * in, StringBuffer & out);
  318. extern jlib_decl bool startsWith(const char* src, const char* dst);
  319. extern jlib_decl bool endsWith(const char* src, const char* dst);
  320. extern jlib_decl bool startsWithIgnoreCase(const char* src, const char* dst);
  321. extern jlib_decl bool endsWithIgnoreCase(const char* src, const char* dst);
  322. inline bool strieq(const char* s, const char* t) { return stricmp(s,t)==0; }
  323. inline bool streq(const char* s, const char* t) { return strcmp(s,t)==0; }
  324. extern jlib_decl char *j_strtok_r(char *str, const char *delim, char **saveptr);
  325. extern jlib_decl int j_memicmp (const void *s1, const void *s2, size32_t len);
  326. extern jlib_decl size32_t memcount(size32_t len, const char * str, char search);
  327. #endif