xref: /haiku/headers/build/os/support/String.h (revision b55a57da7173b9af0432bd3e148d03f06161d036)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2003, 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<<(unsigned long);
289 	BString 		&operator<<(long);
290 	BString 		&operator<<(unsigned long long);
291 	BString 		&operator<<(long long);
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 	char			*_Alloc( int32);
323 
324 	struct PosVect;
325 	void 			_ReplaceAtPositions( const PosVect* positions,
326 											   int32 searchLen,
327 											   const char* with,
328 											   int32 withLen);
329 
330 protected:
331 	char *_privateData;
332 };
333 
334 /*----- Comutative compare operators --------------------------------------*/
335 bool 				operator<(const char *, const BString &);
336 bool 				operator<=(const char *, const BString &);
337 bool 				operator==(const char *, const BString &);
338 bool 				operator>(const char *, const BString &);
339 bool 				operator>=(const char *, const BString &);
340 bool 				operator!=(const char *, const BString &);
341 
342 /*----- Non-member compare for sorting, etc. ------------------------------*/
343 int 				Compare(const BString &, const BString &);
344 int 				ICompare(const BString &, const BString &);
345 int 				Compare(const BString *, const BString *);
346 int 				ICompare(const BString *, const BString *);
347 
348 
349 
350 
351 /*-------------------------------------------------------------------------*/
352 /*---- No user serviceable parts after this -------------------------------*/
353 
354 inline int32
355 BString::Length() const
356 {
357 	return _privateData ? (*((int32 *)_privateData - 1) & 0x7fffffff) : 0;
358 		/* the most significant bit is reserved; accessing
359 		 * it in any way will cause the computer to explode
360 		 */
361 }
362 
363 inline const char *
364 BString::String() const
365 {
366 	if (!_privateData)
367 		return "";
368 	return _privateData;
369 }
370 
371 inline BString &
372 BString::SetTo(const char *str)
373 {
374 	return operator=(str);
375 }
376 
377 inline char
378 BString::operator[](int32 index) const
379 {
380 	return _privateData[index];
381 }
382 
383 inline char
384 BString::ByteAt(int32 index) const
385 {
386 	if (!_privateData || index < 0 || index > Length())
387 		return 0;
388 	return _privateData[index];
389 }
390 
391 inline BString &
392 BString::operator+=(const BString &string)
393 {
394 	_DoAppend(string.String(), string.Length());
395 	return *this;
396 }
397 
398 inline BString &
399 BString::Append(const BString &string)
400 {
401 	_DoAppend(string.String(), string.Length());
402 	return *this;
403 }
404 
405 inline BString &
406 BString::Append(const char *str)
407 {
408 	return operator+=(str);
409 }
410 
411 inline bool
412 BString::operator==(const BString &string) const
413 {
414 	return strcmp(String(), string.String()) == 0;
415 }
416 
417 inline bool
418 BString::operator<(const BString &string) const
419 {
420 	return strcmp(String(), string.String()) < 0;
421 }
422 
423 inline bool
424 BString::operator<=(const BString &string) const
425 {
426 	return strcmp(String(), string.String()) <= 0;
427 }
428 
429 inline bool
430 BString::operator>=(const BString &string) const
431 {
432 	return strcmp(String(), string.String()) >= 0;
433 }
434 
435 inline bool
436 BString::operator>(const BString &string) const
437 {
438 	return strcmp(String(), string.String()) > 0;
439 }
440 
441 inline bool
442 BString::operator!=(const BString &string) const
443 {
444 	return strcmp(String(), string.String()) != 0;
445 }
446 
447 inline bool
448 BString::operator!=(const char *str) const
449 {
450 	return !operator==(str);
451 }
452 
453 inline bool
454 operator<(const char *str, const BString &string)
455 {
456 	return string > str;
457 }
458 
459 inline bool
460 operator<=(const char *str, const BString &string)
461 {
462 	return string >= str;
463 }
464 
465 inline bool
466 operator==(const char *str, const BString &string)
467 {
468 	return string == str;
469 }
470 
471 inline bool
472 operator>(const char *str, const BString &string)
473 {
474 	return string < str;
475 }
476 
477 inline bool
478 operator>=(const char *str, const BString &string)
479 {
480 	return string <= str;
481 }
482 
483 inline bool
484 operator!=(const char *str, const BString &string)
485 {
486 	return string != str;
487 }
488 
489 #endif /* __BSTRING__ */
490