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