String.h revision 3fe7b3f7
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				CompareChars(const BString& string,
187								int32 charCount) const;
188			int				CompareChars(const char* string,
189								int32 charCount) const;
190
191			int				ICompare(const BString& string) const;
192			int				ICompare(const char* string) const;
193			int				ICompare(const BString& string, int32 length) const;
194			int				ICompare(const char* string, int32 length) const;
195
196			// Searching
197			int32			FindFirst(const BString& string) const;
198			int32			FindFirst(const char* string) const;
199			int32			FindFirst(const BString& string,
200								int32 fromOffset) const;
201			int32			FindFirst(const char* string,
202								int32 fromOffset) const;
203			int32			FindFirst(char c) const;
204			int32			FindFirst(char c, int32 fromOffset) const;
205
206			int32			FindFirstChars(const BString& string,
207								int32 fromCharOffset) const;
208			int32			FindFirstChars(const char* string,
209								int32 fromCharOffset) const;
210
211			int32			FindLast(const BString& string) const;
212			int32			FindLast(const char* string) const;
213			int32			FindLast(const BString& string,
214								int32 beforeOffset) const;
215			int32			FindLast(const char* string,
216								int32 beforeOffset) const;
217			int32			FindLast(char c) const;
218			int32			FindLast(char c, int32 beforeOffset) const;
219
220			int32			FindLastChars(const BString& string,
221								int32 beforeCharOffset) const;
222			int32			FindLastChars(const char* string,
223								int32 beforeCharOffset) const;
224
225			int32			IFindFirst(const BString& string) const;
226			int32			IFindFirst(const char* string) const;
227			int32			IFindFirst(const BString& string,
228								int32 fromOffset) const;
229			int32			IFindFirst(const char* string,
230								int32 fromOffset) const;
231
232			int32			IFindLast(const BString& string) const;
233			int32			IFindLast(const char* string) const;
234			int32			IFindLast(const BString& string,
235								int32 beforeOffset) const;
236			int32			IFindLast(const char* string,
237								int32 beforeOffset) const;
238
239			bool			StartsWith(const BString& string) const;
240			bool			StartsWith(const char* string) const;
241			bool			StartsWith(const char* string, int32 length) const;
242
243			bool			EndsWith(const BString& string) const;
244			bool			EndsWith(const char* string) const;
245			bool			EndsWith(const char* string, int32 length) const;
246
247			// Replacing
248			BString&		ReplaceFirst(char replaceThis, char withThis);
249			BString&		ReplaceLast(char replaceThis, char withThis);
250			BString&		ReplaceAll(char replaceThis, char withThis,
251								int32 fromOffset = 0);
252			BString&		Replace(char replaceThis, char withThis,
253								int32 maxReplaceCount, int32 fromOffset = 0);
254			BString&		ReplaceFirst(const char* replaceThis,
255								const char* withThis);
256			BString&		ReplaceLast(const char* replaceThis,
257								const char* withThis);
258			BString&		ReplaceAll(const char* replaceThis,
259								const char* withThis, int32 fromOffset = 0);
260			BString&		Replace(const char* replaceThis,
261								const char* withThis, int32 maxReplaceCount,
262								int32 fromOffset = 0);
263
264			BString&		ReplaceAllChars(const char* replaceThis,
265								const char* withThis, int32 fromCharOffset);
266			BString&		ReplaceChars(const char* replaceThis,
267								const char* withThis, int32 maxReplaceCount,
268								int32 fromCharOffset);
269
270			BString&		IReplaceFirst(char replaceThis, char withThis);
271			BString&		IReplaceLast(char replaceThis, char withThis);
272			BString&		IReplaceAll(char replaceThis, char withThis,
273								int32 fromOffset = 0);
274			BString&		IReplace(char replaceThis, char withThis,
275								int32 maxReplaceCount, int32 fromOffset = 0);
276			BString&		IReplaceFirst(const char* replaceThis,
277								const char* withThis);
278			BString&		IReplaceLast(const char* replaceThis,
279								const char* withThis);
280			BString&		IReplaceAll(const char* replaceThis,
281								const char* withThis, int32 fromOffset = 0);
282			BString&		IReplace(const char* replaceThis,
283								const char* withThis, int32 maxReplaceCount,
284								int32 fromOffset = 0);
285
286			BString&		ReplaceSet(const char* setOfBytes, char with);
287			BString&		ReplaceSet(const char* setOfBytes,
288								const char* with);
289
290			BString&		ReplaceCharsSet(const char* setOfChars,
291								const char* with);
292
293			// Unchecked char access
294			char			operator[](int32 index) const;
295
296#if __GNUC__ > 3
297			BStringRef		operator[](int32 index);
298#else
299			char&			operator[](int32 index);
300#endif
301
302			// Checked char access
303			char			ByteAt(int32 index) const;
304			const char*		CharAt(int32 charIndex, int32* bytes = NULL) const;
305			bool			CharAt(int32 charIndex, char* buffer,
306								int32* bytes) const;
307
308			// Fast low-level manipulation
309			char*			LockBuffer(int32 maxLength);
310			BString&		UnlockBuffer(int32 length = -1);
311
312			// Upercase <-> Lowercase
313			BString&		ToLower();
314			BString&		ToUpper();
315
316			BString&		Capitalize();
317			BString&		CapitalizeEachWord();
318
319			// Escaping and De-escaping
320			BString&		CharacterEscape(const char* original,
321								const char* setOfCharsToEscape,
322								char escapeWith);
323			BString&		CharacterEscape(const char* setOfCharsToEscape,
324								char escapeWith);
325			BString&		CharacterDeescape(const char* original,
326								char escapeChar);
327			BString&		CharacterDeescape(char escapeChar);
328
329			// Trimming
330			BString&		Trim();
331
332			// Insert
333			BString&		operator<<(const char* string);
334			BString&		operator<<(const BString& string);
335			BString&		operator<<(char c);
336			BString&		operator<<(bool value);
337			BString&		operator<<(int value);
338			BString&		operator<<(unsigned int value);
339			BString&		operator<<(unsigned long value);
340			BString&		operator<<(long value);
341			BString&		operator<<(unsigned long long value);
342			BString&		operator<<(long long value);
343			// float/double output hardcodes %.2f style formatting
344			BString&		operator<<(float value);
345			BString&		operator<<(double value);
346
347public:
348			class Private;
349			friend class Private;
350
351private:
352			class PosVect;
353			friend class BStringRef;
354
355			enum PrivateDataTag {
356				PRIVATE_DATA
357			};
358
359private:
360							BString(char* privateData, PrivateDataTag tag);
361
362			// Management
363			status_t		_MakeWritable();
364			status_t		_MakeWritable(int32 length, bool copy);
365	static	char*			_Allocate(int32 length);
366			char*			_Resize(int32 length);
367			void			_Init(const char* src, int32 length);
368			char*			_Clone(const char* data, int32 length);
369			char*			_OpenAtBy(int32 offset, int32 length);
370			char*			_ShrinkAtBy(int32 offset, int32 length);
371
372			// Data
373			void			_SetLength(int32 length);
374			bool			_DoAppend(const char* string, int32 length);
375			bool			_DoPrepend(const char* string, int32 length);
376			bool			_DoInsert(const char* string, int32 offset,
377								int32 length);
378
379			// Search
380			int32			_ShortFindAfter(const char* string,
381								int32 length) const;
382			int32			_FindAfter(const char* string, int32 offset,
383								int32 length) const;
384			int32			_IFindAfter(const char* string, int32 offset,
385								int32 length) const;
386			int32			_FindBefore(const char* string, int32 offset,
387								int32 length) const;
388			int32			_IFindBefore(const char* string, int32 offset,
389								int32 length) const;
390
391			// Escape
392			BString&		_DoCharacterEscape(const char* string,
393								const char* setOfCharsToEscape, char escapeChar);
394			BString&		_DoCharacterDeescape(const char* string,
395								char escapeChar);
396
397			// Replace
398			BString&		_DoReplace(const char* findThis,
399								const char* replaceWith, int32 maxReplaceCount,
400								int32 fromOffset, bool ignoreCase);
401			void			_ReplaceAtPositions(const PosVect* positions,
402								int32 searchLength, const char* with,
403								int32 withLength);
404
405private:
406			int32& 			_ReferenceCount();
407			const int32& 	_ReferenceCount() const;
408			bool			_IsShareable() const;
409			void			_FreePrivateData();
410
411			char*			fPrivateData;
412};
413
414
415// Commutative compare operators
416bool operator<(const char* a, const BString& b);
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);
422
423
424// Non-member compare for sorting, etc.
425int Compare(const BString& a, const BString& b);
426int ICompare(const BString& a, const BString& b);
427int Compare(const BString* a, const BString* b);
428int ICompare(const BString* a, const BString* b);
429
430
431inline int32
432BString::Length() const
433{
434	// the most significant bit is reserved; accessing
435	// it in any way will cause the computer to explode
436	return fPrivateData ? (*(((int32*)fPrivateData) - 1) & 0x7fffffff) : 0;
437}
438
439
440inline bool
441BString::IsEmpty() const
442{
443	return !Length();
444}
445
446
447inline const char*
448BString::String() const
449{
450	if (!fPrivateData)
451		return "";
452	return fPrivateData;
453}
454
455
456inline uint32
457BString::HashValue() const
458{
459	return HashValue(String());
460}
461
462
463inline BString&
464BString::SetTo(const char* string)
465{
466	return operator=(string);
467}
468
469
470inline char
471BString::operator[](int32 index) const
472{
473	return fPrivateData[index];
474}
475
476
477inline char
478BString::ByteAt(int32 index) const
479{
480	if (!fPrivateData || index < 0 || index >= Length())
481		return 0;
482	return fPrivateData[index];
483}
484
485
486inline BString&
487BString::operator+=(const BString& string)
488{
489	_DoAppend(string.String(), string.Length());
490	return *this;
491}
492
493
494inline BString&
495BString::Append(const BString& string)
496{
497	_DoAppend(string.String(), string.Length());
498	return *this;
499}
500
501
502inline BString&
503BString::Append(const char* string)
504{
505	return operator+=(string);
506}
507
508
509inline bool
510BString::operator==(const BString& string) const
511{
512	return strcmp(String(), string.String()) == 0;
513}
514
515
516inline bool
517BString::operator<(const BString& string) const
518{
519	return strcmp(String(), string.String()) < 0;
520}
521
522
523inline bool
524BString::operator<=(const BString& string) const
525{
526	return strcmp(String(), string.String()) <= 0;
527}
528
529
530inline bool
531BString::operator>=(const BString& string) const
532{
533	return strcmp(String(), string.String()) >= 0;
534}
535
536
537inline bool
538BString::operator>(const BString& string) const
539{
540	return strcmp(String(), string.String()) > 0;
541}
542
543
544inline bool
545BString::operator!=(const BString& string) const
546{
547	return strcmp(String(), string.String()) != 0;
548}
549
550
551inline bool
552BString::operator!=(const char* string) const
553{
554	return !operator==(string);
555}
556
557
558inline
559BString::operator const char*() const
560{
561	return String();
562}
563
564
565inline bool
566operator<(const char* str, const BString& string)
567{
568	return string > str;
569}
570
571
572inline bool
573operator<=(const char* str, const BString& string)
574{
575	return string >= str;
576}
577
578
579inline bool
580operator==(const char* str, const BString& string)
581{
582	return string == str;
583}
584
585
586inline bool
587operator>(const char* str, const BString& string)
588{
589	return string < str;
590}
591
592
593inline bool
594operator>=(const char* str, const BString& string)
595{
596	return string <= str;
597}
598
599
600inline bool
601operator!=(const char* str, const BString& string)
602{
603	return string != str;
604}
605
606
607//	#pragma mark - BStringRef
608
609
610class BStringRef {
611public:
612	BStringRef(BString& string, int32 position);
613	~BStringRef() {}
614
615	operator char() const;
616
617	char* operator&();
618	const char* operator&() const;
619
620	BStringRef& operator=(char c);
621	BStringRef& operator=(const BStringRef& rc);
622
623private:
624	BString&	fString;
625	int32		fPosition;
626};
627
628
629#endif	// _B_STRING_H
630