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