1
// SciTE - Scintilla based Text Editor
3
** A simple string class.
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.
11
// These functions are implemented because each platform calls them something different.
12
int CompareCaseInsensitive(const char *a, const char *b);
13
int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
14
bool EqualCaseInsensitive(const char *a, const char *b);
16
// Define another string class.
17
// While it would be 'better' to use std::string, that doubles the executable size.
18
// An SString may contain embedded nul characters.
21
* Base class from which the two other classes (SBuffer & SString)
26
/** Type of string lengths (sizes) and positions (indexes). */
27
typedef size_t lenpos_t;
28
/** Out of bounds value indicating that the string argument should be measured. */
29
enum { measure_length=0xffffffffU};
32
char *s; ///< The C string
33
lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string
35
SContainer() : s(0), sSize(0) {}
37
delete []s; // Suppose it was allocated using StringAllocate
41
/** Size of buffer. */
42
lenpos_t size() const {
51
* Allocate uninitialized memory big enough to fit a string of the given length.
52
* @return the pointer to the new string
54
static char *StringAllocate(lenpos_t len);
56
* Duplicate a buffer/C string.
57
* Allocate memory of the given size, or big enough to fit the string if length isn't given;
58
* then copy the given string in the allocated memory.
59
* @return the pointer to the new string
61
static char *StringAllocate(
62
const char *s, ///< The string to duplicate
63
lenpos_t len=measure_length); ///< The length of memory to allocate. Optional.
68
* @brief A string buffer class.
70
* Main use is to ask an API the length of a string it can provide,
71
* then to allocate a buffer of the given size, and to provide this buffer
72
* to the API to put the string.
73
* This class is intended to be shortlived, to be transformed as SString
74
* as soon as it holds the string, so it has little members.
75
* Note: we assume the buffer is filled by the API. If the length can be shorter,
76
* we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment.
78
class SBuffer : protected SContainer {
80
SBuffer(lenpos_t len) {
81
s = StringAllocate(len);
91
// Here only to be on the safe size, user should avoid returning SBuffer values.
92
SBuffer(const SBuffer &source) : SContainer() {
93
s = StringAllocate(source.s, source.sSize);
94
sSize = (s) ? source.sSize : 0;
96
/// Default assignment operator
97
// Same here, shouldn't be used
98
SBuffer &operator=(const SBuffer &source) {
99
if (this != &source) {
101
s = StringAllocate(source.s, source.sSize);
102
sSize = (s) ? source.sSize : 0;
107
/** Provide direct read/write access to buffer. */
111
/** Ownership of the buffer have been taken, so release it. */
116
/** Size of buffer. */
117
lenpos_t size() const {
118
return SContainer::size();
124
* @brief A simple string class.
126
* Hold the length of the string for quick operations,
127
* can have a buffer bigger than the string to avoid too many memory allocations and copies.
128
* May have embedded zeroes as a result of @a substitute, but relies too heavily on C string
129
* functions to allow reliable manipulations of these strings, other than simple appends, etc.
131
class SString : protected SContainer {
132
lenpos_t sLen; ///< The size of the string in s
133
lenpos_t sizeGrowth; ///< Minimum growth size when appending strings
134
enum { sizeGrowthDefault = 64 };
136
bool grow(lenpos_t lenNew);
137
SString &assign(const char *sOther, lenpos_t sSize_=measure_length);
140
SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {}
141
SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) {
142
s = StringAllocate(source.s, source.sLen);
143
sSize = sLen = (s) ? source.sLen : 0;
145
SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
146
s = StringAllocate(s_);
147
sSize = sLen = (s) ? strlen(s) : 0;
149
SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) {
151
sSize = sLen = buf.size();
152
// Consumes the given buffer!
155
SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) {
156
// note: expects the "last" argument to point one beyond the range end (a la STL iterators)
157
s = StringAllocate(s_ + first, last - first);
158
sSize = sLen = (s) ? last - first : 0;
161
SString(double d, int precision);
171
/** Size of buffer. */
172
lenpos_t size() const {
173
return SContainer::size();
175
/** Size of string in buffer. */
176
lenpos_t length() const {
179
/** Read access to a character of the string. */
180
char operator[](lenpos_t i) const {
181
return (s && i < sSize) ? s[i] : '\0';
183
SString &operator=(const char *source) {
184
return assign(source);
186
SString &operator=(const SString &source) {
187
if (this != &source) {
188
assign(source.s, source.sLen);
192
bool operator==(const SString &sOther) const;
193
bool operator!=(const SString &sOther) const {
194
return !operator==(sOther);
196
bool operator==(const char *sOther) const;
197
bool operator!=(const char *sOther) const {
198
return !operator==(sOther);
200
bool contains(char ch) const {
201
return (s && *s) ? strchr(s, ch) != 0 : false;
203
void setsizegrowth(lenpos_t sizeGrowth_) {
204
sizeGrowth = sizeGrowth_;
206
const char *c_str() const {
209
/** Give ownership of buffer to caller which must use delete[] to free buffer. */
217
SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const;
218
SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
219
SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
220
SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0');
221
SString &operator+=(const char *sOther) {
222
return append(sOther, static_cast<lenpos_t>(measure_length));
224
SString &operator+=(const SString &sOther) {
225
return append(sOther.s, sOther.sLen);
227
SString &operator+=(char ch) {
228
return append(&ch, 1);
230
SString &appendwithseparator(const char *sOther, char sep) {
231
return append(sOther, strlen(sOther), sep);
233
SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length);
236
* Remove @a len characters from the @a pos position, included.
237
* Characters at pos + len and beyond replace characters at pos.
238
* If @a len is 0, or greater than the length of the string
239
* starting at @a pos, the string is just truncated at @a pos.
241
void remove(lenpos_t pos, lenpos_t len);
243
SString &change(lenpos_t pos, char ch) {
244
if (pos < sLen) { // character changed must be in string bounds
249
/** Read an integral numeric value from the string. */
251
return s ? atoi(s) : 0;
253
bool startswith(const char *prefix);
254
bool endswith(const char *suffix);
255
int search(const char *sFind, lenpos_t start=0) const;
256
bool contains(const char *sFind) const {
257
return search(sFind) >= 0;
259
int substitute(char chFind, char chReplace);
260
int substitute(const char *sFind, const char *sReplace);
261
int remove(const char *sFind) {
262
return substitute(sFind, "");
268
* Duplicate a C string.
269
* Allocate memory of the given size, or big enough to fit the string if length isn't given;
270
* then copy the given string in the allocated memory.
271
* @return the pointer to the new string
273
inline char *StringDup(
274
const char *s, ///< The string to duplicate
275
SContainer::lenpos_t len=SContainer::measure_length) ///< The length of memory to allocate. Optional.
277
return SContainer::StringAllocate(s, len);