/* * Copyright 2001-2010 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _B_STRING_H #define _B_STRING_H #include #include #include class BStringList; class BStringRef; class BString { public: BString(); BString(const char* string); BString(const BString& string); BString(const char* string, int32 maxLength); ~BString(); // Access const char* String() const; int32 Length() const; int32 CountChars() const; int32 CountBytes(int32 fromCharOffset, int32 charCount) const; bool IsEmpty() const; uint32 HashValue() const; static uint32 HashValue(const char* string); // Assignment BString& operator=(const BString& string); BString& operator=(const char* string); BString& operator=(char c); BString& SetTo(const char* string); BString& SetTo(const char* string, int32 maxLength); BString& SetTo(const BString& string); BString& Adopt(BString& from); BString& SetTo(const BString& string, int32 maxLength); BString& Adopt(BString& from, int32 maxLength); BString& SetTo(char c, int32 count); BString& SetToChars(const char* string, int32 charCount); BString& SetToChars(const BString& string, int32 charCount); BString& AdoptChars(BString& from, int32 charCount); BString& SetToFormat(const char* format, ...) __attribute__((__format__(__printf__, 2, 3))); BString& SetToFormatVarArgs(const char* format, va_list args) __attribute__((__format__(__printf__, 2, 0))); int ScanWithFormat(const char* format, ...) __attribute__((__format__(__scanf__, 2, 3))); int ScanWithFormatVarArgs(const char* format, va_list args) __attribute__((__format__(__scanf__, 2, 0))); // Substring copying BString& CopyInto(BString& into, int32 fromOffset, int32 length) const; void CopyInto(char* into, int32 fromOffset, int32 length) const; BString& CopyCharsInto(BString& into, int32 fromCharOffset, int32 charCount) const; bool CopyCharsInto(char* into, int32* intoLength, int32 fromCharOffset, int32 charCount) const; bool Split(const char* separator, bool noEmptyStrings, BStringList& _list) const; // Appending BString& operator+=(const BString& string); BString& operator+=(const char* string); BString& operator+=(char c); BString& Append(const BString& string); BString& Append(const char* string); BString& Append(const BString& string, int32 length); BString& Append(const char* string, int32 length); BString& Append(char c, int32 count); BString& AppendChars(const BString& string, int32 charCount); BString& AppendChars(const char* string, int32 charCount); // Prepending BString& Prepend(const char* string); BString& Prepend(const BString& string); BString& Prepend(const char* string, int32 length); BString& Prepend(const BString& string, int32 length); BString& Prepend(char c, int32 count); BString& PrependChars(const char* string, int32 charCount); BString& PrependChars(const BString& string, int32 charCount); // Inserting BString& Insert(const char* string, int32 position); BString& Insert(const char* string, int32 length, int32 position); BString& Insert(const char* string, int32 fromOffset, int32 length, int32 position); BString& Insert(const BString& string, int32 position); BString& Insert(const BString& string, int32 length, int32 position); BString& Insert(const BString& string, int32 fromOffset, int32 length, int32 position); BString& Insert(char c, int32 count, int32 position); BString& InsertChars(const char* string, int32 charPosition); BString& InsertChars(const char* string, int32 charCount, int32 charPosition); BString& InsertChars(const char* string, int32 fromCharOffset, int32 charCount, int32 charPosition); BString& InsertChars(const BString& string, int32 charPosition); BString& InsertChars(const BString& string, int32 charCount, int32 charPosition); BString& InsertChars(const BString& string, int32 fromCharOffset, int32 charCount, int32 charPosition); // Removing BString& Truncate(int32 newLength, bool lazy = true); BString& TruncateChars(int32 newCharCount, bool lazy = true); BString& Remove(int32 from, int32 length); BString& RemoveChars(int32 fromCharOffset, int32 charCount); BString& RemoveFirst(const BString& string); BString& RemoveLast(const BString& string); BString& RemoveAll(const BString& string); BString& RemoveFirst(const char* string); BString& RemoveLast(const char* string); BString& RemoveAll(const char* string); BString& RemoveSet(const char* setOfBytesToRemove); BString& RemoveCharsSet(const char* setOfCharsToRemove); BString& MoveInto(BString& into, int32 from, int32 length); void MoveInto(char* into, int32 from, int32 length); BString& MoveCharsInto(BString& into, int32 fromCharOffset, int32 charCount); bool MoveCharsInto(char* into, int32* intoLength, int32 fromCharOffset, int32 charCount); // Compare functions bool operator<(const BString& string) const; bool operator<=(const BString& string) const; bool operator==(const BString& string) const; bool operator>=(const BString& string) const; bool operator>(const BString& string) const; bool operator!=(const BString& string) const; bool operator<(const char* string) const; bool operator<=(const char* string) const; bool operator==(const char* string) const; bool operator>=(const char* string) const; bool operator>(const char* string) const; bool operator!=(const char* string) const; operator const char*() const; // strcmp()-style compare functions int Compare(const BString& string) const; int Compare(const char* string) const; int Compare(const BString& string, int32 length) const; int Compare(const char* string, int32 length) const; int CompareAt(size_t offset, const BString& string, int32 length) const; int CompareChars(const BString& string, int32 charCount) const; int CompareChars(const char* string, int32 charCount) const; int ICompare(const BString& string) const; int ICompare(const char* string) const; int ICompare(const BString& string, int32 length) const; int ICompare(const char* string, int32 length) const; // Searching int32 FindFirst(const BString& string) const; int32 FindFirst(const char* string) const; int32 FindFirst(const BString& string, int32 fromOffset) const; int32 FindFirst(const char* string, int32 fromOffset) const; int32 FindFirst(char c) const; int32 FindFirst(char c, int32 fromOffset) const; int32 FindFirstChars(const BString& string, int32 fromCharOffset) const; int32 FindFirstChars(const char* string, int32 fromCharOffset) const; int32 FindLast(const BString& string) const; int32 FindLast(const char* string) const; int32 FindLast(const BString& string, int32 beforeOffset) const; int32 FindLast(const char* string, int32 beforeOffset) const; int32 FindLast(char c) const; int32 FindLast(char c, int32 beforeOffset) const; int32 FindLastChars(const BString& string, int32 beforeCharOffset) const; int32 FindLastChars(const char* string, int32 beforeCharOffset) const; int32 IFindFirst(const BString& string) const; int32 IFindFirst(const char* string) const; int32 IFindFirst(const BString& string, int32 fromOffset) const; int32 IFindFirst(const char* string, int32 fromOffset) const; int32 IFindLast(const BString& string) const; int32 IFindLast(const char* string) const; int32 IFindLast(const BString& string, int32 beforeOffset) const; int32 IFindLast(const char* string, int32 beforeOffset) const; bool StartsWith(const BString& string) const; bool StartsWith(const char* string) const; bool StartsWith(const char* string, int32 length) const; bool IStartsWith(const BString& string) const; bool IStartsWith(const char* string) const; bool IStartsWith(const char* string, int32 length) const; bool EndsWith(const BString& string) const; bool EndsWith(const char* string) const; bool EndsWith(const char* string, int32 length) const; bool IEndsWith(const BString& string) const; bool IEndsWith(const char* string) const; bool IEndsWith(const char* string, int32 length) 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& ReplaceAllChars(const char* replaceThis, const char* withThis, int32 fromCharOffset); BString& ReplaceChars(const char* replaceThis, const char* withThis, int32 maxReplaceCount, int32 fromCharOffset); 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* setOfBytes, char with); BString& ReplaceSet(const char* setOfBytes, const char* with); BString& ReplaceCharsSet(const char* setOfChars, const char* with); // Unchecked char access char operator[](int32 index) const; #if __GNUC__ == 2 char& operator[](int32 index); #endif // Checked char access char ByteAt(int32 index) const; const char* CharAt(int32 charIndex, int32* bytes = NULL) const; bool CharAt(int32 charIndex, char* buffer, int32* bytes) const; // Fast low-level manipulation char* LockBuffer(int32 maxLength); BString& UnlockBuffer(int32 length = -1); BString& SetByteAt(int32 pos, char to); // Upercase <-> Lowercase BString& ToLower(); BString& ToUpper(); BString& Capitalize(); BString& CapitalizeEachWord(); // Escaping and De-escaping BString& CharacterEscape(const char* original, const char* setOfCharsToEscape, char escapeWith); BString& CharacterEscape(const char* setOfCharsToEscape, char escapeWith); BString& CharacterDeescape(const char* original, char escapeChar); BString& CharacterDeescape(char escapeChar); // Trimming BString& Trim(); // Insert BString& operator<<(const char* string); BString& operator<<(const BString& string); BString& operator<<(char c); BString& operator<<(bool value); BString& operator<<(int value); BString& operator<<(unsigned int value); BString& operator<<(unsigned long value); BString& operator<<(long value); BString& operator<<(unsigned long long value); BString& operator<<(long long value); // float/double output hardcodes %.2f style formatting BString& operator<<(float value); BString& operator<<(double value); public: class Private; friend class Private; private: class PosVect; friend class BStringRef; enum PrivateDataTag { PRIVATE_DATA }; private: BString(char* privateData, PrivateDataTag tag); // Management status_t _MakeWritable(); status_t _MakeWritable(int32 length, bool copy); static char* _Allocate(int32 length); char* _Resize(int32 length); void _Init(const char* src, int32 length); char* _Clone(const char* data, int32 length); char* _OpenAtBy(int32 offset, int32 length); char* _ShrinkAtBy(int32 offset, int32 length); // Data void _SetLength(int32 length); bool _DoAppend(const char* string, int32 length); bool _DoPrepend(const char* string, int32 length); bool _DoInsert(const char* string, int32 offset, int32 length); // Search int32 _ShortFindAfter(const char* string, int32 length) const; int32 _FindAfter(const char* string, int32 offset, int32 length) const; int32 _IFindAfter(const char* string, int32 offset, int32 length) const; int32 _FindBefore(const char* string, int32 offset, int32 length) const; int32 _IFindBefore(const char* string, int32 offset, int32 length) const; // Escape BString& _DoCharacterEscape(const char* string, const char* setOfCharsToEscape, char escapeChar); BString& _DoCharacterDeescape(const char* string, char escapeChar); // Replace BString& _DoReplace(const char* findThis, const char* replaceWith, int32 maxReplaceCount, int32 fromOffset, bool ignoreCase); void _ReplaceAtPositions(const PosVect* positions, int32 searchLength, const char* with, int32 withLength); private: int32& _ReferenceCount(); const int32& _ReferenceCount() const; bool _IsShareable() const; void _FreePrivateData(); char* fPrivateData; }; // Commutative compare operators bool operator<(const char* a, const BString& b); bool operator<=(const char* a, const BString& b); bool operator==(const char* a, const BString& b); bool operator>(const char* a, const BString& b); bool operator>=(const char* a, const BString& b); bool operator!=(const char* a, const BString& b); // Non-member compare for sorting, etc. int Compare(const BString& a, const BString& b); int ICompare(const BString& a, const BString& b); int Compare(const BString* a, const BString* b); int ICompare(const BString* a, const BString* b); inline int32 BString::Length() const { // the most significant bit is reserved; accessing // it in any way will cause the computer to explode return fPrivateData ? (*(((int32*)fPrivateData) - 1) & 0x7fffffff) : 0; } inline bool BString::IsEmpty() const { return !Length(); } inline const char* BString::String() const { if (!fPrivateData) return ""; return fPrivateData; } inline uint32 BString::HashValue() const { return HashValue(String()); } inline BString& BString::SetTo(const char* string) { return operator=(string); } inline char BString::operator[](int32 index) const { return fPrivateData[index]; } inline char BString::ByteAt(int32 index) const { if (!fPrivateData || index < 0 || index >= Length()) return 0; return fPrivateData[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* string) { return operator+=(string); } 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* string) const { return !operator==(string); } inline BString::operator const char*() const { return String(); } 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; } #endif // _B_STRING_H