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