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