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