xref: /haiku/headers/os/support/String.h (revision ac078a5b110045de12089052a685a6a080545db1)
1 /*
2  * Copyright 2001-2010, Haiku Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef __BSTRING__
6 #define __BSTRING__
7 
8 
9 #include <BeBuild.h>
10 #include <SupportDefs.h>
11 #include <string.h>
12 
13 
14 class BStringRef;
15 
16 
17 class BString {
18 public:
19 							BString();
20 							BString(const char* string);
21 							BString(const BString& string);
22 							BString(const char* string, int32 maxLength);
23 							~BString();
24 
25 			// Access
26 			const char*		String() const;
27 			int32 			Length() const;
28 			int32			CountChars() const;
29 			int32			CountBytes(int32 fromCharOffset,
30 								int32 charCount) const;
31 			bool			IsEmpty() const;
32 
33 			// Assignment
34 			BString&		operator=(const BString& string);
35 			BString&		operator=(const char* string);
36 			BString&		operator=(char c);
37 
38 			BString&		SetTo(const char* string);
39 			BString&		SetTo(const char* string, int32 maxLength);
40 
41 			BString&		SetTo(const BString& string);
42 			BString&		Adopt(BString& from);
43 
44 			BString&		SetTo(const BString& string, int32 maxLength);
45 			BString&		Adopt(BString& from, int32 maxLength);
46 
47 			BString&		SetTo(char c, int32 count);
48 
49 			BString&		SetToChars(const char* string, int32 charCount);
50 			BString&		SetToChars(const BString& string, int32 charCount);
51 			BString&		AdoptChars(BString& from, int32 charCount);
52 
53 			BString&		SetToFormat(const char* format, ...);
54 
55 			// Substring copying
56 			BString&		CopyInto(BString& into, int32 fromOffset,
57 								int32 length) const;
58 			void			CopyInto(char* into, int32 fromOffset,
59 								int32 length) const;
60 
61 			BString&		CopyCharsInto(BString& into, int32 fromCharOffset,
62 								int32 charCount) const;
63 			bool			CopyCharsInto(char* into, int32* intoLength,
64 								int32 fromCharOffset, int32 charCount) const;
65 
66 			// Appending
67 			BString&		operator+=(const BString& string);
68 			BString&		operator+=(const char* string);
69 			BString&		operator+=(char c);
70 
71 			BString&		Append(const BString& string);
72 			BString&		Append(const char* string);
73 
74 			BString&		Append(const BString& string, int32 length);
75 			BString&		Append(const char* string, int32 length);
76 			BString&		Append(char c, int32 count);
77 
78 			BString&		AppendChars(const BString& string, int32 charCount);
79 			BString&		AppendChars(const char* string, int32 charCount);
80 
81 			// Prepending
82 			BString&		Prepend(const char* string);
83 			BString&		Prepend(const BString& string);
84 			BString&		Prepend(const char* string, int32 length);
85 			BString&		Prepend(const BString& string, int32 length);
86 			BString&		Prepend(char c, int32 count);
87 
88 			BString&		PrependChars(const char* string, int32 charCount);
89 			BString&		PrependChars(const BString& string,
90 								int32 charCount);
91 
92 			// Inserting
93 			BString&		Insert(const char* string, int32 position);
94 			BString&		Insert(const char* string, int32 length,
95 								int32 position);
96 			BString&		Insert(const char* string, int32 fromOffset,
97 								int32 length, int32 position);
98 			BString&		Insert(const BString& string, int32 position);
99 			BString&		Insert(const BString& string, int32 length,
100 								int32 position);
101 			BString&		Insert(const BString& string, int32 fromOffset,
102 								int32 length, int32 position);
103 			BString&		Insert(char c, int32 count, int32 position);
104 
105 			BString&		InsertChars(const char* string, int32 charPosition);
106 			BString&		InsertChars(const char* string, int32 charCount,
107 								int32 charPosition);
108 			BString&		InsertChars(const char* string,
109 								int32 fromCharOffset, int32 charCount,
110 								int32 charPosition);
111 			BString&		InsertChars(const BString& string,
112 								int32 charPosition);
113 			BString&		InsertChars(const BString& string, int32 charCount,
114 								int32 charPosition);
115 			BString&		InsertChars(const BString& string,
116 								int32 fromCharOffset, int32 charCount,
117 								int32 charPosition);
118 
119 			// Removing
120 			BString&		Truncate(int32 newLength, bool lazy = true);
121 			BString&		TruncateChars(int32 newCharCount, bool lazy = true);
122 
123 			BString&		Remove(int32 from, int32 length);
124 			BString&		RemoveChars(int32 fromCharOffset, int32 charCount);
125 
126 			BString&		RemoveFirst(const BString& string);
127 			BString&		RemoveLast(const BString& string);
128 			BString&		RemoveAll(const BString& string);
129 
130 			BString&		RemoveFirst(const char* string);
131 			BString&		RemoveLast(const char* string);
132 			BString&		RemoveAll(const char* string);
133 
134 			BString&		RemoveSet(const char* setOfBytesToRemove);
135 			BString&		RemoveCharsSet(const char* setOfCharsToRemove);
136 
137 			BString&		MoveInto(BString& into, int32 from, int32 length);
138 			void			MoveInto(char* into, int32 from, int32 length);
139 
140 			BString&		MoveCharsInto(BString& into, int32 fromCharOffset,
141 								int32 charCount);
142 			bool			MoveCharsInto(char* into, int32* intoLength,
143 								int32 fromCharOffset, int32 charCount);
144 
145 			// Compare functions
146 			bool			operator<(const BString& string) const;
147 			bool			operator<=(const BString& string) const;
148 			bool			operator==(const BString& string) const;
149 			bool			operator>=(const BString& string) const;
150 			bool			operator>(const BString& string) const;
151 			bool			operator!=(const BString& string) const;
152 
153 			bool			operator<(const char* string) const;
154 			bool			operator<=(const char* string) const;
155 			bool			operator==(const char* string) const;
156 			bool			operator>=(const char* string) const;
157 			bool			operator>(const char* string) const;
158 			bool			operator!=(const char* string) const;
159 
160 							operator const char*() const;
161 
162 			// strcmp()-style compare functions
163 			int				Compare(const BString& string) const;
164 			int				Compare(const char* string) const;
165 			int				Compare(const BString& string, int32 length) const;
166 			int				Compare(const char* string, int32 length) const;
167 
168 			int				CompareChars(const BString& string,
169 								int32 charCount) const;
170 			int				CompareChars(const char* string,
171 								int32 charCount) const;
172 
173 			int				ICompare(const BString& string) const;
174 			int				ICompare(const char* string) const;
175 			int				ICompare(const BString& string, int32 length) const;
176 			int				ICompare(const char* string, int32 length) const;
177 
178 			// Searching
179 			int32			FindFirst(const BString& string) const;
180 			int32			FindFirst(const char* string) const;
181 			int32			FindFirst(const BString& string,
182 								int32 fromOffset) const;
183 			int32			FindFirst(const char* string,
184 								int32 fromOffset) const;
185 			int32			FindFirst(char c) const;
186 			int32			FindFirst(char c, int32 fromOffset) const;
187 
188 			int32			FindFirstChars(const BString& string,
189 								int32 fromCharOffset) const;
190 			int32			FindFirstChars(const char* string,
191 								int32 fromCharOffset) const;
192 
193 			int32			FindLast(const BString& string) const;
194 			int32			FindLast(const char* string) const;
195 			int32			FindLast(const BString& string,
196 								int32 beforeOffset) const;
197 			int32			FindLast(const char* string,
198 								int32 beforeOffset) const;
199 			int32			FindLast(char c) const;
200 			int32			FindLast(char c, int32 beforeOffset) const;
201 
202 			int32			FindLastChars(const BString& string,
203 								int32 beforeCharOffset) const;
204 			int32			FindLastChars(const char* string,
205 								int32 beforeCharOffset) const;
206 
207 			int32			IFindFirst(const BString& string) const;
208 			int32			IFindFirst(const char* string) const;
209 			int32			IFindFirst(const BString& string,
210 								int32 fromOffset) const;
211 			int32			IFindFirst(const char* string,
212 								int32 fromOffset) const;
213 
214 			int32			IFindLast(const BString& string) const;
215 			int32			IFindLast(const char* string) const;
216 			int32			IFindLast(const BString& string,
217 								int32 beforeOffset) const;
218 			int32			IFindLast(const char* string,
219 								int32 beforeOffset) const;
220 
221 			// Replacing
222 			BString&		ReplaceFirst(char replaceThis, char withThis);
223 			BString&		ReplaceLast(char replaceThis, char withThis);
224 			BString&		ReplaceAll(char replaceThis, char withThis,
225 								int32 fromOffset = 0);
226 			BString&		Replace(char replaceThis, char withThis,
227 								int32 maxReplaceCount, int32 fromOffset = 0);
228 			BString&		ReplaceFirst(const char* replaceThis,
229 								const char* withThis);
230 			BString&		ReplaceLast(const char* replaceThis,
231 								const char* withThis);
232 			BString&		ReplaceAll(const char* replaceThis,
233 								const char* withThis, int32 fromOffset = 0);
234 			BString&		Replace(const char* replaceThis,
235 								const char* withThis, int32 maxReplaceCount,
236 								int32 fromOffset = 0);
237 
238 			BString&		ReplaceAllChars(const char* replaceThis,
239 								const char* withThis, int32 fromCharOffset);
240 			BString&		ReplaceChars(const char* replaceThis,
241 								const char* withThis, int32 maxReplaceCount,
242 								int32 fromCharOffset);
243 
244 			BString&		IReplaceFirst(char replaceThis, char withThis);
245 			BString&		IReplaceLast(char replaceThis, char withThis);
246 			BString&		IReplaceAll(char replaceThis, char withThis,
247 								int32 fromOffset = 0);
248 			BString&		IReplace(char replaceThis, char withThis,
249 								int32 maxReplaceCount, int32 fromOffset = 0);
250 			BString&		IReplaceFirst(const char* replaceThis,
251 								const char* withThis);
252 			BString&		IReplaceLast(const char* replaceThis,
253 								const char* withThis);
254 			BString&		IReplaceAll(const char* replaceThis,
255 								const char* withThis, int32 fromOffset = 0);
256 			BString&		IReplace(const char* replaceThis,
257 								const char* withThis, int32 maxReplaceCount,
258 								int32 fromOffset = 0);
259 
260 			BString&		ReplaceSet(const char* setOfBytes, char with);
261 			BString&		ReplaceSet(const char* setOfBytes,
262 								const char* with);
263 
264 			BString&		ReplaceCharsSet(const char* setOfChars,
265 								const char* with);
266 
267 			// Unchecked char access
268 			char			operator[](int32 index) const;
269 
270 #if __GNUC__ > 3
271 			BStringRef		operator[](int32 index);
272 #else
273 			char&			operator[](int32 index);
274 #endif
275 
276 			// Checked char access
277 			char			ByteAt(int32 index) const;
278 			const char*		CharAt(int32 charIndex, int32* bytes = NULL) const;
279 			bool			CharAt(int32 charIndex, char* buffer,
280 								int32* bytes) const;
281 
282 			// Fast low-level manipulation
283 			char*			LockBuffer(int32 maxLength);
284 			BString&		UnlockBuffer(int32 length = -1);
285 
286 			// Upercase <-> Lowercase
287 			BString&		ToLower();
288 			BString&		ToUpper();
289 
290 			BString&		Capitalize();
291 			BString&		CapitalizeEachWord();
292 
293 			// Escaping and De-escaping
294 			BString&		CharacterEscape(const char* original,
295 								const char* setOfCharsToEscape,
296 								char escapeWith);
297 			BString&		CharacterEscape(const char* setOfCharsToEscape,
298 								char escapeWith);
299 			BString&		CharacterDeescape(const char* original,
300 								char escapeChar);
301 			BString&		CharacterDeescape(char escapeChar);
302 
303 			// Trimming
304 			BString&		Trim();
305 
306 			// Insert
307 			BString&		operator<<(const char* string);
308 			BString&		operator<<(const BString& string);
309 			BString&		operator<<(char c);
310 			BString&		operator<<(int value);
311 			BString&		operator<<(unsigned int value);
312 			BString&		operator<<(uint32 value);
313 			BString&		operator<<(int32 value);
314 			BString&		operator<<(uint64 value);
315 			BString&		operator<<(int64 value);
316 			// float output hardcodes %.2f style formatting
317 			BString&		operator<<(float value);
318 
319 private:
320 	class PosVect;
321 	friend class BStringRef;
322 
323 			// Management
324 			status_t		_MakeWritable();
325 			status_t		_MakeWritable(int32 length, bool copy);
326 	static	char*			_Allocate(int32 length);
327 			char*			_Resize(int32 length);
328 			void			_Init(const char* src, int32 length);
329 			char*			_Clone(const char* data, int32 length);
330 			char*			_OpenAtBy(int32 offset, int32 length);
331 			char*			_ShrinkAtBy(int32 offset, int32 length);
332 
333 			// Data
334 			void			_SetLength(int32 length);
335 			bool			_DoAppend(const char* string, int32 length);
336 			bool			_DoPrepend(const char* string, int32 length);
337 			bool			_DoInsert(const char* string, int32 offset,
338 								int32 length);
339 
340 			// Search
341 			int32			_ShortFindAfter(const char* string,
342 								int32 length) const;
343 			int32			_FindAfter(const char* string, int32 offset,
344 								int32 length) const;
345 			int32			_IFindAfter(const char* string, int32 offset,
346 								int32 length) const;
347 			int32			_FindBefore(const char* string, int32 offset,
348 								int32 length) const;
349 			int32			_IFindBefore(const char* string, int32 offset,
350 								int32 length) const;
351 
352 			// Escape
353 			BString&		_DoCharacterEscape(const char* string,
354 								const char *setOfCharsToEscape, char escapeChar);
355 			BString&		_DoCharacterDeescape(const char* string,
356 								char escapeChar);
357 
358 			// Replace
359 			BString&		_DoReplace(const char* findThis,
360 								const char* replaceWith, int32 maxReplaceCount,
361 								int32 fromOffset, bool ignoreCase);
362 			void			_ReplaceAtPositions(const PosVect* positions,
363 								int32 searchLength, const char* with,
364 								int32 withLength);
365 
366 private:
367 			vint32& 		_ReferenceCount();
368 			const vint32& 	_ReferenceCount() const;
369 			bool			_IsShareable() const;
370 			void			_FreePrivateData();
371 
372 			char*			fPrivateData;
373 };
374 
375 
376 // Commutative compare operators
377 bool operator<(const char* a, const BString& b);
378 bool operator<=(const char* a, const BString& b);
379 bool operator==(const char* a, const BString& b);
380 bool operator>(const char* a, const BString& b);
381 bool operator>=(const char* a, const BString& b);
382 bool operator!=(const char* a, const BString& b);
383 
384 
385 // Non-member compare for sorting, etc.
386 int Compare(const BString& a, const BString& b);
387 int ICompare(const BString& a, const BString& b);
388 int Compare(const BString* a, const BString* b);
389 int ICompare(const BString* a, const BString* b);
390 
391 
392 inline int32
393 BString::Length() const
394 {
395 	// the most significant bit is reserved; accessing
396 	// it in any way will cause the computer to explode
397 	return fPrivateData ? (*(((int32 *)fPrivateData) - 1) & 0x7fffffff) : 0;
398 }
399 
400 
401 inline bool
402 BString::IsEmpty() const
403 {
404 	return !Length();
405 }
406 
407 
408 inline const char*
409 BString::String() const
410 {
411 	if (!fPrivateData)
412 		return "";
413 	return fPrivateData;
414 }
415 
416 
417 inline BString &
418 BString::SetTo(const char* string)
419 {
420 	return operator=(string);
421 }
422 
423 
424 inline char
425 BString::operator[](int32 index) const
426 {
427 	return fPrivateData[index];
428 }
429 
430 
431 inline char
432 BString::ByteAt(int32 index) const
433 {
434 	if (!fPrivateData || index < 0 || index >= Length())
435 		return 0;
436 	return fPrivateData[index];
437 }
438 
439 
440 inline BString &
441 BString::operator+=(const BString &string)
442 {
443 	_DoAppend(string.String(), string.Length());
444 	return *this;
445 }
446 
447 
448 inline BString &
449 BString::Append(const BString &string)
450 {
451 	_DoAppend(string.String(), string.Length());
452 	return *this;
453 }
454 
455 
456 inline BString &
457 BString::Append(const char* string)
458 {
459 	return operator+=(string);
460 }
461 
462 
463 inline bool
464 BString::operator==(const BString &string) const
465 {
466 	return strcmp(String(), string.String()) == 0;
467 }
468 
469 
470 inline bool
471 BString::operator<(const BString &string) const
472 {
473 	return strcmp(String(), string.String()) < 0;
474 }
475 
476 
477 inline bool
478 BString::operator<=(const BString &string) const
479 {
480 	return strcmp(String(), string.String()) <= 0;
481 }
482 
483 
484 inline bool
485 BString::operator>=(const BString &string) const
486 {
487 	return strcmp(String(), string.String()) >= 0;
488 }
489 
490 
491 inline bool
492 BString::operator>(const BString &string) const
493 {
494 	return strcmp(String(), string.String()) > 0;
495 }
496 
497 
498 inline bool
499 BString::operator!=(const BString &string) const
500 {
501 	return strcmp(String(), string.String()) != 0;
502 }
503 
504 
505 inline bool
506 BString::operator!=(const char* string) const
507 {
508 	return !operator==(string);
509 }
510 
511 
512 inline
513 BString::operator const char*() const
514 {
515 	return String();
516 }
517 
518 
519 inline bool
520 operator<(const char *str, const BString &string)
521 {
522 	return string > str;
523 }
524 
525 
526 inline bool
527 operator<=(const char *str, const BString &string)
528 {
529 	return string >= str;
530 }
531 
532 
533 inline bool
534 operator==(const char *str, const BString &string)
535 {
536 	return string == str;
537 }
538 
539 
540 inline bool
541 operator>(const char *str, const BString &string)
542 {
543 	return string < str;
544 }
545 
546 
547 inline bool
548 operator>=(const char *str, const BString &string)
549 {
550 	return string <= str;
551 }
552 
553 
554 inline bool
555 operator!=(const char *str, const BString &string)
556 {
557 	return string != str;
558 }
559 
560 
561 //	#pragma mark - BStringRef
562 
563 
564 class BStringRef {
565 public:
566 	BStringRef(BString& string, int32 position);
567 	~BStringRef() {}
568 
569 	operator char() const;
570 
571 	char* operator&();
572 	const char* operator&() const;
573 
574 	BStringRef& operator=(char c);
575 	BStringRef& operator=(const BStringRef& rc);
576 
577 private:
578 	BString&	fString;
579 	int32		fPosition;
580 };
581 
582 #endif	// __BSTRING__
583