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