1 // SciTE - Scintilla based Text Editor
\r
3 ** A simple string class.
\r
5 // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
\r
6 // The License.txt file describes the conditions under which this software may be distributed.
\r
12 // These functions are implemented because each platform calls them something different.
\r
13 int CompareCaseInsensitive(const char *a, const char *b);
\r
14 int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
\r
15 bool EqualCaseInsensitive(const char *a, const char *b);
\r
17 #ifdef SCI_NAMESPACE
\r
18 namespace Scintilla {
\r
21 // Define another string class.
\r
22 // While it would be 'better' to use std::string, that doubles the executable size.
\r
23 // An SString may contain embedded nul characters.
\r
26 * Base class from which the two other classes (SBuffer & SString)
\r
31 /** Type of string lengths (sizes) and positions (indexes). */
\r
32 typedef size_t lenpos_t;
\r
33 /** Out of bounds value indicating that the string argument should be measured. */
\r
34 enum { measure_length=0xffffffffU};
\r
37 char *s; ///< The C string
\r
38 lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string
\r
40 SContainer() : s(0), sSize(0) {}
\r
42 delete []s; // Suppose it was allocated using StringAllocate
\r
46 /** Size of buffer. */
\r
47 lenpos_t size() const {
\r
56 * Allocate uninitialized memory big enough to fit a string of the given length.
\r
57 * @return the pointer to the new string
\r
59 static char *StringAllocate(lenpos_t len);
\r
61 * Duplicate a buffer/C string.
\r
62 * Allocate memory of the given size, or big enough to fit the string if length isn't given;
\r
63 * then copy the given string in the allocated memory.
\r
64 * @return the pointer to the new string
\r
66 static char *StringAllocate(
\r
67 const char *s, ///< The string to duplicate
\r
68 lenpos_t len=measure_length); ///< The length of memory to allocate. Optional.
\r
73 * @brief A string buffer class.
\r
75 * Main use is to ask an API the length of a string it can provide,
\r
76 * then to allocate a buffer of the given size, and to provide this buffer
\r
77 * to the API to put the string.
\r
78 * This class is intended to be shortlived, to be transformed as SString
\r
79 * as soon as it holds the string, so it has little members.
\r
80 * Note: we assume the buffer is filled by the API. If the length can be shorter,
\r
81 * we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment.
\r
83 class SBuffer : protected SContainer {
\r
85 SBuffer(lenpos_t len) {
\r
86 s = StringAllocate(len);
\r
95 /// Copy constructor
\r
96 // Here only to be on the safe size, user should avoid returning SBuffer values.
\r
97 SBuffer(const SBuffer &source) : SContainer() {
\r
98 s = StringAllocate(source.s, source.sSize);
\r
99 sSize = (s) ? source.sSize : 0;
\r
101 /// Default assignment operator
\r
102 // Same here, shouldn't be used
\r
103 SBuffer &operator=(const SBuffer &source) {
\r
104 if (this != &source) {
\r
106 s = StringAllocate(source.s, source.sSize);
\r
107 sSize = (s) ? source.sSize : 0;
\r
112 /** Provide direct read/write access to buffer. */
\r
116 /** Ownership of the buffer have been taken, so release it. */
\r
121 /** Size of buffer. */
\r
122 lenpos_t size() const {
\r
123 return SContainer::size();
\r
129 * @brief A simple string class.
\r
131 * Hold the length of the string for quick operations,
\r
132 * can have a buffer bigger than the string to avoid too many memory allocations and copies.
\r
133 * May have embedded zeroes as a result of @a substitute, but relies too heavily on C string
\r
134 * functions to allow reliable manipulations of these strings, other than simple appends, etc.
\r
136 class SString : protected SContainer {
\r
137 lenpos_t sLen; ///< The size of the string in s
\r
138 lenpos_t sizeGrowth; ///< Minimum growth size when appending strings
\r
139 enum { sizeGrowthDefault = 64 };
\r
141 bool grow(lenpos_t lenNew);
\r
142 SString &assign(const char *sOther, lenpos_t sSize_=measure_length);
\r
145 SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {}
\r
146 SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) {
\r
147 s = StringAllocate(source.s, source.sLen);
\r
148 sSize = sLen = (s) ? source.sLen : 0;
\r
150 SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
\r
151 s = StringAllocate(s_);
\r
152 sSize = sLen = (s) ? strlen(s) : 0;
\r
154 SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) {
\r
156 sSize = sLen = buf.size();
\r
157 // Consumes the given buffer!
\r
160 SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) {
\r
161 // note: expects the "last" argument to point one beyond the range end (a la STL iterators)
\r
162 s = StringAllocate(s_ + first, last - first);
\r
163 sSize = sLen = (s) ? last - first : 0;
\r
166 SString(double d, int precision);
\r
176 /** Size of buffer. */
\r
177 lenpos_t size() const {
\r
178 return SContainer::size();
\r
180 /** Size of string in buffer. */
\r
181 lenpos_t length() const {
\r
184 /** Read access to a character of the string. */
\r
185 char operator[](lenpos_t i) const {
\r
186 return (s && i < sSize) ? s[i] : '\0';
\r
188 SString &operator=(const char *source) {
\r
189 return assign(source);
\r
191 SString &operator=(const SString &source) {
\r
192 if (this != &source) {
\r
193 assign(source.s, source.sLen);
\r
197 bool operator==(const SString &sOther) const;
\r
198 bool operator!=(const SString &sOther) const {
\r
199 return !operator==(sOther);
\r
201 bool operator==(const char *sOther) const;
\r
202 bool operator!=(const char *sOther) const {
\r
203 return !operator==(sOther);
\r
205 bool contains(char ch) const {
\r
206 return (s && *s) ? strchr(s, ch) != 0 : false;
\r
208 void setsizegrowth(lenpos_t sizeGrowth_) {
\r
209 sizeGrowth = sizeGrowth_;
\r
211 const char *c_str() const {
\r
214 /** Give ownership of buffer to caller which must use delete[] to free buffer. */
\r
222 SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const;
\r
223 SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
\r
224 SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
\r
225 SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0');
\r
226 SString &operator+=(const char *sOther) {
\r
227 return append(sOther, static_cast<lenpos_t>(measure_length));
\r
229 SString &operator+=(const SString &sOther) {
\r
230 return append(sOther.s, sOther.sLen);
\r
232 SString &operator+=(char ch) {
\r
233 return append(&ch, 1);
\r
235 SString &appendwithseparator(const char *sOther, char sep) {
\r
236 return append(sOther, strlen(sOther), sep);
\r
238 SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length);
\r
241 * Remove @a len characters from the @a pos position, included.
\r
242 * Characters at pos + len and beyond replace characters at pos.
\r
243 * If @a len is 0, or greater than the length of the string
\r
244 * starting at @a pos, the string is just truncated at @a pos.
\r
246 void remove(lenpos_t pos, lenpos_t len);
\r
248 SString &change(lenpos_t pos, char ch) {
\r
249 if (pos < sLen) { // character changed must be in string bounds
\r
254 /** Read an integral numeric value from the string. */
\r
255 int value() const {
\r
256 return s ? atoi(s) : 0;
\r
258 bool startswith(const char *prefix);
\r
259 bool endswith(const char *suffix);
\r
260 int search(const char *sFind, lenpos_t start=0) const;
\r
261 bool contains(const char *sFind) const {
\r
262 return search(sFind) >= 0;
\r
264 int substitute(char chFind, char chReplace);
\r
265 int substitute(const char *sFind, const char *sReplace);
\r
266 int remove(const char *sFind) {
\r
267 return substitute(sFind, "");
\r
273 * Duplicate a C string.
\r
274 * Allocate memory of the given size, or big enough to fit the string if length isn't given;
\r
275 * then copy the given string in the allocated memory.
\r
276 * @return the pointer to the new string
\r
278 inline char *StringDup(
\r
279 const char *s, ///< The string to duplicate
\r
280 SContainer::lenpos_t len=SContainer::measure_length) ///< The length of memory to allocate. Optional.
\r
282 return SContainer::StringAllocate(s, len);
\r
285 #ifdef SCI_NAMESPACE
\r