]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/include/SString.h
Various fixes for Textctrl and Popup Menus.
[wxWidgets.git] / src / stc / scintilla / include / SString.h
1 // SciTE - Scintilla based Text Editor
2 /** @file SString.h
3 ** A simple string class.
4 **/
5 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
7
8 #ifndef SSTRING_H
9 #define SSTRING_H
10
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, int len);
14 bool EqualCaseInsensitive(const char *a, const char *b);
15
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.
19
20 /**
21 * Duplicate a C string.
22 * Allocate memory of the given size, or big enough to fit the string if length isn't given;
23 * then copy the given string in the allocated memory.
24 * @return the pointer to the new string
25 */
26 inline char *StringDup(
27 const char *s, ///< The string to duplicate
28 int len=-1) ///< The length of memory to allocate. Optional.
29 {
30 if (!s)
31 return 0;
32 if (len == -1)
33 len = strlen(s);
34 char *sNew = new char[len + 1];
35 if (sNew) {
36 strncpy(sNew, s, len);
37 sNew[len] = '\0';
38 }
39 return sNew;
40 }
41
42 /**
43 * @brief A simple string class.
44 * Hold the length of the string for quick operations,
45 * can have a buffer bigger than the string to avoid too many memory allocations and copies.
46 * May have embedded zeroes as a result of @a substitute, but rely too heavily on C string
47 * functions to allow reliable manipulations of these strings.
48 **/
49 class SString {
50 char *s; ///< The C string
51 int sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string
52 int sLen; ///< The size of the string in s
53 int sizeGrowth; ///< Minimum growth size when appending strings
54 enum { sizeGrowthDefault = 64 };
55
56 public:
57 typedef int size_type;
58
59 SString() : s(0), sSize(0), sLen(0), sizeGrowth(sizeGrowthDefault) {
60 }
61 SString(const SString &source) : sizeGrowth(sizeGrowthDefault) {
62 s = StringDup(source.s);
63 sSize = sLen = (s) ? strlen(s) : 0;
64 }
65 SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
66 s = StringDup(s_);
67 sSize = sLen = (s) ? strlen(s) : 0;
68 }
69 SString(const char *s_, int first, int last) : sizeGrowth(sizeGrowthDefault) {
70 s = StringDup(s_ + first, last - first);
71 sSize = sLen = (s) ? strlen(s) : 0;
72 }
73 SString(int i) : sizeGrowth(sizeGrowthDefault) {
74 char number[32];
75 sprintf(number, "%0d", i);
76 s = StringDup(number);
77 sSize = sLen = (s) ? strlen(s) : 0;
78 }
79 ~SString() {
80 delete []s;
81 s = 0;
82 sSize = 0;
83 sLen = 0;
84 }
85 void clear(void) {
86 if (s) {
87 *s = '\0';
88 }
89 sLen = 0;
90 }
91 /** Size of buffer. */
92 size_type size(void) const { ///<
93 if (s)
94 return sSize;
95 else
96 return 0;
97 }
98 /** Size of string in buffer. */
99 int length() const {
100 return sLen;
101 }
102 SString &assign(const char* sOther, int sSize_ = -1) {
103 if (!sOther) {
104 sSize_ = 0;
105 }
106 if (sSize_ < 0) {
107 sSize_ = strlen(sOther);
108 }
109 if (sSize > 0 && sSize_ <= sSize) { // Does not allocate new buffer if the current is big enough
110 if (s && sSize_) {
111 strncpy(s, sOther, sSize_);
112 }
113 s[sSize_] = '\0';
114 sLen = sSize_;
115 } else {
116 delete []s;
117 s = StringDup(sOther, sSize_);
118 if (s) {
119 sSize = sSize_; // Allow buffer bigger than real string, thus providing space to grow
120 sLen = strlen(s);
121 } else {
122 sSize = sLen = 0;
123 }
124 }
125 return *this;
126 }
127 SString &assign(const SString& sOther, int sSize_ = -1) {
128 return assign(sOther.s, sSize_);
129 }
130 SString &operator=(const char *source) {
131 return assign(source);
132 }
133 SString &operator=(const SString &source) {
134 if (this != &source) {
135 assign(source.c_str());
136 }
137 return *this;
138 }
139 bool operator==(const SString &sOther) const {
140 if ((s == 0) && (sOther.s == 0))
141 return true;
142 if ((s == 0) || (sOther.s == 0))
143 return false;
144 return strcmp(s, sOther.s) == 0;
145 }
146 bool operator!=(const SString &sOther) const {
147 return !operator==(sOther);
148 }
149 bool operator==(const char *sOther) const {
150 if ((s == 0) && (sOther == 0))
151 return true;
152 if ((s == 0) || (sOther == 0))
153 return false;
154 return strcmp(s, sOther) == 0;
155 }
156 bool operator!=(const char *sOther) const {
157 return !operator==(sOther);
158 }
159 bool contains(char ch) {
160 if (s && *s)
161 return strchr(s, ch) != 0;
162 else
163 return false;
164 }
165 void setsizegrowth(int sizeGrowth_) {
166 sizeGrowth = sizeGrowth_;
167 }
168 const char *c_str() const {
169 if (s)
170 return s;
171 else
172 return "";
173 }
174 /** Give ownership of buffer to caller which must use delete[] to free buffer. */
175 char *detach() {
176 char *sRet = s;
177 s = 0;
178 sSize = 0;
179 sLen = 0;
180 return sRet;
181 }
182 char operator[](int i) const {
183 if (s && i < sSize) // Or < sLen? Depends on the use, both are OK
184 return s[i];
185 else
186 return '\0';
187 }
188 SString &append(const char* sOther, int sLenOther=-1, char sep=0) {
189 if (sLenOther < 0)
190 sLenOther = strlen(sOther);
191 int lenSep = 0;
192 if (sLen && sep) // Only add a separator if not empty
193 lenSep = 1;
194 int lenNew = sLen + sLenOther + lenSep;
195 if (lenNew + 1 < sSize) {
196 // Conservative about growing the buffer: don't do it, unless really needed
197 if (lenSep) {
198 s[sLen] = sep;
199 sLen++;
200 }
201 strncpy(&s[sLen], sOther, sLenOther);
202 s[sLen + sLenOther] = '\0';
203 sLen += sLenOther;
204 } else {
205 // Grow the buffer bigger than really needed, to have room for other appends
206 char *sNew = new char[lenNew + sizeGrowth + 1];
207 if (sNew) {
208 if (s) {
209 memcpy(sNew, s, sLen);
210 delete []s;
211 }
212 s = sNew;
213 sSize = lenNew + sizeGrowth;
214 if (lenSep) {
215 s[sLen] = sep;
216 sLen++;
217 }
218 strncpy(&s[sLen], sOther, sLenOther);
219 sNew[sLen + sLenOther] = '\0';
220 sLen += sLenOther;
221 }
222 }
223 return *this;
224 }
225 SString &operator +=(const char *sOther) {
226 return append(sOther, -1);
227 }
228 SString &operator +=(const SString &sOther) {
229 return append(sOther.s, sOther.sSize);
230 }
231 SString &operator +=(char ch) {
232 return append(&ch, 1);
233 }
234 SString &appendwithseparator(const char* sOther, char sep) {
235 return append(sOther, strlen(sOther), sep);
236 }
237 int value() const {
238 if (s)
239 return atoi(s);
240 else
241 return 0;
242 }
243 void substitute(char find, char replace) {
244 char *t = s;
245 while (t) {
246 t = strchr(t, find);
247 if (t) {
248 *t = replace;
249 t++;
250 }
251 }
252 }
253 };
254
255 #endif