TQt conversion of scintilla for Qt3
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SString.h 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // SciTE - Scintilla based Text Editor
  2. /** @file SString.h
  3. ** A simple string class.
  4. **/
  5. // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
  6. // The License.txt file describes the conditions under which this software may be distributed.
  7. #ifndef SSTRING_H
  8. #define SSTRING_H
  9. // These functions are implemented because each platform calls them something different.
  10. int CompareCaseInsensitive(const char *a, const char *b);
  11. int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
  12. bool EqualCaseInsensitive(const char *a, const char *b);
  13. // Define another string class.
  14. // While it would be 'better' to use std::string, that doubles the executable size.
  15. // An SString may contain embedded nul characters.
  16. /**
  17. * Base class from which the two other classes (SBuffer & SString)
  18. * are derived.
  19. */
  20. class SContainer {
  21. public:
  22. /** Type of string lengths (sizes) and positions (indexes). */
  23. typedef size_t lenpos_t;
  24. /** Out of bounds value indicating that the string argument should be measured. */
  25. enum { measure_length=0xffffffffU};
  26. protected:
  27. char *s; ///< The C string
  28. lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string
  29. SContainer() : s(0), sSize(0) {}
  30. ~SContainer() {
  31. delete []s; // Suppose it was allocated using StringAllocate
  32. s = 0;
  33. sSize = 0;
  34. }
  35. /** Size of buffer. */
  36. lenpos_t size() const {
  37. if (s) {
  38. return sSize;
  39. } else {
  40. return 0;
  41. }
  42. }
  43. public:
  44. /**
  45. * Allocate uninitialized memory big enough to fit a string of the given length.
  46. * @return the pointer to the new string
  47. */
  48. static char *StringAllocate(lenpos_t len);
  49. /**
  50. * Duplicate a buffer/C string.
  51. * Allocate memory of the given size, or big enough to fit the string if length isn't given;
  52. * then copy the given string in the allocated memory.
  53. * @return the pointer to the new string
  54. */
  55. static char *StringAllocate(
  56. const char *s, ///< The string to duplicate
  57. lenpos_t len=measure_length); ///< The length of memory to allocate. Optional.
  58. };
  59. /**
  60. * @brief A string buffer class.
  61. *
  62. * Main use is to ask an API the length of a string it can provide,
  63. * then to allocate a buffer of the given size, and to provide this buffer
  64. * to the API to put the string.
  65. * This class is intended to be shortlived, to be transformed as SString
  66. * as soon as it holds the string, so it has little members.
  67. * Note: we assume the buffer is filled by the API. If the length can be shorter,
  68. * we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment.
  69. */
  70. class SBuffer : protected SContainer {
  71. public:
  72. SBuffer(lenpos_t len) {
  73. s = StringAllocate(len);
  74. if (s) {
  75. *s = '\0';
  76. sSize = len;
  77. } else {
  78. sSize = 0;
  79. }
  80. }
  81. private:
  82. /// Copy constructor
  83. // Here only to be on the safe size, user should avoid returning SBuffer values.
  84. SBuffer(const SBuffer &source) : SContainer() {
  85. s = StringAllocate(source.s, source.sSize);
  86. sSize = (s) ? source.sSize : 0;
  87. }
  88. /// Default assignment operator
  89. // Same here, shouldn't be used
  90. SBuffer &operator=(const SBuffer &source) {
  91. if (this != &source) {
  92. delete []s;
  93. s = StringAllocate(source.s, source.sSize);
  94. sSize = (s) ? source.sSize : 0;
  95. }
  96. return *this;
  97. }
  98. public:
  99. /** Provide direct read/write access to buffer. */
  100. char *ptr() {
  101. return s;
  102. }
  103. /** Ownership of the buffer have been taken, so release it. */
  104. void reset() {
  105. s = 0;
  106. sSize = 0;
  107. }
  108. /** Size of buffer. */
  109. lenpos_t size() const {
  110. return SContainer::size();
  111. }
  112. };
  113. /**
  114. * @brief A simple string class.
  115. *
  116. * Hold the length of the string for quick operations,
  117. * can have a buffer bigger than the string to avoid too many memory allocations and copies.
  118. * May have embedded zeroes as a result of @a substitute, but relies too heavily on C string
  119. * functions to allow reliable manipulations of these strings, other than simple appends, etc.
  120. */
  121. class SString : protected SContainer {
  122. lenpos_t sLen; ///< The size of the string in s
  123. lenpos_t sizeGrowth; ///< Minimum growth size when appending strings
  124. enum { sizeGrowthDefault = 64 };
  125. bool grow(lenpos_t lenNew);
  126. SString &assign(const char *sOther, lenpos_t sSize_=measure_length);
  127. public:
  128. SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {}
  129. SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) {
  130. s = StringAllocate(source.s, source.sLen);
  131. sSize = sLen = (s) ? source.sLen : 0;
  132. }
  133. SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
  134. s = StringAllocate(s_);
  135. sSize = sLen = (s) ? strlen(s) : 0;
  136. }
  137. SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) {
  138. s = buf.ptr();
  139. sSize = sLen = buf.size();
  140. // Consumes the given buffer!
  141. buf.reset();
  142. }
  143. SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) {
  144. // note: expects the "last" argument to point one beyond the range end (a la STL iterators)
  145. s = StringAllocate(s_ + first, last - first);
  146. sSize = sLen = (s) ? last - first : 0;
  147. }
  148. SString(int i);
  149. SString(double d, int precision);
  150. ~SString() {
  151. sLen = 0;
  152. }
  153. void clear() {
  154. if (s) {
  155. *s = '\0';
  156. }
  157. sLen = 0;
  158. }
  159. /** Size of buffer. */
  160. lenpos_t size() const {
  161. return SContainer::size();
  162. }
  163. /** Size of string in buffer. */
  164. lenpos_t length() const {
  165. return sLen;
  166. }
  167. /** Read access to a character of the string. */
  168. char operator[](lenpos_t i) const {
  169. return (s && i < sSize) ? s[i] : '\0';
  170. }
  171. SString &operator=(const char *source) {
  172. return assign(source);
  173. }
  174. SString &operator=(const SString &source) {
  175. if (this != &source) {
  176. assign(source.s, source.sLen);
  177. }
  178. return *this;
  179. }
  180. bool operator==(const SString &sOther) const;
  181. bool operator!=(const SString &sOther) const {
  182. return !operator==(sOther);
  183. }
  184. bool operator==(const char *sOther) const;
  185. bool operator!=(const char *sOther) const {
  186. return !operator==(sOther);
  187. }
  188. bool contains(char ch) const {
  189. return (s && *s) ? strchr(s, ch) != 0 : false;
  190. }
  191. void setsizegrowth(lenpos_t sizeGrowth_) {
  192. sizeGrowth = sizeGrowth_;
  193. }
  194. const char *c_str() const {
  195. return s ? s : "";
  196. }
  197. /** Give ownership of buffer to caller which must use delete[] to free buffer. */
  198. char *detach() {
  199. char *sRet = s;
  200. s = 0;
  201. sSize = 0;
  202. sLen = 0;
  203. return sRet;
  204. }
  205. SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const;
  206. SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
  207. SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
  208. SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0');
  209. SString &operator+=(const char *sOther) {
  210. return append(sOther, static_cast<lenpos_t>(measure_length));
  211. }
  212. SString &operator+=(const SString &sOther) {
  213. return append(sOther.s, sOther.sLen);
  214. }
  215. SString &operator+=(char ch) {
  216. return append(&ch, 1);
  217. }
  218. SString &appendwithseparator(const char *sOther, char sep) {
  219. return append(sOther, strlen(sOther), sep);
  220. }
  221. SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length);
  222. /**
  223. * Remove @a len characters from the @a pos position, included.
  224. * Characters at pos + len and beyond replace characters at pos.
  225. * If @a len is 0, or greater than the length of the string
  226. * starting at @a pos, the string is just truncated at @a pos.
  227. */
  228. void remove(lenpos_t pos, lenpos_t len);
  229. SString &change(lenpos_t pos, char ch) {
  230. if (pos < sLen) { // character changed must be in string bounds
  231. *(s + pos) = ch;
  232. }
  233. return *this;
  234. }
  235. /** Read an integral numeric value from the string. */
  236. int value() const {
  237. return s ? atoi(s) : 0;
  238. }
  239. bool startswith(const char *prefix);
  240. bool endswith(const char *suffix);
  241. int search(const char *sFind, lenpos_t start=0) const;
  242. bool contains(const char *sFind) const {
  243. return search(sFind) >= 0;
  244. }
  245. int substitute(char chFind, char chReplace);
  246. int substitute(const char *sFind, const char *sReplace);
  247. int remove(const char *sFind) {
  248. return substitute(sFind, "");
  249. }
  250. };
  251. /**
  252. * Duplicate a C string.
  253. * Allocate memory of the given size, or big enough to fit the string if length isn't given;
  254. * then copy the given string in the allocated memory.
  255. * @return the pointer to the new string
  256. */
  257. inline char *StringDup(
  258. const char *s, ///< The string to duplicate
  259. SContainer::lenpos_t len=SContainer::measure_length) ///< The length of memory to allocate. Optional.
  260. {
  261. return SContainer::StringAllocate(s, len);
  262. }
  263. #endif