2002-09-06 11:12:06 +04:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Copyright (c) 2001-2002, OpenBeOS
|
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
//
|
|
|
|
// File Name: String.h
|
|
|
|
// Author(s): Stefano Ceccherini (burton666@libero.it)
|
|
|
|
// Description: String class supporting common string operations.
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef __BSTRING__
|
|
|
|
#define __BSTRING__
|
|
|
|
|
|
|
|
#include <BeBuild.h>
|
|
|
|
#include <SupportDefs.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
class BString {
|
|
|
|
public:
|
|
|
|
BString();
|
|
|
|
BString(const char *);
|
|
|
|
BString(const BString &);
|
|
|
|
BString(const char *, int32 maxLength);
|
|
|
|
|
|
|
|
~BString();
|
|
|
|
|
|
|
|
/*---- Access --------------------------------------------------------------*/
|
|
|
|
const char *String() const;
|
|
|
|
/* returns null-terminated string */
|
|
|
|
|
|
|
|
int32 Length() const;
|
|
|
|
/* length of corresponding string */
|
|
|
|
|
|
|
|
int32 CountChars() const;
|
|
|
|
/* returns number of UTF8 characters in string */
|
|
|
|
/*---- Assignment ----------------------------------------------------------*/
|
|
|
|
BString &operator=(const BString &);
|
|
|
|
BString &operator=(const char *);
|
|
|
|
BString &operator=(char);
|
|
|
|
|
|
|
|
BString &SetTo(const char *);
|
|
|
|
BString &SetTo(const char *, int32 length);
|
|
|
|
|
|
|
|
BString &SetTo(const BString &from);
|
|
|
|
BString &Adopt(BString &from);
|
|
|
|
/* leaves <from> empty, avoiding a copy */
|
|
|
|
|
|
|
|
BString &SetTo(const BString &, int32 length);
|
|
|
|
BString &Adopt(BString &from, int32 length);
|
|
|
|
/* leaves <from> empty, avoiding a copy */
|
|
|
|
|
|
|
|
BString &SetTo(char, int32 count);
|
|
|
|
|
|
|
|
/*---- Substring copying ---------------------------------------------------*/
|
|
|
|
BString &CopyInto(BString &into, int32 fromOffset,
|
|
|
|
int32 length) const;
|
|
|
|
/* returns <into> ref as it's result; doesn't do
|
|
|
|
* anything if <into> is <this>
|
|
|
|
*/
|
|
|
|
|
|
|
|
void CopyInto(char *into, int32 fromOffset,
|
|
|
|
int32 length) const;
|
|
|
|
/* caller guarantees that <into> is large enough */
|
|
|
|
|
|
|
|
/*---- Appending -----------------------------------------------------------*/
|
|
|
|
BString &operator+=(const BString &);
|
|
|
|
BString &operator+=(const char *);
|
|
|
|
BString &operator+=(char);
|
|
|
|
|
|
|
|
BString &Append(const BString &);
|
|
|
|
BString &Append(const char *);
|
|
|
|
|
|
|
|
BString &Append(const BString &, int32 length);
|
|
|
|
BString &Append(const char *, int32 length);
|
|
|
|
BString &Append(char, int32 count);
|
|
|
|
|
|
|
|
/*---- Prepending ----------------------------------------------------------*/
|
|
|
|
BString &Prepend(const char *);
|
|
|
|
BString &Prepend(const BString &);
|
|
|
|
BString &Prepend(const char *, int32);
|
|
|
|
BString &Prepend(const BString &, int32);
|
|
|
|
BString &Prepend(char, int32 count);
|
|
|
|
|
|
|
|
/*---- Inserting ----------------------------------------------------------*/
|
|
|
|
BString &Insert(const char *, int32 pos);
|
|
|
|
BString &Insert(const char *, int32 length, int32 pos);
|
|
|
|
BString &Insert(const char *, int32 fromOffset,
|
|
|
|
int32 length, int32 pos);
|
|
|
|
|
|
|
|
BString &Insert(const BString &, int32 pos);
|
|
|
|
BString &Insert(const BString &, int32 length, int32 pos);
|
|
|
|
BString &Insert(const BString &, int32 fromOffset,
|
|
|
|
int32 length, int32 pos);
|
|
|
|
BString &Insert(char, int32 count, int32 pos);
|
|
|
|
|
|
|
|
/*---- Removing -----------------------------------------------------------*/
|
|
|
|
BString &Truncate(int32 newLength, bool lazy = true);
|
|
|
|
/* pass false in <lazy> to ensure freeing up the
|
|
|
|
* truncated memory
|
|
|
|
*/
|
|
|
|
|
|
|
|
BString &Remove(int32 from, int32 length);
|
|
|
|
|
|
|
|
BString &RemoveFirst(const BString &);
|
|
|
|
BString &RemoveLast(const BString &);
|
|
|
|
BString &RemoveAll(const BString &);
|
|
|
|
|
|
|
|
BString &RemoveFirst(const char *);
|
|
|
|
BString &RemoveLast(const char *);
|
|
|
|
BString &RemoveAll(const char *);
|
|
|
|
|
|
|
|
BString &RemoveSet(const char *setOfCharsToRemove);
|
|
|
|
|
|
|
|
BString &MoveInto(BString &into, int32 from, int32 length);
|
|
|
|
void MoveInto(char *into, int32 from, int32 length);
|
|
|
|
/* caller guarantees that <into> is large enough */
|
|
|
|
|
|
|
|
|
|
|
|
/*---- Compare functions ---------------------------------------------------*/
|
|
|
|
bool operator<(const BString &) const;
|
|
|
|
bool operator<=(const BString &) const;
|
|
|
|
bool operator==(const BString &) const;
|
|
|
|
bool operator>=(const BString &) const;
|
|
|
|
bool operator>(const BString &) const;
|
|
|
|
bool operator!=(const BString &) const;
|
|
|
|
|
|
|
|
bool operator<(const char *) const;
|
|
|
|
bool operator<=(const char *) const;
|
|
|
|
bool operator==(const char *) const;
|
|
|
|
bool operator>=(const char *) const;
|
|
|
|
bool operator>(const char *) const;
|
|
|
|
bool operator!=(const char *) const;
|
|
|
|
|
|
|
|
/*---- strcmp-style compare functions --------------------------------------*/
|
|
|
|
int Compare(const BString &) const;
|
|
|
|
int Compare(const char *) const;
|
|
|
|
int Compare(const BString &, int32 n) const;
|
|
|
|
int Compare(const char *, int32 n) const;
|
|
|
|
int ICompare(const BString &) const;
|
|
|
|
int ICompare(const char *) const;
|
|
|
|
int ICompare(const BString &, int32 n) const;
|
|
|
|
int ICompare(const char *, int32 n) const;
|
|
|
|
|
|
|
|
/*---- Searching -----------------------------------------------------------*/
|
|
|
|
int32 FindFirst(const BString &) const;
|
|
|
|
int32 FindFirst(const char *) const;
|
|
|
|
int32 FindFirst(const BString &, int32 fromOffset) const;
|
|
|
|
int32 FindFirst(const char *, int32 fromOffset) const;
|
|
|
|
int32 FindFirst(char) const;
|
|
|
|
int32 FindFirst(char, int32 fromOffset) const;
|
|
|
|
|
|
|
|
int32 FindLast(const BString &) const;
|
|
|
|
int32 FindLast(const char *) const;
|
|
|
|
int32 FindLast(const BString &, int32 beforeOffset) const;
|
|
|
|
int32 FindLast(const char *, int32 beforeOffset) const;
|
|
|
|
int32 FindLast(char) const;
|
2002-11-18 16:45:27 +03:00
|
|
|
int32 FindLast(char, int32 beforeOffset) const;
|
2002-09-06 11:12:06 +04:00
|
|
|
|
|
|
|
int32 IFindFirst(const BString &) const;
|
|
|
|
int32 IFindFirst(const char *) const;
|
|
|
|
int32 IFindFirst(const BString &, int32 fromOffset) const;
|
|
|
|
int32 IFindFirst(const char *, int32 fromOffset) const;
|
|
|
|
|
|
|
|
int32 IFindLast(const BString &) const;
|
|
|
|
int32 IFindLast(const char *) const;
|
|
|
|
int32 IFindLast(const BString &, int32 beforeOffset) const;
|
|
|
|
int32 IFindLast(const char *, int32 beforeOffset) const;
|
|
|
|
|
|
|
|
/*---- Replacing -----------------------------------------------------------*/
|
|
|
|
|
|
|
|
BString &ReplaceFirst(char replaceThis, char withThis);
|
|
|
|
BString &ReplaceLast(char replaceThis, char withThis);
|
|
|
|
BString &ReplaceAll(char replaceThis, char withThis,
|
|
|
|
int32 fromOffset = 0);
|
|
|
|
BString &Replace(char replaceThis, char withThis,
|
|
|
|
int32 maxReplaceCount, int32 fromOffset = 0);
|
|
|
|
BString &ReplaceFirst(const char *replaceThis,
|
|
|
|
const char *withThis);
|
|
|
|
BString &ReplaceLast(const char *replaceThis,
|
|
|
|
const char *withThis);
|
|
|
|
BString &ReplaceAll(const char *replaceThis,
|
|
|
|
const char *withThis, int32 fromOffset = 0);
|
|
|
|
BString &Replace(const char *replaceThis, const char *withThis,
|
|
|
|
int32 maxReplaceCount, int32 fromOffset = 0);
|
|
|
|
|
|
|
|
BString &IReplaceFirst(char replaceThis, char withThis);
|
|
|
|
BString &IReplaceLast(char replaceThis, char withThis);
|
|
|
|
BString &IReplaceAll(char replaceThis, char withThis,
|
|
|
|
int32 fromOffset = 0);
|
|
|
|
BString &IReplace(char replaceThis, char withThis,
|
|
|
|
int32 maxReplaceCount, int32 fromOffset = 0);
|
|
|
|
BString &IReplaceFirst(const char *replaceThis,
|
|
|
|
const char *withThis);
|
|
|
|
BString &IReplaceLast(const char *replaceThis,
|
|
|
|
const char *withThis);
|
|
|
|
BString &IReplaceAll(const char *replaceThis,
|
|
|
|
const char *withThis, int32 fromOffset = 0);
|
|
|
|
BString &IReplace(const char *replaceThis, const char *withThis,
|
|
|
|
int32 maxReplaceCount, int32 fromOffset = 0);
|
|
|
|
|
|
|
|
BString &ReplaceSet(const char *setOfChars, char with);
|
|
|
|
BString &ReplaceSet(const char *setOfChars, const char *with);
|
|
|
|
/*---- Unchecked char access -----------------------------------------------*/
|
|
|
|
char operator[](int32 index) const;
|
|
|
|
char &operator[](int32 index);
|
|
|
|
|
|
|
|
/*---- Checked char access -------------------------------------------------*/
|
|
|
|
char ByteAt(int32 index) const;
|
|
|
|
|
|
|
|
/*---- Fast low-level manipulation -----------------------------------------*/
|
|
|
|
char *LockBuffer(int32 maxLength);
|
|
|
|
|
|
|
|
/* Make room for characters to be added by C-string like manipulation.
|
|
|
|
* Returns the equivalent of String(), <maxLength> includes space for
|
|
|
|
* trailing zero while used as C-string, it is illegal to call other
|
|
|
|
* BString routines that rely on data/length consistency until
|
|
|
|
* UnlockBuffer sets things up again.
|
|
|
|
*/
|
|
|
|
|
|
|
|
BString &UnlockBuffer(int32 length = -1);
|
|
|
|
|
|
|
|
/* Finish using BString as C-string, adjusting length. If no length
|
|
|
|
* passed in, strlen of internal data is used to determine it.
|
|
|
|
* BString is in consistent state after this.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*---- Upercase<->Lowercase ------------------------------------------------*/
|
|
|
|
BString &ToLower();
|
|
|
|
BString &ToUpper();
|
|
|
|
|
|
|
|
BString &Capitalize();
|
|
|
|
/* Converts first character to upper-case, rest to
|
|
|
|
* lower-case
|
|
|
|
*/
|
|
|
|
|
|
|
|
BString &CapitalizeEachWord();
|
2002-11-18 16:45:27 +03:00
|
|
|
/* Converts first character in each
|
|
|
|
* non-alphabethycal-character-separated
|
2002-09-06 11:12:06 +04:00
|
|
|
* word to upper-case, rest to lower-case
|
|
|
|
*/
|
|
|
|
/*----- Escaping and Deescaping --------------------------------------------*/
|
|
|
|
BString &CharacterEscape(const char *original,
|
|
|
|
const char *setOfCharsToEscape, char escapeWith);
|
|
|
|
/* copies original into <this>, escaping characters
|
|
|
|
* specified in <setOfCharsToEscape> by prepending
|
|
|
|
* them with <escapeWith>
|
|
|
|
*/
|
|
|
|
BString &CharacterEscape(const char *setOfCharsToEscape,
|
|
|
|
char escapeWith);
|
|
|
|
/* escapes characters specified in <setOfCharsToEscape>
|
|
|
|
* by prepending them with <escapeWith>
|
|
|
|
*/
|
|
|
|
|
|
|
|
BString &CharacterDeescape(const char *original, char escapeChar);
|
|
|
|
/* copy <original> into the string removing the escaping
|
|
|
|
* characters <escapeChar>
|
|
|
|
*/
|
|
|
|
BString &CharacterDeescape(char escapeChar);
|
|
|
|
/* remove the escaping characters <escapeChar> from
|
|
|
|
* the string
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*---- Simple sprintf replacement calls ------------------------------------*/
|
|
|
|
/*---- Slower than sprintf but type and overflow safe ----------------------*/
|
|
|
|
BString &operator<<(const char *);
|
|
|
|
BString &operator<<(const BString &);
|
|
|
|
BString &operator<<(char);
|
|
|
|
BString &operator<<(int);
|
|
|
|
BString &operator<<(unsigned int);
|
|
|
|
BString &operator<<(uint32);
|
|
|
|
BString &operator<<(int32);
|
|
|
|
BString &operator<<(uint64);
|
|
|
|
BString &operator<<(int64);
|
|
|
|
BString &operator<<(float);
|
|
|
|
/* float output hardcodes %.2f style formatting */
|
|
|
|
|
|
|
|
/*----- Private or reserved ------------------------------------------------*/
|
|
|
|
private:
|
|
|
|
void _Init(const char *, int32);
|
|
|
|
void _DoAssign(const char *, int32);
|
|
|
|
void _DoAppend(const char *, int32);
|
|
|
|
char *_GrowBy(int32);
|
|
|
|
char *_OpenAtBy(int32, int32);
|
|
|
|
char *_ShrinkAtBy(int32, int32);
|
|
|
|
void _DoPrepend(const char *, int32);
|
|
|
|
|
|
|
|
int32 _FindAfter(const char *, int32, int32) const;
|
|
|
|
int32 _IFindAfter(const char *, int32, int32) const;
|
|
|
|
int32 _ShortFindAfter(const char *, int32) const;
|
|
|
|
int32 _FindBefore(const char *, int32, int32) const;
|
|
|
|
int32 _IFindBefore(const char *, int32, int32) const;
|
|
|
|
void _SetLength(int32);
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
void _SetUsingAsCString(bool);
|
|
|
|
void _AssertNotUsingAsCString() const;
|
|
|
|
#else
|
|
|
|
void _SetUsingAsCString(bool) {}
|
|
|
|
void _AssertNotUsingAsCString() const {}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
protected:
|
|
|
|
char *_privateData;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*----- Comutative compare operators --------------------------------------*/
|
|
|
|
bool operator<(const char *, const BString &);
|
|
|
|
bool operator<=(const char *, const BString &);
|
|
|
|
bool operator==(const char *, const BString &);
|
|
|
|
bool operator>(const char *, const BString &);
|
|
|
|
bool operator>=(const char *, const BString &);
|
|
|
|
bool operator!=(const char *, const BString &);
|
|
|
|
|
|
|
|
/*----- Non-member compare for sorting, etc. ------------------------------*/
|
|
|
|
int Compare(const BString &, const BString &);
|
|
|
|
int ICompare(const BString &, const BString &);
|
|
|
|
int Compare(const BString *, const BString *);
|
|
|
|
int ICompare(const BString *, const BString *);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/*---- No user serviceable parts after this -------------------------------*/
|
|
|
|
|
|
|
|
inline int32
|
|
|
|
BString::Length() const
|
|
|
|
{
|
|
|
|
return _privateData ? (*((int32 *)_privateData - 1) & 0x7fffffff) : 0;
|
|
|
|
/* the most significant bit is reserved; accessing
|
2002-09-26 18:22:16 +04:00
|
|
|
* it in any way will cause the computer to explode
|
2002-09-06 11:12:06 +04:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
inline const char *
|
|
|
|
BString::String() const
|
|
|
|
{
|
|
|
|
if (!_privateData)
|
|
|
|
return "";
|
|
|
|
return _privateData;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline BString &
|
|
|
|
BString::SetTo(const char *str)
|
|
|
|
{
|
|
|
|
return operator=(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline char
|
|
|
|
BString::operator[](int32 index) const
|
|
|
|
{
|
|
|
|
return _privateData[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
inline char
|
|
|
|
BString::ByteAt(int32 index) const
|
|
|
|
{
|
|
|
|
if (!_privateData || index < 0 || index > Length())
|
|
|
|
return 0;
|
|
|
|
return _privateData[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
inline BString &
|
|
|
|
BString::operator+=(const BString &string)
|
|
|
|
{
|
|
|
|
_DoAppend(string.String(), string.Length());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline BString &
|
|
|
|
BString::Append(const BString &string)
|
|
|
|
{
|
|
|
|
_DoAppend(string.String(), string.Length());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline BString &
|
|
|
|
BString::Append(const char *str)
|
|
|
|
{
|
|
|
|
return operator+=(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
BString::operator==(const BString &string) const
|
|
|
|
{
|
|
|
|
return strcmp(String(), string.String()) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
BString::operator<(const BString &string) const
|
|
|
|
{
|
|
|
|
return strcmp(String(), string.String()) < 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
BString::operator<=(const BString &string) const
|
|
|
|
{
|
|
|
|
return strcmp(String(), string.String()) <= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
BString::operator>=(const BString &string) const
|
|
|
|
{
|
|
|
|
return strcmp(String(), string.String()) >= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
BString::operator>(const BString &string) const
|
|
|
|
{
|
|
|
|
return strcmp(String(), string.String()) > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
BString::operator!=(const BString &string) const
|
|
|
|
{
|
|
|
|
return strcmp(String(), string.String()) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
BString::operator!=(const char *str) const
|
|
|
|
{
|
|
|
|
return !operator==(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
operator<(const char *str, const BString &string)
|
|
|
|
{
|
|
|
|
return string > str;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
operator<=(const char *str, const BString &string)
|
|
|
|
{
|
|
|
|
return string >= str;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
operator==(const char *str, const BString &string)
|
|
|
|
{
|
|
|
|
return string == str;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
operator>(const char *str, const BString &string)
|
|
|
|
{
|
|
|
|
return string < str;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
operator>=(const char *str, const BString &string)
|
|
|
|
{
|
|
|
|
return string <= str;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
operator!=(const char *str, const BString &string)
|
|
|
|
{
|
|
|
|
return string != str;
|
|
|
|
}
|
|
|
|
|
2002-09-28 03:44:26 +04:00
|
|
|
#endif /* __BSTRING__ */
|