"Fossies" - the Fresh Open Source Software Archive 
Member "muscle/util/String.h" (21 Nov 2020, 69684 Bytes) of package /linux/privat/muscle7.62.zip:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "String.h" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
7.61_vs_7.62.
1 /* This file is Copyright 2000-2013 Meyer Sound Laboratories Inc. See the included LICENSE.txt file for details. */
2
3 /* NOTE TO MACOS/X X-CODE USERS: If you are trying to #include <string.h>
4 * and X-Code is "helpfully" pulling in this file instead (because the
5 * OS/X filesystem is case-insensitive), you can get around that problem
6 * by adding "USE_HEADERMAP = NO" to your X-Code target settings.
7 * ref: http://lists.apple.com/archives/xcode-users/2004/Aug/msg00934.html
8 * --Jeremy
9 */
10
11 #ifndef MuscleString_h
12 #define MuscleString_h
13
14 #include <ctype.h>
15 #include "support/PseudoFlattenable.h"
16 #include "syslog/SysLog.h"
17 #include "system/GlobalMemoryAllocator.h" // for muscleFree()
18 #include "util/Hashtable.h"
19
20 #ifdef __APPLE__
21 // Using a forward declaration rather than an #include here to avoid pulling in other things like Mac's
22 // Point and Rect typedefs, that can cause ambiguities with Muscle's Point and Rect classes.
23 struct __CFString;
24 typedef const struct __CFString * CFStringRef;
25 #endif
26
27 namespace muscle {
28
29 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
30 # ifdef MUSCLE_COUNT_STRING_COPY_OPERATIONS
31 enum {
32 STRING_OP_DEFAULT_CTOR = 0,
33 STRING_OP_CSTR_CTOR,
34 STRING_OP_COPY_CTOR,
35 STRING_OP_PARTIAL_COPY_CTOR,
36 STRING_OP_SET_FROM_CSTR,
37 STRING_OP_SET_FROM_STRING,
38 STRING_OP_MOVE_CTOR,
39 STRING_OP_MOVE_FROM_STRING,
40 STRING_OP_DTOR,
41 NUM_STRING_OPS
42 };
43 extern uint32 _stringOpCounts[NUM_STRING_OPS];
44 extern void PrintAndClearStringCopyCounts(const char * optDesc = NULL);
45 # define MUSCLE_INCREMENT_STRING_OP_COUNT(which) _stringOpCounts[which]++
46 # else
47 # define MUSCLE_INCREMENT_STRING_OP_COUNT(which)
48 static inline void PrintAndClearStringCopyCounts(const char * optDesc = NULL) {(void) optDesc;}
49 # endif
50 #endif
51
52 class Point;
53 class Rect;
54
55 #ifndef SMALL_MUSCLE_STRING_LENGTH
56 /** Defines the number of ASCII characters that may be held "inline" in a String object, without requiring a separate heap allocation. If not specified explicitly via a compiler argument (e.g. -DSMALL_MUSCLE_STRING_LENGTH=15), it defaults to 7, and 7 ASCII-chars plus one NUL byte exactly match the space required for a 64-bit pointer, and thus can be used with no space-penalty. Beware that setting this to a value greater than 7 will cause sizeof(String) to increase. */
57 # define SMALL_MUSCLE_STRING_LENGTH 7
58 #endif
59
60 /** Same as strcmp(), except that it will sort numbers within the string numerically rather than lexically.
61 * @param s1 The first of the two strings to compare using the number-aware comparison algorithm.
62 * @param s2 The second of the two strings to compare using the number-aware comparison algorithm.
63 * @returns 0 if the two strings are equal, >0 if (s2) is the "later" string, or <0 if (s1) is the "later" string.
64 */
65 int NumericAwareStrcmp(const char * s1, const char * s2);
66
67 /** Same as NumericAwareStrcmp(), but case-insensitive.
68 * @param s1 The first of the two strings to compare using the case-insensitive number-aware comparison algorithm.
69 * @param s2 The second of the two strings to compare using the case-insensitive number-aware comparison algorithm.
70 * @returns 0 if the two strings are equal, >0 if (s2) is the "later" string, or <0 if (s1) is the "later" string.
71 */
72 int NumericAwareStrcasecmp(const char * s1, const char * s2);
73
74 /** Wrapper for strcasecmp(), which isn't always named the same on all OS's
75 * @param s1 The first of the two strings to compare using the case-insensitive comparison algorithm.
76 * @param s2 The second of the two strings to compare using the case-insensitive comparison algorithm.
77 * @returns 0 if the two strings are equal, >0 if (s2) is the "later" string, or <0 if (s1) is the "later" string.
78 */
79 inline int Strcasecmp(const char * s1, const char * s2)
80 {
81 #ifdef WIN32
82 return _stricmp(s1, s2);
83 #else
84 return strcasecmp(s1, s2);
85 #endif
86 }
87
88 /** Wrapper for strncasecmp(), which isn't always named the same on all OS's
89 * @param s1 The first of the two strings to compare using the case-insensitive comparison algorithm.
90 * @param s2 The second of the two strings to compare using the case-insensitive comparison algorithm.
91 * @param n The maximum number of bytes to compare (any bytes after the (nth) byte in the strings will be ignored)
92 * @returns 0 if the two strings are equal, >0 if (s2) is the "later" string, or <0 if (s1) is the "later" string.
93 */
94 inline int Strncasecmp(const char * s1, const char * s2, size_t n)
95 {
96 #ifdef WIN32
97 return _strnicmp(s1, s2, n);
98 #else
99 return strncasecmp(s1, s2, n);
100 #endif
101 }
102
103 /** Wrapper for strcasestr(), which isn't always present on all OS's.
104 * @param haystack The string to search in
105 * @param needle The string to search for
106 * @returns a pointer to (needle), if it exists inside (haystack), or NULL if it doesn't.
107 * @note that the search is case-insensitive.
108 */
109 const char * Strcasestr(const char * haystack, const char * needle);
110
111 /** Extended wrapper for strcasestr(), which isn't always named the same on all OS's
112 * @param haystack The string to search in
113 * @param haystackLen The number of text-bytes that (haystack) is pointing to (i.e. strlen(haystack))
114 * @param needle The string to search for
115 * @param needleLen The number of text-bytes that (needle) is pointing to (i.e. strlen(needle))
116 * @param searchBackwards If set true, the last instance of (needle) in the (haystack) will be returned rather than the first.
117 * @returns a pointer to a (needle), if one exists inside (haystack), or NULL if it doesn't.
118 * @note that the search is case-insensitive.
119 */
120 const char * StrcasestrEx(const char * haystack, uint32 haystackLen, const char * needle, uint32 needleLen, bool searchBackwards);
121
122 /** An arbitrary-length character-string class. Represents a dynamically resizable, NUL-terminated ASCII string.
123 * This class can be used to hold UTF8-encoded strings as well, but because the code in this class is not
124 * UTF8-aware, certain operations (such as Reverse() and ToLowerCase()) may not do the right thing when used in
125 * conjunction with non-ASCII UTF8 data.
126 */
127 class String MUSCLE_FINAL_CLASS : public PseudoFlattenable
128 {
129 public:
130 /** Constructor.
131 * @param str If non-NULL, the initial value for this String.
132 * @param maxLen The maximum number of characters to place into
133 * this String (not including the NUL terminator byte).
134 * Default is unlimited (i.e. scan the entire string no matter how long it is)
135 */
136 String(const char * str = NULL, uint32 maxLen = MUSCLE_NO_LIMIT) : _bufferLen(sizeof(_strData._smallBuffer)), _length(0)
137 {
138 MUSCLE_INCREMENT_STRING_OP_COUNT(str?STRING_OP_CSTR_CTOR:STRING_OP_DEFAULT_CTOR);
139 ClearSmallBuffer();
140 if (str) (void) SetCstr(str, maxLen);
141 }
142
143 /** @copydoc DoxyTemplate::DoxyTemplate(const DoxyTemplate &) */
144 String(const String & rhs) : _bufferLen(sizeof(_strData._smallBuffer)), _length(0)
145 {
146 MUSCLE_INCREMENT_STRING_OP_COUNT(STRING_OP_COPY_CTOR);
147 ClearSmallBuffer(); (void) SetFromString(rhs);
148 }
149
150 /** This constructor sets this String to be a substring of the specified String.
151 * @param str String to become a copy of.
152 * @param beginIndex Index of the first character in (str) to include.
153 * @param endIndex Index after the last character in (str) to include.
154 * Defaults to a very large number, so that by default the entire remainder of the string is included.
155 */
156 String(const String & str, uint32 beginIndex, uint32 endIndex=MUSCLE_NO_LIMIT) : _bufferLen(sizeof(_strData._smallBuffer)), _length(0)
157 {
158 MUSCLE_INCREMENT_STRING_OP_COUNT(STRING_OP_PARTIAL_COPY_CTOR);
159 ClearSmallBuffer(); (void) SetFromString(str, beginIndex, endIndex);
160 }
161
162 #ifdef __APPLE__
163 /** Special MACOS/X-only convenience constructor that sets our state from a UTF8 Core Foundation String
164 * @param cfStringRef A CFStringRef that we will get our string value from
165 */
166 String(const CFStringRef & cfStringRef) : _bufferLen(sizeof(_strData._smallBuffer)), _length(0) {(void) SetFromCFStringRef(cfStringRef);}
167 #endif
168
169 /** Destructor. */
170 ~String()
171 {
172 MUSCLE_INCREMENT_STRING_OP_COUNT(STRING_OP_DTOR);
173 if (IsArrayDynamicallyAllocated()) muscleFree(_strData._bigBuffer);
174 }
175
176 /** Assignment Operator.
177 * @param val Pointer to the C-style string to copy from. If NULL, this string will become an empty string.
178 */
179 String & operator = (const char * val)
180 {
181 MUSCLE_INCREMENT_STRING_OP_COUNT(STRING_OP_SET_FROM_CSTR);
182 (void) SetCstr(val); return *this;
183 }
184
185 /** @copydoc DoxyTemplate::operator=(const DoxyTemplate &) */
186 String & operator = (const String & rhs)
187 {
188 MUSCLE_INCREMENT_STRING_OP_COUNT(STRING_OP_SET_FROM_STRING);
189 (void) SetFromString(rhs); return *this;
190 }
191
192 /** Append Operator.
193 * @param rhs A string to append to this string.
194 */
195 String & operator += (const String & rhs);
196
197 /** Append Operator.
198 * @param rhs A string to append to this string. If NULL, this operation is a no-op.
199 */
200 String & operator += (const char * rhs);
201
202 /** Append Operator.
203 * @param ch A character to append to this string.
204 */
205 String & operator += (char ch)
206 {
207 if (EnsureBufferSize(Length()+2, true, false) == B_NO_ERROR)
208 {
209 GetBuffer()[_length++] = ch;
210 WriteNULTerminatorByte();
211 }
212 return *this;
213 }
214
215 /** Remove Operator.
216 * @param rhs A substring to remove from this string; the
217 * last instance of the substring will be cut out.
218 * If (rhs) is not found, there is no effect.
219 */
220 String & operator -= (const String & rhs);
221
222 /** Remove Operator.
223 * @param rhs A substring to remove from this string; the
224 * last instance of the substring will be cut out.
225 * If (rhs) is not found, there is no effect.
226 */
227 String & operator -= (const char * rhs);
228
229 /** Remove Operator.
230 * @param ch A character to remove from this string; the last
231 * instance of this char will be cut out. If (ch) is
232 * not found, there is no effect.
233 */
234 String & operator -= (const char ch);
235
236 /** Append 'Stream' Operator.
237 * @param rhs A String to append to this string.
238 * @return a non const String refrence to 'this' so you can chain appends.
239 */
240 String & operator << (const String & rhs) {return (*this += rhs);}
241
242 /** Append 'Stream' Operator.
243 * @param rhs A const char* to append to this string.
244 * @return a non const String refrence to 'this' so you can chain appends.
245 */
246 String & operator << (const char * rhs) {return (*this += rhs);}
247
248 /** Append 'Stream' Operator.
249 * @param rhs An int to append to this string.
250 * @return a non const String refrence to 'this' so you can chain appends.
251 */
252 String & operator << (int rhs);
253
254 /** Append 'Stream' Operator.
255 * @param rhs A float to append to this string. Formatting is set at 2 decimals of precision.
256 * @return a non const String refrence to 'this' so you can chain appends.
257 */
258 String & operator << (float rhs);
259
260 /** Append 'Stream' Operator.
261 * @param rhs A bool to append to this string. Converts to 'true' and 'false' strings appropriately.
262 * @return a non const String refrence to 'this' so you can chain appends.
263 */
264 String & operator << (bool rhs);
265
266 /** Comparison Operator. Returns true iff the two strings contain the same sequence of characters (as determined by memcmp()).
267 * @param rhs A string to compare ourself with
268 */
269 bool operator == (const String & rhs) const {return ((this == &rhs)||((Length() == rhs.Length())&&(memcmp(Cstr(), rhs.Cstr(), Length()) == 0)));}
270
271 /** Comparison Operator. Returns true if the two strings are equal (as determined by strcmp())
272 * @param rhs Pointer to a C string to compare with. NULL pointers are considered a synonym for "".
273 */
274 bool operator == (const char * rhs) const {return (strcmp(Cstr(), rhs?rhs:"") == 0);}
275
276 /** Comparison Operator. Returns true if the two strings are not equal (as determined by memcmp())
277 * @param rhs A string to compare ourself with
278 */
279 bool operator != (const String & rhs) const {return !(*this == rhs);}
280
281 /** Comparison Operator. Returns true if the two strings are not equal (as determined by strcmp())
282 * @param rhs Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
283 */
284 bool operator != (const char * rhs) const {return (strcmp(Cstr(), rhs?rhs:"") != 0);}
285
286 /** Comparison Operator. Returns true if this string comes before (rhs) lexically (as determined by strcmp()).
287 * @param rhs A string to compare ourself with
288 */
289 bool operator < (const String & rhs) const {return (this == &rhs) ? false : (strcmp(Cstr(), rhs.Cstr()) < 0);}
290
291 /** Comparison Operator. Returns true if this string comes before (rhs) lexically (as determined by strcmp()).
292 * @param rhs Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
293 */
294 bool operator < (const char * rhs) const {return (strcmp(Cstr(), rhs?rhs:"") < 0);}
295
296 /** Comparison Operator. Returns true if this string comes after (rhs) lexically (as determined by strcmp()).
297 * @param rhs A string to compare ourself with
298 */
299 bool operator > (const String & rhs) const {return (this == &rhs) ? false : (strcmp(Cstr(), rhs.Cstr()) > 0);}
300
301 /** Comparison Operator. Returns true if this string comes after (rhs) lexically.
302 * @param rhs Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
303 */
304 bool operator > (const char * rhs) const {return (strcmp(Cstr(), rhs?rhs:"") > 0);}
305
306 /** Comparison Operator. Returns true if the two strings are equal, or this string comes before (rhs) lexically (as determined by strcmp()).
307 * @param rhs A string to compare ourself with
308 */
309 bool operator <= (const String & rhs) const {return (this == &rhs) ? true : (strcmp(Cstr(), rhs.Cstr()) <= 0);}
310
311 /** Comparison Operator. Returns true if the two strings are equal, or this string comes before (rhs) lexically (as determined by strcmp()).
312 * @param rhs Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
313 */
314 bool operator <= (const char * rhs) const {return (strcmp(Cstr(), rhs?rhs:"") <= 0);}
315
316 /** Comparison Operator. Returns true if the two strings are equal, or this string comes after (rhs) lexically (as determined by strcmp()).
317 * @param rhs A string to compare ourself with
318 */
319 bool operator >= (const String & rhs) const {return (this == &rhs) ? true : (strcmp(Cstr(), rhs.Cstr()) >= 0);}
320
321 /** Comparison Operator. Returns true if the two strings are equal, or this string comes after (rhs) lexically (as determined by strcmp()).
322 * @param rhs Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
323 */
324 bool operator >= (const char * rhs) const {return (strcmp(Cstr(), rhs?rhs:"") >= 0);}
325
326 /** Array Operator. Used to get easy access to the characters that make up this string.
327 * @param index Index of the character to return. Be sure to only use valid indices!
328 */
329 char operator [] (uint32 index) const {VerifyIndex(index); return Cstr()[index];}
330
331 /** Array Operator. Used to get easy access to the characters that make up this string.
332 * @param index Index of the character to set. Be sure to only use valid indices!
333 */
334 char & operator [] (uint32 index) {VerifyIndex(index); return GetBuffer()[index];}
335
336 /** Adds a space to the end of this string. */
337 void operator ++ (int) {(*this) += ' ';}
338
339 /** Remove the last character from the end of this string. It's a no-op if the string is already empty. */
340 void operator -- (int) {TruncateChars(1);}
341
342 /** Returns the character at the (index)'th position in the string.
343 * @param index A value between 0 and (Length()-1), inclusive.
344 * @return A character value.
345 */
346 char CharAt(uint32 index) const {return operator[](index);}
347
348 /** Compares this string to another string using strcmp()
349 * @param rhs A string to compare ourself with
350 * @returns 0 if the two strings are equal, a negative value if this string is "first", or a positive value of (rhs) is "first"
351 */
352 int CompareTo(const String & rhs) const {return strcmp(Cstr(), rhs.Cstr());}
353
354 /** Compares this string to a C string using strcmp()
355 * @param rhs Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
356 * @returns 0 if the two strings are equal, a negative value if this string is "first", or a positive value of (rhs) is "first"
357 */
358 int CompareTo(const char * rhs) const {return strcmp(Cstr(), rhs?rhs:"");}
359
360 /** Compares this string to another string using NumericAwareStrcmp()
361 * @param rhs A string to compare ourself with
362 * @returns 0 if the two strings are equal, a negative value if this string is "first", or a positive value of (rhs) is "first"
363 */
364 int NumericAwareCompareTo(const String & rhs) const {return NumericAwareStrcmp(Cstr(), rhs.Cstr());}
365
366 /** Compares this string to a C string using NumericAwareStrcmp()
367 * @param rhs Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
368 * @returns 0 if the two strings are equal, a negative value if this string is "first", or a positive value of (rhs) is "first"
369 */
370 int NumericAwareCompareTo(const char * rhs) const {return NumericAwareStrcmp(Cstr(), rhs?rhs:"");}
371
372 /** Returns a read-only C-style pointer to our held character string. */
373 const char * Cstr() const {return IsArrayDynamicallyAllocated() ? _strData._bigBuffer : _strData._smallBuffer;}
374
375 /** Convenience synonym for Cstr(). */
376 const char * operator()() const {return Cstr();}
377
378 /** Clears this string so that it contains no characters. Equivalent to setting this string to "". */
379 void Clear() {_length = 0; WriteNULTerminatorByte();}
380
381 /** Similar to Clear(), except this version also frees up any dynamically allocated character array we may have cached. */
382 void ClearAndFlush();
383
384 /** Shrinks our internally allocated buffer down so that it is just big enough to hold the current string (plus numExtraBytes)
385 * @param numExtraBytes an additional number of bytes that the buffer should have room for. Defaults to zero.
386 * @returns B_NO_ERROR on success, or an error code on failure (although I don't know why this method would ever fail).
387 */
388 status_t ShrinkToFit(uint32 numExtraBytes = 0) {return EnsureBufferSize(FlattenedSize()+numExtraBytes, true, true);}
389
390 /** Sets our state from the given C-style string.
391 * @param str The new string to copy from. If maxLen is negative, this may be NULL.
392 * @param maxLen If set, the maximum number of characters to copy (not including the NUL
393 * terminator byte). By default, all characters up to the first encountered
394 * NUL terminator byte will be copied out of (str).
395 */
396 status_t SetCstr(const char * str, uint32 maxLen = MUSCLE_NO_LIMIT);
397
398 /** Sets our state from the given String. This is similar to the copy constructor, except
399 * that it allows you to optionally specify a maximum length, and it allows you to detect
400 * out-of-memory errors.
401 * @param str The new string to copy from.
402 * @param beginIndex Index of the first character in (str) to include.
403 * Defaults to zero, so that by default the entire string is included.
404 * @param endIndex Index after the last character in (str) to include.
405 * Defaults to a very large number, so that by default the entire remainder of the string is included.
406 * @returns B_NO_ERROR on success, or B_OUT_OF_MEMORY on failure.
407 */
408 status_t SetFromString(const String & str, uint32 beginIndex = 0, uint32 endIndex = MUSCLE_NO_LIMIT);
409
410 #ifdef __APPLE__
411 /** MACOS/X-only convenience method: Sets our string equal to the string pointed to by (cfStringRef).
412 * @param cfStringRef A CFStringRef that we will get our string value from. May be NULL (in which case we'll be set to an empty string)
413 * @returns B_NO_ERROR on success, or an error code on failure.
414 */
415 status_t SetFromCFStringRef(const CFStringRef & cfStringRef);
416
417 /** MACOS/X-only convenience method: Returns a CFStringRef containing the same string that we have.
418 * It becomes the caller's responsibility to CFRelease() the CFStringRef when he is done with it.
419 * May return a NULL CFStringRef on failure (e.g. out of memory)
420 */
421 CFStringRef ToCFStringRef() const;
422 #endif
423
424 /** Returns true iff this string is a zero-length string. */
425 bool IsEmpty() const {return (_length == 0);}
426
427 /** Returns true iff this string starts with a number.
428 * @param allowNegativeValues if true, negative values will be considered as numbers also. Defaults to true.
429 */
430 bool StartsWithNumber(bool allowNegativeValues = true) const {const char * s = Cstr(); return ((isdigit(*s))||((allowNegativeValues)&&(s[0]=='-')&&(isdigit(s[1]))));}
431
432 /** Returns true iff this string is not a zero-length string. */
433 bool HasChars() const {return (_length > 0);}
434
435 /** Returns true iff this string starts with (prefix)
436 * @param c a character to check for at the end of this String.
437 */
438 bool EndsWith(char c) const {return (_length > 0)&&(Cstr()[_length-1] == c);}
439
440 /** Returns true iff this string ends with (suffix)
441 * @param suffix a String to check for at the end of this String.
442 */
443 bool EndsWith(const String & suffix) const {return ((Length() >= suffix.Length())&&(strcmp(Cstr()+(Length()-suffix.Length()), suffix.Cstr()) == 0));}
444
445 /** Returns true iff this string ends with (suffix)
446 * @param suffix a String to check for at the end of this String. NULL pointers are treated as a synonym for "".
447 */
448 bool EndsWith(const char * suffix) const
449 {
450 if (suffix == NULL) suffix = "";
451 const uint32 suffixLen = (uint32) strlen(suffix);
452 return (Length() < suffixLen) ? false : (strcmp(Cstr()+(Length()-suffixLen), suffix) == 0);
453 }
454
455 /** Returns true iff this string is equal to (string), as determined by strcmp().
456 * @param str a String to compare this String with.
457 */
458 bool Equals(const String & str) const {return (*this == str);}
459
460 /** Returns true iff this string is equal to (str), as determined by strcmp().
461 * @param str Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
462 */
463 bool Equals(const char * str) const {return (*this == str);}
464
465 /** Returns true iff this string contains a single character (c).
466 * @param c a character to compare this String with.
467 */
468 bool Equals(char c) const {return (_length == 1)&&(Cstr()[0] == c);}
469
470 /** Returns the first index of (ch) in this string starting at or after (fromIndex), or -1 if not found.
471 * @param ch A character to look for in this string.
472 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
473 */
474 int IndexOf(char ch, uint32 fromIndex = 0) const
475 {
476 const char * temp = (fromIndex < Length()) ? strchr(Cstr()+fromIndex, ch) : NULL;
477 return temp ? (int)(temp - Cstr()) : -1;
478 }
479
480 /** Returns true iff (ch) is contained in this string.
481 * @param ch A character to look for in this string.
482 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
483 */
484 bool Contains(char ch, uint32 fromIndex = 0) const {return (IndexOf(ch, fromIndex) >= 0);}
485
486 /** Returns true iff substring (str) is in this string starting at or after (fromIndex).
487 * @param str A String to look for in this string.
488 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
489 */
490 bool Contains(const String & str, uint32 fromIndex = 0) const {return (IndexOf(str, fromIndex) >=0);}
491
492 /** Returns true iff the substring (str) is in this string starting at or after (fromIndex).
493 * @param str Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
494 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
495 */
496 bool Contains(const char * str, uint32 fromIndex = 0) const {return (IndexOf(str, fromIndex) >= 0);}
497
498 /** Returns the first index of substring (str) in this string starting at or after (fromIndex), or -1 if not found.
499 * @param str A String to look for in this string.
500 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
501 */
502 int IndexOf(const String & str, uint32 fromIndex = 0) const
503 {
504 const char * temp = (fromIndex < Length()) ? strstr(Cstr()+fromIndex, str()) : NULL;
505 return temp ? (int)(temp - Cstr()) : -1;
506 }
507
508 /** Returns the first index of substring (str) in this string starting at or after (fromIndex), or -1 if not found.
509 * @param str Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
510 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
511 */
512 int IndexOf(const char * str, uint32 fromIndex = 0) const
513 {
514 const char * temp = (fromIndex < Length()) ? strstr(Cstr()+fromIndex, str?str:"") : NULL;
515 return temp ? (int)(temp - Cstr()) : -1;
516 }
517
518 /** Returns the last index of (ch) in this string starting at or after (fromIndex), or -1 if not found.
519 * @param ch A character to look for in this string.
520 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
521 */
522 int LastIndexOf(char ch, uint32 fromIndex = 0) const
523 {
524 if (fromIndex < Length())
525 {
526 const char * s = Cstr()+fromIndex;
527 const char * p = Cstr()+Length();
528 while(--p >= s) if (*p == ch) return (int)(p-Cstr());
529 }
530 return -1;
531 }
532
533 /** Returns the last index of substring (str) in this string
534 * @param str A String to look for in this string.
535 */
536 int LastIndexOf(const String & str) const {return (str.Length() <= Length()) ? LastIndexOf(str, Length()-str.Length()) : -1;}
537
538 /** Returns the last index of substring (str) in this string
539 * @param str Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
540 */
541 int LastIndexOf(const char * str) const
542 {
543 if (str == NULL) str = "";
544 uint32 strLen = (uint32) strlen(str);
545 return (strLen <= Length()) ? LastIndexOf(str, Length()-strLen) : -1;
546 }
547
548 /** Returns the last index of substring (str) in this string starting at or after (fromIndex), or -1 if not found.
549 * @param str A String to look for in this string.
550 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
551 */
552 int LastIndexOf(const String & str, uint32 fromIndex) const;
553
554 /** Returns the last index of substring (str) in this string starting at or after (fromIndex), or -1 if not found.
555 * @param str Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
556 * @param fromIndex Index of the first character to start searching at in this String. Defaults to zero (i.e. start from the first character)
557 */
558 int LastIndexOf(const char * str, uint32 fromIndex) const;
559
560 /** Returns the number of characters in the string (not including the terminating NUL byte) */
561 uint32 Length() const {return _length;}
562
563 /** Returns the number of bytes of storage we have allocated. Note that this value will often
564 * be greater than the value returned by Length(), since we allocate extra bytes to minimize
565 * the number of reallocations that must be done as data is being added to a String.
566 */
567 uint32 GetNumAllocatedBytes() const {return _bufferLen;}
568
569 /** Returns the number of instances of (c) in this string.
570 * @param ch The character to count the number of instances of in this String.
571 */
572 uint32 GetNumInstancesOf(char ch) const;
573
574 /** Returns the number of instances of (substring) in this string.
575 * @param substring String to count the number of instances of in this String.
576 */
577 uint32 GetNumInstancesOf(const String & substring) const;
578
579 /** Returns the number of instances of (substring) in this string.
580 * @param substring C string to count the number of instances of in this String.
581 */
582 uint32 GetNumInstancesOf(const char * substring) const;
583
584 /** Returns the Levenshtein distance between this string and (otherString).
585 * @param otherString a String to calculate our Levenshtein distance to.
586 * @param maxResult The maximum score to return. (Setting a maximum score to return can
587 * speed up execution time, as it allows this method to return early
588 * as soon as the maximum score has been reached). Defaults to MUSCLE_NO_LIMIT.
589 * @returns The Levenshtein distance -- i.e. the number of single-character insertions, deletions,
590 * or character replacements it would take to convert one string into the other.
591 */
592 uint32 GetDistanceTo(const String & otherString, uint32 maxResult = MUSCLE_NO_LIMIT) const;
593
594 /** Returns the Levenshtein distance between this string and (otherString).
595 * @param otherString a C string to calculate our Levenshtein distance to. NULL pointers are considered a synonym for "".
596 * @param maxResult The maximum score to return. (Setting a maximum score to return can
597 * speed up execution time, as it allows this method to return early
598 * as soon as the maximum score has been reached). Defaults to MUSCLE_NO_LIMIT.
599 * @returns The Levenshtein distance -- i.e. the number of single-character insertions, deletions,
600 * or character replacements it would take to convert one string into the other.
601 */
602 uint32 GetDistanceTo(const char * otherString, uint32 maxResult = MUSCLE_NO_LIMIT) const;
603
604 /** Returns true iff this string starts with (c)
605 * @param c The character to see if this string starts with or not
606 */
607 bool StartsWith(char c) const {return (*Cstr() == c);}
608
609 /** Returns true iff this string starts with (prefix)
610 * @param prefix The prefix to see whether this string starts with or not
611 */
612 bool StartsWith(const String & prefix) const {return ((Length() >= prefix.Length())&&(strncmp(Cstr(), prefix(), prefix.Length()) == 0));}
613
614 /** Returns true iff this string starts with (prefix)
615 * @param prefix Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
616 */
617 bool StartsWith(const char * prefix) const
618 {
619 if (prefix == NULL) prefix = "";
620 uint32 prefixLen = (uint32) strlen(prefix);
621 return (Length() < prefixLen) ? false : (strncmp(Cstr(), prefix, prefixLen) == 0);
622 }
623
624 /** Returns a string that consists of (count) copies of (str), followed by this string.
625 * @param str The string to prepend
626 * @param count How many instances of (str) to prepend. Defaults to 1.
627 */
628 String Prepend(const String & str, uint32 count = 1) const;
629
630 /** Returns a string that consists of (count) copies of (str), followed by this string.
631 * @param str Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
632 * @param count How many instances of (str) should be prepended to this string. Defaults to 1.
633 */
634 String Prepend(const char * str, uint32 count = 1) const;
635
636 /** Returns a string that consists of (count) copies of (c), followed by this string.
637 * @param c The character to prepend
638 * @param count How many instances of (c) to prepend. Defaults to 1.
639 */
640 String Prepend(char c, uint32 count = 1) const {const char cc[2] = {c, '\0'}; return Prepend(cc, count);}
641
642 /** Similar to Prepend(), but this version will insert separator string between our current content and the prepended string, if necessary.
643 * @param str A string to prepended to the end of this string.
644 * @param sep Pointer to the string used to separate words. Defaults to " "
645 * @returns a reference to this object, which will have had the specified string prepended, with an inserted (sep) infix if necessary.
646 */
647 String PrependWord(const String & str, const char * sep = " ") const {return str.AppendWord(*this, sep);}
648
649 /** Returns a string that consists of this string followed by (count) copies of (str).
650 * @param str A string to append to the end of this string.
651 * @param count How many copies of (str) to append. Defaults to 1.
652 */
653 String Append(const String & str, uint32 count = 1) const;
654
655 /** Returns a string that consists of this string followed by (count) copies of (str).
656 * @param str Pointer to a C string to compare to. NULL pointers are considered a synonym for "".
657 * @param count How many instances of (str) should be appended to this string. Defaults to 1.
658 */
659 String Append(const char * str, uint32 count = 1) const;
660
661 /** Returns a string that consists of this string followed by (count) copies of (c).
662 * @param c The character to append
663 * @param count How many instances of (c) to append. Defaults to 1.
664 */
665 String Append(char c, uint32 count = 1) const {const char cc[2] = {c, '\0'}; return Append(cc, count);}
666
667 /** Similar to the += operator, but this version will insert a separator between our current content and the appended string, if necessary.
668 * @param str Pointer to a C string to return appended to this string. NULL pointers are considered a synonym for "".
669 * @param sep Pointer to the string used to separate words. Defaults to " "
670 * @returns a reference to this object, which will have had the specified string appended, with an inserted (sep) infix if necessary.
671 */
672 String AppendWord(const char * str, const char * sep = " ") const;
673
674 /** Similar to the += operator, but this version will insert a separator between our current content and the appended string, if necessary.
675 * @param str A string to append to the end of this string.
676 * @param sep Pointer to the string used to separate words. Defaults to " "
677 * @returns a reference to this object, which will have had the specified string appended, with an inserted (sep) infix if necessary.
678 */
679 String AppendWord(const String & str, const char * sep = " ") const;
680
681 /** Returns a string that is like this string, but padded out to the specified minimum length with (padChar).
682 * @param minLength Minimum length that the returned string should be.
683 * @param padOnRight If true, (padChar)s will be added to the right; if false (the default), they will be added on the left.
684 * @param padChar The character to pad out the string with. Defaults to ' '.
685 * @returns the new, padded String.
686 */
687 String Pad(uint32 minLength, bool padOnRight = false, char padChar = ' ') const;
688
689 /** Returns a string that is the same as this one, except that the beginning of each line in the string has (numIndentChars)
690 * instances of (indentChar) prepended to it.
691 * @param numIndentChars How many indent characters to prepend to each line
692 * @param indentChar The character to use to make the indentations. Defaults to ' '.
693 * @returns the indented string.
694 */
695 String Indent(uint32 numIndentChars, char indentChar = ' ') const;
696
697 /** Returns a string that consists of only the last part of this string, starting with index (beginIndex). Does not modify the string it is called on.
698 * @param beginIndex the index of the first character to include in the returned substring
699 */
700 String Substring(uint32 beginIndex) const {return String(*this, beginIndex);}
701
702 /** Returns a string that consists of only the characters in this string from range (beginIndex) to (endIndex-1). Does not modify the string it is called on.
703 * @param beginIndex the index of the first character to include in the returned substring
704 * @param endIndex the index after the final character to include in the returned substring (if set to MUSCLE_NO_LIMIT, or any other too-large-value,
705 * returned substring will include thi entire string starting with (beginIndex)
706 */
707 String Substring(uint32 beginIndex, uint32 endIndex) const {return String(*this, beginIndex, endIndex);}
708
709 /** Returns a string that consists of only the last part of this string, starting with the first character after the last instance of (markerString).
710 * If (markerString) is not found in the string, then this entire String is returned.
711 * For example, String("this is a test").Substring("is a") returns " test".
712 * Does not modify the string it is called on.
713 * @param markerString the substring to return the suffix string that follows
714 */
715 String Substring(const String & markerString) const
716 {
717 int idx = LastIndexOf(markerString);
718 return (idx >= 0) ? String(*this, idx+markerString.Length()) : *this;
719 }
720
721 /** @copydoc String::Substring(const String &) const */
722 String Substring(const char * markerString) const
723 {
724 int idx = LastIndexOf(markerString);
725 return (idx >= 0) ? String(*this, idx+(int)strlen(markerString)) : *this; // if (idx >= 0), then we know markerString is non-NULL
726 }
727
728 /** Returns a string that consists of only the characters in the string from range (beginIndex) until the character just before
729 * the first character in (markerString). If (markerString) is not found, then the entire substring starting at (beginIndex) is returned.
730 * For example, String("this is a test").Substring(1, "is a") returns "his ".
731 * Does not modify the string it is called on.
732 * @param beginIndex the first character in our string to search at
733 * @param markerString the substring to return the suffix string that follows
734 */
735 String Substring(uint32 beginIndex, const String & markerString) const {return String(*this, beginIndex, (uint32) IndexOf(markerString, beginIndex));}
736
737 /** @copydoc String::Substring(uint32, const String &) const */
738 String Substring(uint32 beginIndex, const char * markerString) const {return String(*this, beginIndex, (uint32) IndexOf(markerString, beginIndex));}
739
740 /** Returns an all lower-case version of this string. Does not modify the string it is called on. */
741 String ToLowerCase() const;
742
743 /** Returns an all upper-case version of this string. Does not modify the string it is called on. */
744 String ToUpperCase() const;
745
746 /** Returns a version of this string where All Words Are In Lower Case Except For The First Letter. */
747 String ToMixedCase() const;
748
749 /** Returns an version of this string that has all leading and trailing whitespace removed. Does not modify the string it is called on. */
750 String Trim() const;
751
752 /** Swaps the state of this string with (swapWithMe). Very efficient since little or no data copying is required.
753 * @param swapWithMe the String to swap contents with
754 */
755 inline void SwapContents(String & swapWithMe)
756 {
757 muscleSwap(_strData, swapWithMe._strData);
758 muscleSwap(_bufferLen, swapWithMe._bufferLen);
759 muscleSwap(_length, swapWithMe._length); // always do this
760 }
761
762 #ifndef MUSCLE_AVOID_CPLUSPLUS11
763 /** @copydoc DoxyTemplate::DoxyTemplate(DoxyTemplate &&) */
764 String(String && rhs) : _bufferLen(0), _length(0)
765 {
766 MUSCLE_INCREMENT_STRING_OP_COUNT(STRING_OP_MOVE_CTOR);
767 ClearSmallBuffer();
768 SwapContents(rhs);
769 }
770
771 /** @copydoc DoxyTemplate::DoxyTemplate(DoxyTemplate &&) */
772 String & operator =(String && rhs)
773 {
774 MUSCLE_INCREMENT_STRING_OP_COUNT(STRING_OP_MOVE_FROM_STRING);
775 SwapContents(rhs);
776 return *this;
777 }
778 #endif
779
780 /** Like CompareTo(), but case insensitive.
781 * @param s the String to compare this string to
782 * @returns 0 if the two strings are equal, a negative value if this string is "first", or a positive value of (rhs) is "first"
783 */
784 int CompareToIgnoreCase(const String & s) const {return Strcasecmp(Cstr(), s());}
785
786 /** Like CompareTo(), but case insensitive.
787 * @param s the String to compare this string to
788 * @returns 0 if the two strings are equal, a negative value if this string is "first", or a positive value of (rhs) is "first"
789 */
790 int CompareToIgnoreCase(const char * s) const {return Strcasecmp(Cstr(), s?s:"");}
791
792 /** Like NumericAwareCompareTo(), but case insensitive.
793 * @param s the String to compare this string to
794 * @returns 0 if the two strings are equal, a negative value if this string is "first", or a positive value of (rhs) is "first"
795 */
796 int NumericAwareCompareToIgnoreCase(const String & s) const {return NumericAwareStrcasecmp(Cstr(), s());}
797
798 /** Like NumericAwareCompareTo(), but case insensitive.
799 * @param s the String to compare this string to
800 * @returns 0 if the two strings are equal, a negative value if this string is "first", or a positive value of (rhs) is "first"
801 */
802 int NumericAwareCompareToIgnoreCase(const char * s) const {return NumericAwareStrcasecmp(Cstr(), s?s:"");}
803
804 /** Like EndsWith(), but case insensitive.
805 * @param c a character to check for at the end of this String.
806 */
807 bool EndsWithIgnoreCase(char c) const {return (HasChars())&&(tolower(Cstr()[_length-1]) == tolower(c));}
808
809 /** Like EndsWith(), but case insensitive.
810 * @param s a suffix to check for at the end of this String.
811 */
812 bool EndsWithIgnoreCase(const String & s) const {return ((Length() >= s.Length())&&(Strcasecmp(Cstr()+(Length()-s.Length()), s()) == 0));}
813
814 /** Like EndsWith(), but case insensitive.
815 * @param s a suffix to check for at the end of this String.
816 */
817 bool EndsWithIgnoreCase(const char * s) const;
818
819 /** Like Equals(), but case insensitive.
820 * @param s a string to check for (case-insensitive) equality with this String
821 */
822 bool EqualsIgnoreCase(const String & s) const {return ((this==&s)||((Length()==s.Length())&&(Strcasecmp(Cstr(), s()) == 0)));}
823
824 /** Like Equals(), but case insensitive.
825 * @param s a string to check for (case-insensitive) equality with this String
826 */
827 bool EqualsIgnoreCase(const char * s) const {if (s==NULL) s=""; return ((Cstr()==s)||(Strcasecmp(Cstr(), s) == 0));}
828
829 /** Like Equals(), but case insensitive.
830 * @param c a character to check for (case-insensitive) equality with this String.
831 */
832 bool EqualsIgnoreCase(char c) const {return (_length==1)&&(tolower(Cstr()[0])==tolower(c));}
833
834 /** Like Contains(), but case insensitive.
835 * @param s A String to look for in this string.
836 * @param f Index of the first character to start searching at in this String. Defaults to zero.
837 */
838 bool ContainsIgnoreCase(const String & s, uint32 f = 0) const {return (IndexOfIgnoreCase(s, f) >= 0);}
839
840 /** Like Contains(), but case insensitive.
841 * @param s A String to look for in this string.
842 * @param f Index of the first character to start searching at in this String. Defaults to zero.
843 */
844 bool ContainsIgnoreCase(const char * s, uint32 f = 0) const {return (IndexOfIgnoreCase(s, f) >= 0);}
845
846 /** Like Contains(), but case insensitive.
847 * @param ch A character to look for in this string.
848 * @param f Index of the first character to start searching at in this String. Defaults to zero.
849 */
850 bool ContainsIgnoreCase(char ch, uint32 f = 0) const {return (IndexOfIgnoreCase(ch, f) >= 0);}
851
852 /** Like IndexOf(), but case insensitive.
853 * @param s A String to look for in this string.
854 * @param f Index of the first character to start searching at in this String.
855 */
856 int IndexOfIgnoreCase(const String & s, uint32 f = 0) const;
857
858 /** Like IndexOf(), but case insensitive.
859 * @param s A string to look for in this string.
860 * @param f Index of the first character to start searching at in this String.
861 */
862 int IndexOfIgnoreCase(const char * s, uint32 f = 0) const;
863
864 /** Like IndexOf(), but case insensitive.
865 * @param ch A character to look for in this string.
866 * @param f Index of the first character to start searching at in this String. Defaults to zero.
867 */
868 int IndexOfIgnoreCase(char ch, uint32 f = 0) const;
869
870 /** Like LastIndexOf(), but case insensitive.
871 * @param s A String to look for in this string.
872 * @param f Index of the first character to start searching at in this String. Defaults to zero.
873 */
874 int LastIndexOfIgnoreCase(const String & s, uint32 f = 0) const;
875
876 /** Like LastIndexOf(), but case insensitive.
877 * @param s A string to look for in this string.
878 * @param f Index of the first character to start searching at in this String. Defaults to zero.
879 */
880 int LastIndexOfIgnoreCase(const char * s, uint32 f = 0) const;
881
882 /** Like LastIndexOf(), but case insensitive.
883 * @param ch A character to look for in this string.
884 * @param f Index of the first character to start searching at in this String. Defaults to zero.
885 */
886 int LastIndexOfIgnoreCase(char ch, uint32 f = 0) const;
887
888 /** Like StartsWith(), but case insensitive.
889 * @param c The character to see if this string starts with or not
890 */
891 bool StartsWithIgnoreCase(char c) const {return (_length > 0)&&(tolower(Cstr()[0]) == tolower(c));}
892
893 /** Like StartsWith(), but case insensitive.
894 * @param s The prefix to see whether this string starts with or not
895 */
896 bool StartsWithIgnoreCase(const String & s) const {return ((Length() >= s.Length())&&(Strncasecmp(Cstr(), s(), s.Length()) == 0));}
897
898 /** Like StartsWith(), but case insensitive.
899 * @param s The prefix to see whether this string starts with or not
900 */
901 bool StartsWithIgnoreCase(const char * s) const {if (s==NULL) s=""; return (Strncasecmp(Cstr(), s, strlen(s)) == 0);}
902
903 /** @copydoc DoxyTemplate::HashCode() const */
904 inline uint32 HashCode() const {return CalculateHashCode(Cstr(), Length());}
905
906 /** @copydoc DoxyTemplate::HashCode64() const */
907 inline uint64 HashCode64() const {return CalculateHashCode64(Cstr(), Length());}
908
909 /** Replaces all instances of (oldChar) in this string with (newChar).
910 * @param replaceMe The character to search for.
911 * @param withMe The character to replace all occurrences of (replaceMe) with.
912 * @param maxReplaceCount The maximum number of characters that should be replaced. Defaults to MUSCLE_NO_LIMIT.
913 * @returns The number of characters that were successfully replaced.
914 */
915 uint32 Replace(char replaceMe, char withMe, uint32 maxReplaceCount = MUSCLE_NO_LIMIT);
916
917 /** Same as Replace(), but instead of modifying this object, it returns a modified copy, and the called object remains unchanged.
918 * @param replaceMe The character to search for.
919 * @param withMe The character to replace all occurrences of (replaceMe) with.
920 * @param maxReplaceCount The maximum number of characters that should be replaced. Defaults to MUSCLE_NO_LIMIT.
921 * @returns The modified string.
922 */
923 String WithReplacements(char replaceMe, char withMe, uint32 maxReplaceCount = MUSCLE_NO_LIMIT) const;
924
925 /** Replaces all instances of (replaceMe) in this string with (withMe).
926 * @param replaceMe The substring to search for.
927 * @param withMe The substring to replace all occurrences of (replaceMe) with.
928 * @param maxReplaceCount The maximum number of substrings that should be replaced. Defaults to MUSCLE_NO_LIMIT.
929 * @returns The number of substrings that were successfully replaced, or -1 if the operation failed (out of memory)
930 */
931 int32 Replace(const String & replaceMe, const String & withMe, uint32 maxReplaceCount = MUSCLE_NO_LIMIT);
932
933 /** Same as Replace(), but instead of modifying this object, it returns a modified copy, and the called object remains unchanged.
934 * @param replaceMe The substring to search for.
935 * @param withMe The substring to replace all occurrences of (replaceMe) with.
936 * @param maxReplaceCount The maximum number of substrings that should be replaced. Defaults to MUSCLE_NO_LIMIT.
937 * @returns The modified string.
938 */
939 String WithReplacements(const String & replaceMe, const String & withMe, uint32 maxReplaceCount = MUSCLE_NO_LIMIT) const;
940
941 /** Returns a String equal to this one, except with a set of search-and-replace operations performed.
942 * @param beforeToAfter the search-and-replace operations to perform. Keys in this table are the strings
943 * to be searched for, and each key's associated value is the string to replace it with.
944 * @param maxReplaceCount The maximum number of substrings that should be replaced. Defaults to MUSCLE_NO_LIMIT.
945 * @note By performing multiple search-and-replace operations simultaneously, we can give correct results in
946 * certain cases where a series of single-string search-and-replace operations would not. For example,
947 * String("1,2,3,4").WithReplacements("1","2").WithReplacements("2","3") returns "3,3,3,4"
948 * instead of the hoped-for "2,3,3,4".
949 * @note Search-and-replace operations will be done in the iteration-order of the beforeToAfter Hashtable
950 * argument, so in any cases of conflicts, key->value pairs found earlier in the iteration will
951 * take precedence over those found later in the iteration.
952 */
953 String WithReplacements(const Hashtable<String, String> & beforeToAfter, uint32 maxReplaceCount = MUSCLE_NO_LIMIT) const;
954
955 /** Reverses the order of all characters in the string, so that e.g. "string" becomes "gnirts" */
956 void Reverse();
957
958 /** Part of the Flattenable pseudo-interface.
959 * @return false
960 */
961 bool IsFixedSize() const {return false;}
962
963 /** Part of the Flattenable pseudo-interface.
964 * @return B_STRING_TYPE
965 */
966 uint32 TypeCode() const {return B_STRING_TYPE;}
967
968 /** Returns true iff (tc) equals B_STRING_TYPE.
969 * @param tc the type code to check
970 */
971 bool AllowsTypeCode(uint32 tc) const {return (TypeCode()==tc);}
972
973 /** Part of the Flattenable pseudo-interface.
974 * @return Length()+1 (the +1 is for the terminating NUL byte)
975 */
976 uint32 FlattenedSize() const {return Length()+1;}
977
978 /** Part of the Flattenable pseudo-interface. Flattens our string into (buffer).
979 * @param buffer A byte array to receive the flattened version of this string.
980 * There must be at least FlattenedSize() bytes available in this array.
981 * @note The clever secret here is that a flattened String is just a C-style
982 * zero-terminated char array, and can be used interchangably as such.
983 */
984 void Flatten(uint8 *buffer) const {memcpy((char *)buffer, Cstr(), FlattenedSize());}
985
986 /** Unflattens a String from (buf).
987 * @param buf an array of (size) bytes.
988 * @param size the number of bytes in (buf).
989 * @note The clever secret here is that (buf) is treated as just a C-style
990 * zero-terminated char array, and can be used interchangably as such.
991 * @return B_NO_ERROR (never fails!)
992 */
993 status_t Unflatten(const uint8 *buf, uint32 size) {return SetCstr((const char *)buf, size);}
994
995 /** Makes sure that we have pre-allocated enough space for a NUL-terminated string
996 * at least (numChars) bytes long (not including the NUL byte).
997 * If not, this method will try to allocate the space.
998 * @param numChars How much space to pre-allocate, in ASCII characters.
999 * @returns B_NO_ERROR on success, or B_OUT_OF_MEMORY on failure.
1000 */
1001 status_t Prealloc(uint32 numChars) {return EnsureBufferSize(numChars+1, true, false);}
1002
1003 /** Removes (numCharsToTruncate) characters from the end of this string.
1004 * @param numCharsToTruncate How many characters to truncate. If greater than the
1005 * length of this String, this String will become empty.
1006 */
1007 void TruncateChars(uint32 numCharsToTruncate) {_length -= muscleMin(_length, numCharsToTruncate); WriteNULTerminatorByte();}
1008
1009 /** Makes sure this string is no longer than (maxLength) characters long by truncating
1010 * any extra characters, if necessary
1011 * @param maxLength Maximum length that this string should be allowed to be.
1012 */
1013 void TruncateToLength(uint32 maxLength) {_length = muscleMin(_length, maxLength); WriteNULTerminatorByte();}
1014
1015 /** Returns a string like this string, but with the appropriate %# tokens
1016 * replaced with a textual representation of the values passed in as (value).
1017 * For example, String("%1 is a %2").Arg(13).Arg("bakers dozen") would return
1018 * the string "13 is a bakers dozen".
1019 * @param value The value to replace in the string.
1020 * @param fmt The format parameter to pass to muscleSprintf(). Note that if you supply your
1021 * own format string, you'll need to be careful since a badly chosen format
1022 * string could lead to a crash or out-of-bounds memory overwrite. In particular,
1023 * the format string should match the type specified, and should not lead to
1024 * more than 256 bytes being written.
1025 * @returns a new String with the appropriate tokens replaced.
1026 */
1027 String Arg(bool value, const char * fmt = "%s") const;
1028
1029 /** As above, but for char values.
1030 * @copydoc Arg(bool, const char *) const
1031 */
1032 String Arg(char value, const char * fmt = "%i") const;
1033
1034 /** As above, but for unsigned char values.
1035 * @copydoc Arg(bool, const char *) const
1036 */
1037 String Arg(unsigned char value, const char * fmt = "%u") const;
1038
1039 /** As above, but for short values.
1040 * @copydoc Arg(bool, const char *) const
1041 */
1042 String Arg(short value, const char * fmt = "%i") const;
1043
1044 /** As above, but for unsigned shot values.
1045 * @copydoc Arg(bool, const char *) const
1046 */
1047 String Arg(unsigned short value, const char * fmt = "%u") const;
1048
1049 /** As above, but for int values.
1050 * @copydoc Arg(bool, const char *) const
1051 */
1052 String Arg(int value, const char * fmt = "%i") const;
1053
1054 /** As above, but for unsigned int values.
1055 * @copydoc Arg(bool, const char *) const
1056 */
1057 String Arg(unsigned int value, const char * fmt = "%u") const;
1058
1059 /** As above, but for long values.
1060 * @copydoc Arg(bool, const char *) const
1061 */
1062 String Arg(long value, const char * fmt = "%li") const;
1063
1064 /** As above, but for unsigned long values.
1065 * @copydoc Arg(bool, const char *) const
1066 */
1067 String Arg(unsigned long value, const char * fmt = "%lu") const;
1068
1069 /** As above, but for long long values.
1070 * @copydoc Arg(bool, const char *) const
1071 */
1072 String Arg(long long value, const char * fmt = INT64_FORMAT_SPEC) const;
1073
1074 /** As above, but for unsigned long long values.
1075 * @copydoc Arg(bool, const char *) const
1076 */
1077 String Arg(unsigned long long value, const char * fmt = UINT64_FORMAT_SPEC) const;
1078
1079 /** As above, but for double values.
1080 * @copydoc Arg(bool, const char *) const
1081 */
1082 String Arg(double value, const char * fmt) const;
1083
1084 /** As above, but for double values.
1085 * Returns a String representation of the given floating point value,
1086 * with up to (maxDigitsAfterDecimal) digits appearing after the decimal point.
1087 * @param f the floating-point value to return a String representation of.
1088 * @param minDigitsAfterDecimal the minimum number of digits to display after the decimal
1089 * point. Defaults to 0 (meaning try to use as few as possible)
1090 * @param maxDigitsAfterDecimal the maximum number of digits to display after the decimal
1091 * point. Defaults to MUSCLE_NO_LIMIT (meaning that no particular
1092 * maximum value should be enforced)
1093 * @note Trailing zeroes will be omitted from the string, as will the decimal point itself, if it
1094 * would otherwise be the last character in the String.
1095 */
1096 String Arg(double f, uint32 minDigitsAfterDecimal = 0, uint32 maxDigitsAfterDecimal = MUSCLE_NO_LIMIT) const;
1097
1098 /** As above, but for string values.
1099 * @param value the string to replace any instances of %1 with (or %2 if %1 isn't present, or etc)
1100 */
1101 String Arg(const String & value) const;
1102
1103 /** As above, but for Point values.
1104 * @copydoc Arg(bool, const char *) const
1105 */
1106 String Arg(const Point & value, const char * fmt = "%f,%f") const;
1107
1108 /** As above, but for Rect values.
1109 * @copydoc Arg(bool, const char *) const
1110 */
1111 String Arg(const Rect & value, const char * fmt = "%f,%f,%f,%f") const;
1112
1113 /** As above, but for C string values.
1114 * @param value the string to replace any instances of "%1" with (or "%2" if "%1" isn't present, or etc)
1115 */
1116 String Arg(const char * value) const;
1117
1118 /** As above, but for printing pointer values.
1119 * @param value the pointer-value whose string representation we should replace any instances of %1 with (or %2 if %1 isn't present, or etc)
1120 */
1121 String Arg(const void * value) const;
1122
1123 /** If this string already ends with the specified character, returns this string verbatim.
1124 * Otherwise, returns a String equivalent to this one but with the specified character appended.
1125 * @param c The char we want to be sure is at the end of the returned String.
1126 */
1127 String WithSuffix(char c) const {return EndsWith(c) ? *this : Append(c);}
1128
1129 /** If this string already ends with the specified string, returns this string verbatim.
1130 * Otherwise, returns a String equivalent to this one but with the specified string appended.
1131 * @param str The string we want to be sure is at the end of the returned String.
1132 */
1133 String WithSuffix(const String & str) const {return EndsWith(str) ? *this : Append(str);}
1134
1135 /** If this string already begins with the specified character, returns this string verbatim.
1136 * Otherwise, returns a String equivalent to this one but with the specified character prepended.
1137 * @param c The character we want to be sure is at the beginning of the returned String.
1138 */
1139 String WithPrefix(char c) const {return StartsWith(c) ? *this : Prepend(c);}
1140
1141 /** If this string already begins with the specified string, returns this string verbatim.
1142 * Otherwise, returns a String equivalent to this one but with the specified string prepended.
1143 * @param str The string we want to be sure is at the beginning of the returned String.
1144 */
1145 String WithPrefix(const String & str) const {return StartsWith(str) ? *this : Prepend(str);}
1146
1147 /** Returns a String like this one, but with any characters (c) removed from the end.
1148 * @param c The char we want to be sure is not at the end of the returned String.
1149 * @param maxToRemove Maximum number of instances of (c) to remove from the returned String.
1150 * Defaults to MUSCLE_NO_LIMIT, i.e. remove all trailing (c) chars.
1151 */
1152 String WithoutSuffix(char c, uint32 maxToRemove = MUSCLE_NO_LIMIT) const;
1153
1154 /** Returns a String like this one, but with any instances of (str) removed from the end.
1155 * @param str The substring we want to be sure is not at the end of the returned String.
1156 * @param maxToRemove Maximum number of instances of (c) to remove from the returned String.
1157 * Defaults to MUSCLE_NO_LIMIT, i.e. remove all trailing (str) substrings.
1158 * @note if (str) is empty, this method will return (*this).
1159 */
1160 String WithoutSuffix(const String & str, uint32 maxToRemove = MUSCLE_NO_LIMIT) const;
1161
1162 /** Returns a String like this one, but with any characters (c) removed from the beginning.
1163 * @param c The char we want to be sure is not at the beginning of the returned String.
1164 * @param maxToRemove Maximum number of instances of (c) to remove from the returned String.
1165 * Defaults to MUSCLE_NO_LIMIT, i.e. remove all starting (c) chars.
1166 */
1167 String WithoutPrefix(char c, uint32 maxToRemove = MUSCLE_NO_LIMIT) const;
1168
1169 /** Returns a String like this one, but with any instances of (str) removed from the beginning.
1170 * @param str The substring we want to be sure is not at the beginning of the returned String.
1171 * @param maxToRemove Maximum number of instances of (c) to remove from the returned String.
1172 * Defaults to MUSCLE_NO_LIMIT, i.e. remove all starting (str) substrings.
1173 * @note if (str) is empty, this method will return (*this).
1174 */
1175 String WithoutPrefix(const String & str, uint32 maxToRemove = MUSCLE_NO_LIMIT) const;
1176
1177 /** Returns a String like this one, but with any characters (c) removed from the end.
1178 * @param c The char we want to be sure is not at the end of the returned String (case-insensitive).
1179 * @param maxToRemove Maximum number of instances of (c) to remove from the returned String.
1180 * Defaults to MUSCLE_NO_LIMIT, i.e. remove all trailing (c) chars.
1181 */
1182 String WithoutSuffixIgnoreCase(char c, uint32 maxToRemove = MUSCLE_NO_LIMIT) const;
1183
1184 /** Returns a String like this one, but with any instances of (str) removed from the end.
1185 * @param str The substring we want to be sure is not at the end of the returned String (case-insensitive).
1186 * @param maxToRemove Maximum number of instances of (c) to remove from the returned String.
1187 * Defaults to MUSCLE_NO_LIMIT, i.e. remove all trailing (str) substrings.
1188 * @note if (str) is empty, this method will return (*this).
1189 */
1190 String WithoutSuffixIgnoreCase(const String & str, uint32 maxToRemove = MUSCLE_NO_LIMIT) const;
1191
1192 /** Returns a String like this one, but with any characters (c) removed from the beginning.
1193 * @param c The char we want to be sure is not at the beginning of the returned String (case-insensitive).
1194 * @param maxToRemove Maximum number of instances of (c) to remove from the returned String.
1195 * Defaults to MUSCLE_NO_LIMIT, i.e. remove all starting (c) chars.
1196 */
1197 String WithoutPrefixIgnoreCase(char c, uint32 maxToRemove = MUSCLE_NO_LIMIT) const;
1198
1199 /** Returns a String like this one, but with any instances of (str) removed from the beginning.
1200 * @param str The substring we want to be sure is not at the beginning of the returned String (case-insensitive).
1201 * @param maxToRemove Maximum number of instances of (c) to remove from the returned String.
1202 * Defaults to MUSCLE_NO_LIMIT, i.e. remove all starting (str) substrings.
1203 * @note if (str) is empty, this method will return (*this).
1204 */
1205 String WithoutPrefixIgnoreCase(const String & str, uint32 maxToRemove = MUSCLE_NO_LIMIT) const;
1206
1207 /** Returns a String equal to this one, but with any integer/numeric suffix removed.
1208 * For example, if you called this method on the String "Joe-54", this method would return "Joe".
1209 * @param optRetRemovedSuffixValue If non-NULL, the numeric suffix that was removed will be returned here.
1210 * If there was no numeric suffix, zero will be written here.
1211 * @note that negative numeric suffixes aren't supported -- i.e. plus or minus is not considered to be part of the numeric-suffix.
1212 */
1213 String WithoutNumericSuffix(uint32 * optRetRemovedSuffixValue = NULL) const;
1214
1215 /** If this string ends in a numeric value, returns that value; otherwise returns (defaultValue).
1216 * For example, ParseNumericSuffix("Joe-54") would return 54.
1217 * @param defaultValue the value to return if no numeric suffix is found. Defaults to zero.
1218 * @note that negative numeric suffixes aren't supported -- i.e. plus or minus is not considered to be part of the numeric-suffix.
1219 */
1220 uint32 ParseNumericSuffix(uint32 defaultValue = 0) const;
1221
1222 /** Returns a 32-bit checksum corresponding to this String's contents.
1223 * Note that this method method is O(N).
1224 */
1225 uint32 CalculateChecksum() const {return muscle::CalculateChecksum((const uint8 *) Cstr(), Length());}
1226
1227 /** Returns true iff the given pointer points into our held character array.
1228 * @param s A character pointer. It will not be dereferenced by this call.
1229 */
1230 bool IsCharInLocalArray(const char * s) const {const char * b = Cstr(); return muscleInRange(s, b, b+_length);}
1231
1232 private:
1233 bool IsSpaceChar(char c) const {return ((c==' ')||(c=='\t')||(c=='\r')||(c=='\n'));}
1234 status_t EnsureBufferSize(uint32 newBufLen, bool retainValue, bool allowShrink);
1235 String ArgAux(const char * buf) const;
1236 bool IsArrayDynamicallyAllocated() const {return (_bufferLen>sizeof(_strData._smallBuffer));}
1237 char * GetBuffer() {return IsArrayDynamicallyAllocated() ? _strData._bigBuffer : _strData._smallBuffer;}
1238 void ClearSmallBuffer() {memset(_strData._smallBuffer, 0, sizeof(_strData._smallBuffer));}
1239 void WriteNULTerminatorByte() {GetBuffer()[_length] = '\0';}
1240
1241 #ifdef __clang_analyzer__
1242 struct ShortStringOptimizationData { // ClangSA gets confused by unions, so we'll avoid SSO during Clang analysis
1243 #else
1244 union ShortStringOptimizationData {
1245 #endif
1246 char * _bigBuffer; // Pointer to allocated array. Valid iff (_bufferLen > sizeof(_smallBuffer))
1247 char _smallBuffer[SMALL_MUSCLE_STRING_LENGTH+1]; // inline character array. Valid iff (_bufferLen <= sizeof(_smallBuffer))
1248 } _strData;
1249
1250 uint32 _bufferLen; // Number of bytes pointed to by (GetBuffer())
1251 uint32 _length; // cached strlen(GetBuffer())
1252
1253 void VerifyIndex(uint32 index) const
1254 {
1255 #ifdef MUSCLE_AVOID_ASSERTIONS
1256 (void) index; // avoid compiler warnings
1257 #else
1258 MASSERT(index < _length, "Index Out Of Bounds Exception");
1259 #endif
1260 }
1261 };
1262
1263 /** A custom compare functor for case-insensitive comparisons of Strings. */
1264 class CaseInsensitiveStringCompareFunctor
1265 {
1266 public:
1267 /** Compares the two String's strcmp() style, returning zero if they are equal, a negative value if (item1) comes first, or a positive value if (item2) comes first.
1268 * @param s1 the first String to compare
1269 * @param s2 the second String to compare
1270 */
1271 int Compare(const String & s1, const String & s2, void *) const {return s1.CompareToIgnoreCase(s2);}
1272 };
1273
1274 /** A custom compare functor for numeric-aware comparisons of Strings. */
1275 class NumericAwareStringCompareFunctor
1276 {
1277 public:
1278 /** Compares the two String's strcmp() style, returning zero if they are equal, a negative value if (item1) comes first, or a positive value if (item2) comes first.
1279 * @param s1 the first String to compare
1280 * @param s2 the second String to compare
1281 */
1282 int Compare(const String & s1, const String & s2, void *) const {return s1.NumericAwareCompareTo(s2);}
1283 };
1284
1285 /** A custom compare functor for case-insensitive numeric-aware comparisons of Strings. */
1286 class CaseInsensitiveNumericAwareStringCompareFunctor
1287 {
1288 public:
1289 /** Compares the two String's strcmp() style, returning zero if they are equal, a negative value if (item1) comes first, or a positive value if (item2) comes first.
1290 * @param s1 the first String to compare
1291 * @param s2 the second String to compare
1292 */
1293 int Compare(const String & s1, const String & s2, void *) const {return s1.NumericAwareCompareToIgnoreCase(s2);}
1294 };
1295
1296 /** Convenience method: returns a string with no characters in it (a.k.a. "") */
1297 inline const String & GetEmptyString() {return GetDefaultObjectForType<String>();}
1298
1299 inline String operator+(const String & lhs, const String & rhs) {String ret; (void) ret.Prealloc(lhs.Length()+rhs.Length()); ret = lhs; ret += rhs; return ret;}
1300 inline String operator+(const String & lhs, const char *rhs) {String ret; (void) ret.Prealloc(lhs.Length()+(rhs?(uint32)strlen(rhs):0)); ret = lhs; ret += rhs; return ret;}
1301 inline String operator+(const char * lhs, const String & rhs) {String ret; (void) ret.Prealloc((lhs?(uint32)strlen(lhs):0)+rhs.Length()); ret = lhs; ret += rhs; return ret;}
1302 inline String operator+(const String & lhs, char rhs) {String ret; (void) ret.Prealloc(lhs.Length()+1); ret = lhs; ret += rhs; return ret;}
1303 inline String operator+(char lhs, const String & rhs) {String ret; (void) ret.Prealloc(1+rhs.Length()); ret.SetCstr(&lhs, 1); ret += rhs; return ret;}
1304 inline String operator-(const String & lhs, const String & rhs) {String ret = lhs; ret -= rhs; return ret;}
1305 inline String operator-(const String & lhs, const char *rhs) {String ret = lhs; ret -= rhs; return ret;}
1306 inline String operator-(const char *lhs, const String & rhs) {String ret = lhs; ret -= rhs; return ret;}
1307 inline String operator-(const String & lhs, char rhs) {String ret = lhs; ret -= rhs; return ret;}
1308 inline String operator-(char lhs, const String & rhs) {String ret; ret.SetCstr(&lhs, 1); ret -= rhs; return ret;}
1309
1310 } // end namespace muscle
1311
1312 #endif