"Fossies" - the Fresh Open Source Software Archive

Member "muscle/util/String.h" (8 Jun 2019, 67086 Bytes) of package /linux/privat/muscle7.30.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 last Fossies "Diffs" side-by-side code changes report: 7.20_vs_7.21.

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