xref: /haiku/headers/os/support/String.h (revision d7496886521c82fdc76cd4b6b80bab61ffa2471e)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		String.h
23 //	Author(s):		Stefano Ceccherini (burton666@libero.it)
24 //	Description:	String class supporting common string operations.
25 //------------------------------------------------------------------------------
26 
27 
28 
29 #ifndef __BSTRING__
30 #define __BSTRING__
31 
32 #include <BeBuild.h>
33 #include <SupportDefs.h>
34 #include <string.h>
35 
36 class BString {
37 public:
38 						BString();
39 						BString(const char *);
40 						BString(const BString &);
41 						BString(const char *, int32 maxLength);
42 
43 						~BString();
44 
45 /*---- Access --------------------------------------------------------------*/
46 	const char 			*String() const;
47 						/* returns null-terminated string */
48 
49 	int32 				Length() const;
50 						/* length of corresponding string */
51 
52 	int32				CountChars() const;
53 						/* returns number of UTF8 characters in string */
54 /*---- Assignment ----------------------------------------------------------*/
55 	BString 			&operator=(const BString &);
56 	BString 			&operator=(const char *);
57 	BString 			&operator=(char);
58 
59 	BString				&SetTo(const char *);
60 	BString 			&SetTo(const char *, int32 length);
61 
62 	BString				&SetTo(const BString &from);
63 	BString				&Adopt(BString &from);
64 						/* leaves <from> empty, avoiding a copy */
65 
66 	BString 			&SetTo(const BString &, int32 length);
67 	BString 			&Adopt(BString &from, int32 length);
68 						/* leaves <from> empty, avoiding a copy */
69 
70 	BString 			&SetTo(char, int32 count);
71 
72 /*---- Substring copying ---------------------------------------------------*/
73 	BString 			&CopyInto(BString &into, int32 fromOffset,
74 							int32 length) const;
75 						/* returns <into> ref as it's result; doesn't do
76 						 * anything if <into> is <this>
77 						 */
78 
79 	void				CopyInto(char *into, int32 fromOffset,
80 							int32 length) const;
81 						/* caller guarantees that <into> is large enough */
82 
83 /*---- Appending -----------------------------------------------------------*/
84 	BString 			&operator+=(const BString &);
85 	BString 			&operator+=(const char *);
86 	BString 			&operator+=(char);
87 
88 	BString 			&Append(const BString &);
89 	BString 			&Append(const char *);
90 
91 	BString 			&Append(const BString &, int32 length);
92 	BString 			&Append(const char *, int32 length);
93 	BString 			&Append(char, int32 count);
94 
95 /*---- Prepending ----------------------------------------------------------*/
96 	BString 			&Prepend(const char *);
97 	BString 			&Prepend(const BString &);
98 	BString 			&Prepend(const char *, int32);
99 	BString 			&Prepend(const BString &, int32);
100 	BString 			&Prepend(char, int32 count);
101 
102 /*---- Inserting ----------------------------------------------------------*/
103 	BString 			&Insert(const char *, int32 pos);
104 	BString 			&Insert(const char *, int32 length, int32 pos);
105 	BString 			&Insert(const char *, int32 fromOffset,
106 							int32 length, int32 pos);
107 
108 	BString 			&Insert(const BString &, int32 pos);
109 	BString 			&Insert(const BString &, int32 length, int32 pos);
110 	BString 			&Insert(const BString &, int32 fromOffset,
111 							int32 length, int32 pos);
112 	BString 			&Insert(char, int32 count, int32 pos);
113 
114 /*---- Removing -----------------------------------------------------------*/
115 	BString 			&Truncate(int32 newLength, bool lazy = true);
116 						/* pass false in <lazy> to ensure freeing up the
117 						 * truncated memory
118 						 */
119 
120 	BString 			&Remove(int32 from, int32 length);
121 
122 	BString 			&RemoveFirst(const BString &);
123 	BString 			&RemoveLast(const BString &);
124 	BString 			&RemoveAll(const BString &);
125 
126 	BString 			&RemoveFirst(const char *);
127 	BString 			&RemoveLast(const char *);
128 	BString 			&RemoveAll(const char *);
129 
130 	BString 			&RemoveSet(const char *setOfCharsToRemove);
131 
132 	BString 			&MoveInto(BString &into, int32 from, int32 length);
133 	void				MoveInto(char *into, int32 from, int32 length);
134 						/* caller guarantees that <into> is large enough */
135 
136 
137 /*---- Compare functions ---------------------------------------------------*/
138 	bool 				operator<(const BString &) const;
139 	bool 				operator<=(const BString &) const;
140 	bool 				operator==(const BString &) const;
141 	bool 				operator>=(const BString &) const;
142 	bool 				operator>(const BString &) const;
143 	bool 				operator!=(const BString &) const;
144 
145 	bool 				operator<(const char *) const;
146 	bool 				operator<=(const char *) const;
147 	bool 				operator==(const char *) const;
148 	bool 				operator>=(const char *) const;
149 	bool 				operator>(const char *) const;
150 	bool 				operator!=(const char *) const;
151 
152 /*---- strcmp-style compare functions --------------------------------------*/
153 	int 				Compare(const BString &) const;
154 	int 				Compare(const char *) const;
155 	int 				Compare(const BString &, int32 n) const;
156 	int 				Compare(const char *, int32 n) const;
157 	int 				ICompare(const BString &) const;
158 	int 				ICompare(const char *) const;
159 	int 				ICompare(const BString &, int32 n) const;
160 	int 				ICompare(const char *, int32 n) const;
161 
162 /*---- Searching -----------------------------------------------------------*/
163 	int32 				FindFirst(const BString &) const;
164 	int32 				FindFirst(const char *) const;
165 	int32 				FindFirst(const BString &, int32 fromOffset) const;
166 	int32 				FindFirst(const char *, int32 fromOffset) const;
167 	int32				FindFirst(char) const;
168 	int32				FindFirst(char, int32 fromOffset) const;
169 
170 	int32 				FindLast(const BString &) const;
171 	int32 				FindLast(const char *) const;
172 	int32 				FindLast(const BString &, int32 beforeOffset) const;
173 	int32 				FindLast(const char *, int32 beforeOffset) const;
174 	int32				FindLast(char) const;
175 	int32				FindLast(char, int32 beforeOffset) const;
176 
177 	int32 				IFindFirst(const BString &) const;
178 	int32 				IFindFirst(const char *) const;
179 	int32 				IFindFirst(const BString &, int32 fromOffset) const;
180 	int32 				IFindFirst(const char *, int32 fromOffset) const;
181 
182 	int32 				IFindLast(const BString &) const;
183 	int32 				IFindLast(const char *) const;
184 	int32 				IFindLast(const BString &, int32 beforeOffset) const;
185 	int32 				IFindLast(const char *, int32 beforeOffset) const;
186 
187 /*---- Replacing -----------------------------------------------------------*/
188 
189 	BString 			&ReplaceFirst(char replaceThis, char withThis);
190 	BString 			&ReplaceLast(char replaceThis, char withThis);
191 	BString 			&ReplaceAll(char replaceThis, char withThis,
192 							int32 fromOffset = 0);
193 	BString 			&Replace(char replaceThis, char withThis,
194 							int32 maxReplaceCount, int32 fromOffset = 0);
195 	BString 			&ReplaceFirst(const char *replaceThis,
196 							const char *withThis);
197 	BString 			&ReplaceLast(const char *replaceThis,
198 							const char *withThis);
199 	BString 			&ReplaceAll(const char *replaceThis,
200 							const char *withThis, int32 fromOffset = 0);
201 	BString 			&Replace(const char *replaceThis, const char *withThis,
202 							int32 maxReplaceCount, int32 fromOffset = 0);
203 
204 	BString 			&IReplaceFirst(char replaceThis, char withThis);
205 	BString 			&IReplaceLast(char replaceThis, char withThis);
206 	BString 			&IReplaceAll(char replaceThis, char withThis,
207 							int32 fromOffset = 0);
208 	BString 			&IReplace(char replaceThis, char withThis,
209 							int32 maxReplaceCount, int32 fromOffset = 0);
210 	BString 			&IReplaceFirst(const char *replaceThis,
211 							const char *withThis);
212 	BString 			&IReplaceLast(const char *replaceThis,
213 							const char *withThis);
214 	BString 			&IReplaceAll(const char *replaceThis,
215 							const char *withThis, int32 fromOffset = 0);
216 	BString 			&IReplace(const char *replaceThis, const char *withThis,
217 							int32 maxReplaceCount, int32 fromOffset = 0);
218 
219 	BString				&ReplaceSet(const char *setOfChars, char with);
220 	BString				&ReplaceSet(const char *setOfChars, const char *with);
221 /*---- Unchecked char access -----------------------------------------------*/
222 	char 				operator[](int32 index) const;
223 	char 				&operator[](int32 index);
224 
225 /*---- Checked char access -------------------------------------------------*/
226 	char 				ByteAt(int32 index) const;
227 
228 /*---- Fast low-level manipulation -----------------------------------------*/
229 	char 				*LockBuffer(int32 maxLength);
230 
231 		/* Make room for characters to be added by C-string like manipulation.
232 		 * Returns the equivalent of String(), <maxLength> includes space for
233 		 * trailing zero while used as C-string, it is illegal to call other
234 		 * BString routines that rely on data/length consistency until
235 		 * UnlockBuffer sets things up again.
236 		 */
237 
238 	BString 			&UnlockBuffer(int32 length = -1);
239 
240 		/* Finish using BString as C-string, adjusting length. If no length
241 		 * passed in, strlen of internal data is used to determine it.
242 		 * BString is in consistent state after this.
243 		 */
244 
245 /*---- Upercase<->Lowercase ------------------------------------------------*/
246 	BString				&ToLower();
247 	BString 			&ToUpper();
248 
249 	BString 			&Capitalize();
250 						/* Converts first character to upper-case, rest to
251 						 * lower-case
252 						 */
253 
254 	BString 			&CapitalizeEachWord();
255 						/* Converts first character in each
256 						 * non-alphabethycal-character-separated
257 						 * word to upper-case, rest to lower-case
258 						 */
259 /*----- Escaping and Deescaping --------------------------------------------*/
260 	BString				&CharacterEscape(const char *original,
261 							const char *setOfCharsToEscape, char escapeWith);
262 						/* copies original into <this>, escaping characters
263 						 * specified in <setOfCharsToEscape> by prepending
264 						 * them with <escapeWith>
265 						 */
266 	BString				&CharacterEscape(const char *setOfCharsToEscape,
267 							char escapeWith);
268 						/* escapes characters specified in <setOfCharsToEscape>
269 						 * by prepending them with <escapeWith>
270 						 */
271 
272 	BString				&CharacterDeescape(const char *original, char escapeChar);
273 						/* copy <original> into the string removing the escaping
274 						 * characters <escapeChar>
275 						 */
276 	BString				&CharacterDeescape(char escapeChar);
277 						/* remove the escaping characters <escapeChar> from
278 						 * the string
279 						 */
280 
281 /*---- Simple sprintf replacement calls ------------------------------------*/
282 /*---- Slower than sprintf but type and overflow safe ----------------------*/
283 	BString 		&operator<<(const char *);
284 	BString 		&operator<<(const BString &);
285 	BString 		&operator<<(char);
286 	BString 		&operator<<(int);
287 	BString 		&operator<<(unsigned int);
288 	BString 		&operator<<(uint32);
289 	BString 		&operator<<(int32);
290 	BString 		&operator<<(uint64);
291 	BString 		&operator<<(int64);
292 	BString 		&operator<<(float);
293 		/* float output hardcodes %.2f style formatting */
294 
295 /*----- Private or reserved ------------------------------------------------*/
296 private:
297 	void 			_Init(const char *, int32);
298 	void 			_DoAssign(const char *, int32);
299 	void 			_DoAppend(const char *, int32);
300 	char 			*_GrowBy(int32);
301 	char 			*_OpenAtBy(int32, int32);
302 	char 			*_ShrinkAtBy(int32, int32);
303 	void 			_DoPrepend(const char *, int32);
304 
305 	int32 			_FindAfter(const char *, int32, int32) const;
306 	int32 			_IFindAfter(const char *, int32, int32) const;
307 	int32 			_ShortFindAfter(const char *, int32) const;
308 	int32 			_FindBefore(const char *, int32, int32) const;
309 	int32 			_IFindBefore(const char *, int32, int32) const;
310 	BString			&_DoReplace(const char *, const char *, int32, int32,
311 								bool);
312 	void 			_SetLength(int32);
313 
314 #if DEBUG
315 	void			_SetUsingAsCString(bool);
316 	void 			_AssertNotUsingAsCString() const;
317 #else
318 	void 			_SetUsingAsCString(bool) {}
319 	void			_AssertNotUsingAsCString() const {}
320 #endif
321 
322 protected:
323 	char *_privateData;
324 };
325 
326 /*----- Comutative compare operators --------------------------------------*/
327 bool 				operator<(const char *, const BString &);
328 bool 				operator<=(const char *, const BString &);
329 bool 				operator==(const char *, const BString &);
330 bool 				operator>(const char *, const BString &);
331 bool 				operator>=(const char *, const BString &);
332 bool 				operator!=(const char *, const BString &);
333 
334 /*----- Non-member compare for sorting, etc. ------------------------------*/
335 int 				Compare(const BString &, const BString &);
336 int 				ICompare(const BString &, const BString &);
337 int 				Compare(const BString *, const BString *);
338 int 				ICompare(const BString *, const BString *);
339 
340 
341 
342 
343 /*-------------------------------------------------------------------------*/
344 /*---- No user serviceable parts after this -------------------------------*/
345 
346 inline int32
347 BString::Length() const
348 {
349 	return _privateData ? (*((int32 *)_privateData - 1) & 0x7fffffff) : 0;
350 		/* the most significant bit is reserved; accessing
351 		 * it in any way will cause the computer to explode
352 		 */
353 }
354 
355 inline const char *
356 BString::String() const
357 {
358 	if (!_privateData)
359 		return "";
360 	return _privateData;
361 }
362 
363 inline BString &
364 BString::SetTo(const char *str)
365 {
366 	return operator=(str);
367 }
368 
369 inline char
370 BString::operator[](int32 index) const
371 {
372 	return _privateData[index];
373 }
374 
375 inline char
376 BString::ByteAt(int32 index) const
377 {
378 	if (!_privateData || index < 0 || index > Length())
379 		return 0;
380 	return _privateData[index];
381 }
382 
383 inline BString &
384 BString::operator+=(const BString &string)
385 {
386 	_DoAppend(string.String(), string.Length());
387 	return *this;
388 }
389 
390 inline BString &
391 BString::Append(const BString &string)
392 {
393 	_DoAppend(string.String(), string.Length());
394 	return *this;
395 }
396 
397 inline BString &
398 BString::Append(const char *str)
399 {
400 	return operator+=(str);
401 }
402 
403 inline bool
404 BString::operator==(const BString &string) const
405 {
406 	return strcmp(String(), string.String()) == 0;
407 }
408 
409 inline bool
410 BString::operator<(const BString &string) const
411 {
412 	return strcmp(String(), string.String()) < 0;
413 }
414 
415 inline bool
416 BString::operator<=(const BString &string) const
417 {
418 	return strcmp(String(), string.String()) <= 0;
419 }
420 
421 inline bool
422 BString::operator>=(const BString &string) const
423 {
424 	return strcmp(String(), string.String()) >= 0;
425 }
426 
427 inline bool
428 BString::operator>(const BString &string) const
429 {
430 	return strcmp(String(), string.String()) > 0;
431 }
432 
433 inline bool
434 BString::operator!=(const BString &string) const
435 {
436 	return strcmp(String(), string.String()) != 0;
437 }
438 
439 inline bool
440 BString::operator!=(const char *str) const
441 {
442 	return !operator==(str);
443 }
444 
445 inline bool
446 operator<(const char *str, const BString &string)
447 {
448 	return string > str;
449 }
450 
451 inline bool
452 operator<=(const char *str, const BString &string)
453 {
454 	return string >= str;
455 }
456 
457 inline bool
458 operator==(const char *str, const BString &string)
459 {
460 	return string == str;
461 }
462 
463 inline bool
464 operator>(const char *str, const BString &string)
465 {
466 	return string < str;
467 }
468 
469 inline bool
470 operator>=(const char *str, const BString &string)
471 {
472 	return string <= str;
473 }
474 
475 inline bool
476 operator!=(const char *str, const BString &string)
477 {
478 	return string != str;
479 }
480 
481 #endif /* __BSTRING__ */
482