jstring.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef __JSTRING__
  14. #define __JSTRING__
  15. #include "jiface.hpp"
  16. #include "jio.hpp"
  17. #include "jstream.hpp"
  18. #include "jbuff.hpp"
  19. // A Java compatible String and StringBuffer class - useful for dynamic strings.
  20. class String;
  21. interface IAtom;
  22. interface IFile;
  23. class jlib_decl StringBuffer
  24. {
  25. enum { InternalBufferSize = 16 };
  26. public:
  27. StringBuffer();
  28. StringBuffer(String & value);
  29. StringBuffer(const char *value);
  30. StringBuffer(StringBuffer && value);
  31. StringBuffer(size_t len, const char *value);
  32. StringBuffer(const StringBuffer & value);
  33. StringBuffer(bool useInternal);
  34. StringBuffer(char value);
  35. ~StringBuffer();
  36. inline size32_t length() const { return (size32_t)curLen; }
  37. inline bool isEmpty() const { return (curLen == 0); }
  38. void setLength(size_t len);
  39. inline void ensureCapacity(size_t max) { if (maxLen <= curLen + max) _realloc(curLen + max); }
  40. size32_t lengthUtf8() const;
  41. StringBuffer & append(char value);
  42. StringBuffer & append(unsigned char value);
  43. StringBuffer & append(const char * value);
  44. StringBuffer & append(const unsigned char * value);
  45. StringBuffer & append(const IAtom * value);
  46. StringBuffer & append(size_t len, const char * value);
  47. StringBuffer & append(const char * value, size_t offset, size_t len);
  48. StringBuffer & append(double value);
  49. StringBuffer & append(float value);
  50. StringBuffer & append(int value);
  51. StringBuffer & append(unsigned value);
  52. StringBuffer & append(__int64 value);
  53. StringBuffer & append(unsigned __int64 value);
  54. StringBuffer & append(const String & value);
  55. StringBuffer & append(const IStringVal & value);
  56. StringBuffer & append(const IStringVal * value);
  57. StringBuffer & appendN(size_t count, char fill);
  58. StringBuffer & appendf(const char *format, ...) __attribute__((format(printf, 2, 3)));
  59. StringBuffer & appendLower(size_t len, const char * value);
  60. StringBuffer & appendLower(const char * value) { return appendLower(strlen(value), value); }
  61. StringBuffer & setf(const char* format, ...) __attribute__((format(printf,2,3)));
  62. StringBuffer & limited_valist_appendf(size_t szLimit, const char *format, va_list args) __attribute__((format(printf,3,0)));
  63. inline StringBuffer &valist_appendf(const char *format, va_list args) __attribute__((format(printf,2,0))) { return limited_valist_appendf(0, format, args); }
  64. StringBuffer & appendhex(unsigned char value, char lower);
  65. inline char charAt(size_t pos) { return buffer[pos]; }
  66. inline StringBuffer & clear() { curLen = 0; return *this; }
  67. void kill();
  68. void getChars(size_t srcBegin, size_t srcEnd, char * target) const;
  69. StringBuffer & insert(size_t offset, char value);
  70. StringBuffer & insert(size_t offset, unsigned char value);
  71. StringBuffer & insert(size_t offset, const char * value);
  72. StringBuffer & insert(size_t offset, const unsigned char * value);
  73. StringBuffer & insert(size_t offset, double value);
  74. StringBuffer & insert(size_t offset, float value);
  75. StringBuffer & insert(size_t offset, int value);
  76. StringBuffer & insert(size_t offset, unsigned value);
  77. StringBuffer & insert(size_t offset, __int64 value);
  78. StringBuffer & insert(size_t offset, const String & value);
  79. StringBuffer & insert(size_t offset, const StringBuffer & value);
  80. StringBuffer & insert(size_t offset, const IStringVal & value);
  81. StringBuffer & insert(size_t offset, const IStringVal * value);
  82. StringBuffer & reverse();
  83. void setCharAt(size_t offset, char value);
  84. //Non-standard functions:
  85. MemoryBuffer & deserialize(MemoryBuffer & in);
  86. MemoryBuffer & serialize(MemoryBuffer & out) const;
  87. StringBuffer & loadFile(const char *fname, bool binaryMode=false);
  88. StringBuffer & loadFile(IFile* f);
  89. StringBuffer & append(const StringBuffer & value);
  90. StringBuffer & newline();
  91. StringBuffer & pad(size_t count);
  92. StringBuffer & padTo(size_t count);
  93. char * detach();
  94. StringBuffer & clip();
  95. StringBuffer & trim();
  96. StringBuffer & trimLeft();
  97. inline StringBuffer & trimRight() { return clip(); }
  98. StringBuffer & remove(size_t start, size_t len);
  99. const char * str() const;
  100. StringBuffer & toLowerCase();
  101. StringBuffer & toUpperCase();
  102. StringBuffer & replace(char oldChar, char newChar);
  103. StringBuffer & replaceString(const char* oldStr, const char* newStr);
  104. StringBuffer & replaceStringNoCase(const char* oldStr, const char* newStr);
  105. char * reserve(size_t size);
  106. char * reserveTruncate(size_t size);
  107. void setown(StringBuffer &other);
  108. StringBuffer & stripChar(char oldChar);
  109. void swapWith(StringBuffer &other);
  110. void setBuffer(size_t buffLen, char * newBuff, size_t strLen);
  111. inline StringBuffer& set(const char* value) { return clear().append(value); }
  112. inline operator const char* () const { return str(); }
  113. inline StringBuffer& operator=(const char* value)
  114. {
  115. return clear().append(value);
  116. }
  117. inline StringBuffer& operator=(const StringBuffer& value)
  118. {
  119. return clear().append(value.str());
  120. }
  121. StringBuffer& operator=(StringBuffer&& value);
  122. explicit operator bool() const { return (length() != 0); }
  123. StringBuffer & appendlong(long value);
  124. StringBuffer & appendulong(unsigned long value);
  125. private: // long depreciated
  126. StringBuffer & append(long value);
  127. StringBuffer & append(unsigned long value);
  128. StringBuffer & insert(size_t offset, long value);
  129. protected:
  130. inline bool useInternal() const { return buffer == internalBuffer; }
  131. void init()
  132. {
  133. buffer = internalBuffer;
  134. curLen = 0;
  135. maxLen = InternalBufferSize;
  136. }
  137. void initNoInternal()
  138. {
  139. buffer = NULL;
  140. curLen = 0;
  141. maxLen = 0;
  142. }
  143. void freeBuffer();
  144. void _insert(size_t offset, size_t insertLen);
  145. void _realloc(size_t newLen);
  146. private:
  147. char internalBuffer[InternalBufferSize];
  148. char * buffer;
  149. size_t curLen;
  150. size_t maxLen;
  151. };
  152. // add a variable-parameter constructor to StringBuffer.
  153. class jlib_decl VStringBuffer : public StringBuffer
  154. {
  155. public:
  156. VStringBuffer(const char* format, ...) __attribute__((format(printf, 2, 3)));
  157. };
  158. class SCMStringBuffer : public CInterface, implements IStringVal
  159. {
  160. public:
  161. IMPLEMENT_IINTERFACE;
  162. StringBuffer s;
  163. virtual const char * str() const { return s.str(); };
  164. virtual void set(const char *val) { s.clear().append(val); };
  165. virtual void set(StringBuffer &&str) { s.swapWith(str); }
  166. virtual void clear() { s.clear(); };
  167. virtual void setLen(const char *val, unsigned length) { s.clear().append(length, val); };
  168. virtual unsigned length() const { return s.length(); };
  169. };
  170. class jlib_decl String : public CInterface, implements IInterface
  171. {
  172. public:
  173. IMPLEMENT_IINTERFACE;
  174. String();
  175. // String(byte[]);
  176. // String(byte[], int);
  177. // String(byte[], int, int);
  178. // String(byte[], int, int, int);
  179. // String(byte[], int, int, String);
  180. // String(byte[], String);
  181. String(const char * value);
  182. String(const char * value, int offset, int count);
  183. String(String & value);
  184. String(StringBuffer & value);
  185. ~String();
  186. char charAt(size32_t index) const;
  187. int compareTo(const String & value) const;
  188. int compareTo(const char* value) const;
  189. String * concat(const String & value) const;
  190. bool endsWith(const String & value) const;
  191. bool endsWith(const char* value) const;
  192. bool equals(String & value) const;
  193. bool equalsIgnoreCase(const String & value) const;
  194. void getBytes(int srcBegin, int srcEnd, void * dest, int dstBegin) const;
  195. void getChars(int srcBegin, int srcEnd, void * dest, int dstBegin) const;
  196. int hashCode() const;
  197. int indexOf(int ch) const;
  198. int indexOf(int ch, int from) const;
  199. int indexOf(const String & search) const;
  200. int indexOf(const String & search, int from) const;
  201. int lastIndexOf(int ch) const;
  202. int lastIndexOf(int ch, int from) const;
  203. int lastIndexOf(const String & search) const;
  204. int lastIndexOf(const String & serach, int from) const;
  205. size32_t length() const;
  206. bool startsWith(String & value) const;
  207. bool startsWith(String & value, int offset) const;
  208. bool startsWith(const char* value) const;
  209. String * substring(int beginIndex) const;
  210. String * substring(int beginIndex, int endIndex) const;
  211. const char *str() const;
  212. String * toLowerCase() const;
  213. String * toString(); // Links this
  214. String * toUpperCase() const;
  215. String * trim() const;
  216. protected:
  217. char * text;
  218. };
  219. //This simple class is useful for storing string member variables
  220. class jlib_decl StringAttr
  221. {
  222. public:
  223. inline StringAttr(void) { text = NULL; }
  224. StringAttr(const char * _text, size_t _len);
  225. StringAttr(const char * _text);
  226. StringAttr(const StringAttr & src);
  227. StringAttr(StringAttr && src);
  228. StringAttr& operator = (StringAttr && from);
  229. StringAttr& operator = (const StringAttr & from);
  230. inline ~StringAttr(void) { free(text); }
  231. inline operator const char * () const { return text; }
  232. inline void clear() { setown(NULL); }
  233. inline char * detach() { char * ret = text; text = NULL; return ret; }
  234. inline const char * get() const { return text; }
  235. inline size_t length() const { return text ? strlen(text) : 0; }
  236. inline bool isEmpty() const { return !text||!*text; } // faster than (length==0)
  237. inline const char * str() const { return text ? text : ""; } // safe form (doesn't return NULL)
  238. void set(const char * _text);
  239. void setown(const char * _text);
  240. void set(const char * _text, size_t _len);
  241. void set(const StringBuffer & source);
  242. void setown(StringBuffer & source);
  243. void toLowerCase();
  244. void toUpperCase();
  245. private:
  246. char * text;
  247. };
  248. class jlib_decl StringAttrBuilder : public StringBuffer
  249. {
  250. public:
  251. StringAttrBuilder(StringAttr & _target);
  252. ~StringAttrBuilder();
  253. protected:
  254. StringAttr & target;
  255. };
  256. class jlib_decl StringAttrAdaptor : implements IStringVal
  257. {
  258. public:
  259. StringAttrAdaptor(StringAttr & _attr) : attr(_attr) {}
  260. virtual const char * str() const { return attr.get(); };
  261. virtual void set(const char *val) { attr.set(val); };
  262. virtual void clear() { attr.clear(); };
  263. virtual void setLen(const char *val, unsigned length) { attr.set(val, length); };
  264. virtual unsigned length() const { return (unsigned)attr.length(); };
  265. private:
  266. StringAttr & attr;
  267. };
  268. class jlib_decl StringBufferAdaptor : implements IStringVal
  269. {
  270. public:
  271. StringBufferAdaptor(StringBuffer & _buffer) : buffer(_buffer) { initsize=buffer.length(); }
  272. virtual const char * str() const { return buffer.str(); };
  273. virtual void set(const char *val) { clear(); buffer.append(val); };
  274. virtual void clear() { buffer.setLength(initsize); }
  275. virtual void setLen(const char *val, unsigned length) { clear(); buffer.append(length, val); };
  276. virtual unsigned length() const { return buffer.length(); };
  277. private:
  278. size_t initsize;
  279. StringBuffer & buffer;
  280. };
  281. #ifdef __GNUC__
  282. class jlib_decl GccStringAttrAdaptor
  283. {
  284. public:
  285. GccStringAttrAdaptor(StringAttr & _attr) : adaptor(_attr) {}
  286. inline operator IStringVal & () { return adaptor; }
  287. private:
  288. StringAttrAdaptor adaptor;
  289. };
  290. class jlib_decl GccStringBufferAdaptor
  291. {
  292. public:
  293. GccStringBufferAdaptor(StringBuffer & _buffer) : adaptor(_buffer) {}
  294. inline operator IStringVal & () { return adaptor; }
  295. private:
  296. StringBufferAdaptor adaptor;
  297. };
  298. #define StringAttrAdaptor GccStringAttrAdaptor
  299. #define StringBufferAdaptor GccStringBufferAdaptor
  300. #endif
  301. class jlib_decl StringBufferItem : public CInterface, public StringBuffer
  302. {
  303. public:
  304. StringBufferItem() : StringBuffer() {}
  305. StringBufferItem(const char *value) : StringBuffer(value) {}
  306. StringBufferItem(unsigned len, const char *value) : StringBuffer(len, value) {}
  307. StringBufferItem(const StringBuffer & value) : StringBuffer(value) {}
  308. };
  309. class jlib_decl StringAttrItem : public CInterface
  310. {
  311. public:
  312. StringAttrItem(void) {}
  313. StringAttrItem(const char * _text) : text(_text) {}
  314. StringAttrItem(const char * _text, unsigned _len);
  315. public:
  316. StringAttr text;
  317. };
  318. // --$appendURL-----------------------------------------------------------------
  319. // appends the URL encoded version of src to dest
  320. // if len is unspecified, then src is assumed to be an NTS
  321. // if lower is TRUE a-f is used for hex numbers, otherwise A-F is used
  322. // -----------------------------------------------------------------------------
  323. #define ENCODE_SPACES 1
  324. #define ENCODE_NEWLINES 2
  325. #define ENCODE_WHITESPACE 3
  326. #define ENCODE_NONE 4
  327. interface IEntityHelper
  328. {
  329. virtual bool find(const char *entity, StringBuffer &value) = 0;
  330. };
  331. void jlib_decl appendURL(StringBuffer *dest, const char *src, size32_t len = -1, char lower=FALSE);
  332. extern jlib_decl StringBuffer &appendDecodedURL(StringBuffer &out, const char *url);
  333. extern jlib_decl StringBuffer & appendStringAsCPP(StringBuffer &out, unsigned len, const char * src, bool addBreak);
  334. extern jlib_decl StringBuffer & appendStringAsQuotedCPP(StringBuffer &out, unsigned len, const char * src, bool addBreak);
  335. extern jlib_decl StringBuffer & appendDataAsHex(StringBuffer &out, unsigned len, const void * data);
  336. extern jlib_decl StringBuffer & appendStringAsSQL(StringBuffer & out, unsigned len, const char * src);
  337. extern jlib_decl StringBuffer & appendStringAsECL(StringBuffer & out, unsigned len, const char * src);
  338. extern jlib_decl StringBuffer & appendStringAsQuotedECL(StringBuffer &out, unsigned len, const char * src);
  339. extern jlib_decl StringBuffer & appendUtf8AsECL(StringBuffer &out, unsigned len, const char * src);
  340. extern jlib_decl const char *decodeJSON(const char *x, StringBuffer &ret, unsigned len=(unsigned)-1, const char **errMark=NULL);
  341. extern jlib_decl void extractItem(StringBuffer & res, const char * src, const char * sep, int whichItem, bool caps);
  342. extern jlib_decl const char *encodeXML(const char *x, StringBuffer &ret, unsigned flags=0, unsigned len=(unsigned)-1, bool utf8=false);
  343. extern jlib_decl const char *decodeXML(const char *x, StringBuffer &ret, const char **errMark=NULL, IEntityHelper *entityHelper=NULL, bool strict = true);
  344. extern jlib_decl const char *encodeXML(const char *x, IIOStream &out, unsigned flags=0, unsigned len=(unsigned)-1, bool utf8=false);
  345. extern jlib_decl void decodeXML(ISimpleReadStream &in, StringBuffer &out, unsigned len=(unsigned)-1);
  346. extern jlib_decl int utf8CharLen(unsigned char ch);
  347. extern jlib_decl int utf8CharLen(const unsigned char *ch, unsigned maxsize = (unsigned)-1);
  348. extern jlib_decl StringBuffer &replaceString(StringBuffer & result, size_t lenSource, const char *source, size_t lenOldStr, const char* oldStr, size_t lenNewStr, const char* newStr);
  349. inline const char *encodeUtf8XML(const char *x, StringBuffer &ret, unsigned flags=false, unsigned len=(unsigned)-1)
  350. {
  351. return encodeXML(x, ret, flags, len, true);
  352. }
  353. inline StringBuffer &appendXMLTagName(StringBuffer &xml, const char *tag, const char *prefix=NULL)
  354. {
  355. if (prefix && *prefix)
  356. xml.append(prefix).append(':');
  357. xml.append(tag);
  358. return xml;
  359. }
  360. extern jlib_decl StringBuffer & appendXMLOpenTag(StringBuffer &xml, const char *tag, const char *prefix=NULL, bool complete=true, bool close=false, const char *uri=NULL);
  361. inline StringBuffer &appendXMLAttr(StringBuffer &xml, const char *name, const char *value, const char *prefix=NULL, bool useDblQuote=false)
  362. {
  363. if (!name || !*name || !value)
  364. return xml;
  365. xml.append(' ');
  366. appendXMLTagName(xml, name, prefix);
  367. xml.append("=").append(useDblQuote ? '"' : '\'');
  368. encodeXML(value, xml);
  369. xml.append(useDblQuote ? '"' : '\'');
  370. return xml;
  371. }
  372. inline StringBuffer & appendXMLCloseTag(StringBuffer &xml, const char *tag, const char *prefix=NULL)
  373. {
  374. if (!tag || !*tag)
  375. return xml;
  376. xml.append("</");
  377. return appendXMLTagName(xml, tag, prefix).append('>');
  378. }
  379. inline StringBuffer &appendXMLTag(StringBuffer &xml, const char *tag, const char *value, const char *prefix=NULL, unsigned flags=0, unsigned len=(unsigned)-1, bool utf8=true)
  380. {
  381. appendXMLOpenTag(xml, tag, prefix);
  382. if (value && *value)
  383. {
  384. if (flags != ENCODE_NONE)
  385. encodeXML(value, xml, flags, len, utf8);
  386. else
  387. xml.append(value);
  388. }
  389. return appendXMLCloseTag(xml, tag, prefix);
  390. }
  391. inline StringBuffer &delimitJSON(StringBuffer &s, bool addNewline=false, bool escapeNewline=false)
  392. {
  393. if (s.length() && !strchr("{ [:,n\n", s.charAt(s.length()-1))) //'n' or '\n' indicates already formatted with optionally escaped newline
  394. {
  395. s.append(",");
  396. if (addNewline)
  397. s.append(escapeNewline ? "\\n" : "\n");
  398. else
  399. s.append(' ');
  400. }
  401. return s;
  402. }
  403. jlib_decl StringBuffer &encodeJSON(StringBuffer &s, const char *value);
  404. jlib_decl StringBuffer &encodeJSON(StringBuffer &s, unsigned len, const char *value);
  405. jlib_decl StringBuffer &appendJSONName(StringBuffer &s, const char *name);
  406. jlib_decl StringBuffer &appendfJSONName(StringBuffer &s, const char *format, ...) __attribute__((format(printf, 2, 3)));
  407. jlib_decl StringBuffer &appendJSONDataValue(StringBuffer& s, const char *name, unsigned len, const void *_value);
  408. jlib_decl StringBuffer &appendJSONRealValue(StringBuffer& s, const char *name, double value);
  409. inline StringBuffer &appendJSONNameOrDelimit(StringBuffer &s, const char *name)
  410. {
  411. if (name && *name)
  412. return appendJSONName(s, name);
  413. return delimitJSON(s);
  414. }
  415. inline StringBuffer &appendJSONStringValue(StringBuffer& s, const char *name, unsigned len, const char *value, bool encode, bool quoted=true)
  416. {
  417. appendJSONNameOrDelimit(s, name);
  418. if (!value)
  419. return s.append("null");
  420. if (quoted)
  421. s.append('"');
  422. if (encode)
  423. encodeJSON(s, len, value);
  424. else
  425. s.append(len, value);
  426. if (quoted)
  427. s.append('"');
  428. return s;
  429. }
  430. inline StringBuffer &appendJSONStringValue(StringBuffer& s, const char *name, const char *value, bool encode, bool quoted=true)
  431. {
  432. return appendJSONStringValue(s, name, (size32_t)(value ? strlen(value) : 0), value, encode, quoted);
  433. }
  434. template <typename type>
  435. inline StringBuffer &appendJSONValue(StringBuffer& s, const char *name, type value)
  436. {
  437. appendJSONNameOrDelimit(s, name);
  438. return s.append(value);
  439. }
  440. //specialization
  441. template <>
  442. inline StringBuffer &appendJSONValue(StringBuffer& s, const char *name, bool value)
  443. {
  444. appendJSONNameOrDelimit(s, name);
  445. return s.append((value) ? "true" : "false");
  446. }
  447. template <>
  448. inline StringBuffer &appendJSONValue(StringBuffer& s, const char *name, const char *value)
  449. {
  450. return appendJSONStringValue(s, name, value, true);
  451. }
  452. template <>
  453. inline StringBuffer &appendJSONValue(StringBuffer& s, const char *name, long value)
  454. {
  455. appendJSONNameOrDelimit(s, name);
  456. return s.appendlong(value);
  457. }
  458. template <>
  459. inline StringBuffer &appendJSONValue(StringBuffer& s, const char *name, double value)
  460. {
  461. return ::appendJSONRealValue(s, name, value);
  462. }
  463. template <>
  464. inline StringBuffer &appendJSONValue(StringBuffer& s, const char *name, float value)
  465. {
  466. return ::appendJSONRealValue(s, name, value);
  467. }
  468. template <>
  469. inline StringBuffer &appendJSONValue(StringBuffer& s, const char *name, unsigned long value)
  470. {
  471. appendJSONNameOrDelimit(s, name);
  472. return s.appendulong(value);
  473. }
  474. template <typename TValue>
  475. inline StringBuffer& operator << (StringBuffer& s, const TValue& value)
  476. {
  477. return s.append(value);
  478. }
  479. extern jlib_decl bool checkUnicodeLiteral(char const * str, unsigned length, unsigned & ep, StringBuffer & msg);
  480. extern jlib_decl void decodeCppEscapeSequence(StringBuffer & out, const char * in, bool errorIfInvalid);
  481. extern jlib_decl bool strToBool(const char * text);
  482. inline const char *boolToStr(bool b) { return b ? "true" : "false"; }
  483. extern jlib_decl bool strToBool(size_t len, const char * text);
  484. extern jlib_decl bool clipStrToBool(size_t len, const char * text);
  485. extern jlib_decl bool clipStrToBool(const char * text);
  486. extern jlib_decl StringBuffer & ncnameEscape(char const * in, StringBuffer & out);
  487. extern jlib_decl StringBuffer & ncnameUnescape(char const * in, StringBuffer & out);
  488. extern jlib_decl StringBuffer & elideString(StringBuffer & s, unsigned maxLength);
  489. extern jlib_decl bool startsWith(const char* src, const char* prefix);
  490. extern jlib_decl bool endsWith(const char* src, const char* dst);
  491. extern jlib_decl bool startsWithIgnoreCase(const char* src, const char* prefix);
  492. extern jlib_decl bool endsWithIgnoreCase(const char* src, const char* dst);
  493. inline bool strieq(const char* s, const char* t) { return stricmp(s,t)==0; }
  494. inline bool streq(const char* s, const char* t) { return strcmp(s,t)==0; }
  495. inline bool strsame(const char* s, const char* t) { return (s == t) || (s && t && strcmp(s,t)==0); } // also allow nulls
  496. inline bool isEmptyString(const char *text) { return !text||!*text; }
  497. inline bool hasPrefix(const char * text, const char * prefix, bool caseSensitive)
  498. {
  499. if (caseSensitive)
  500. return strncmp(text, prefix, strlen(prefix)) == 0;
  501. else
  502. return strnicmp(text, prefix, strlen(prefix)) == 0;
  503. }
  504. // Search for a string in a null terminated array of const char * strings
  505. extern jlib_decl unsigned matchString(const char * search, const char * const * strings);
  506. extern jlib_decl char *j_strtok_r(char *str, const char *delim, char **saveptr);
  507. extern jlib_decl int j_memicmp (const void *s1, const void *s2, size32_t len);
  508. extern jlib_decl size32_t memcount(size32_t len, const char * str, char search);
  509. extern jlib_decl const char * nullText(const char * text);
  510. #endif