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