Patch by Julun: implements a refcounted BString. Thank You!

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24102 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2008-02-24 21:16:58 +00:00
parent b8872c02c1
commit 576e2bf833
2 changed files with 1186 additions and 1041 deletions
+143 -89
View File
@@ -1,7 +1,7 @@
/* /*
* Copyright 2001-2007, Haiku Inc. All Rights Reserved. * Copyright 2001-2008, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef __BSTRING__ #ifndef __BSTRING__
#define __BSTRING__ #define __BSTRING__
@@ -11,8 +11,12 @@
#include <string.h> #include <string.h>
class BString { class BStringRef;
public:
class BString
{
public:
BString(); BString();
BString(const char* string); BString(const char* string);
BString(const BString& string); BString(const BString& string);
@@ -21,11 +25,9 @@ class BString {
// Access // Access
const char* String() const; const char* String() const;
int32 Length() const; int32 Length() const;
// length of corresponding string
int32 CountChars() const; int32 CountChars() const;
// returns number of UTF8 characters in string int32 ReferenceCount() const;
// Assignment // Assignment
BString& operator=(const BString& string); BString& operator=(const BString& string);
@@ -44,10 +46,8 @@ class BString {
BString& SetTo(char c, int32 count); BString& SetTo(char c, int32 count);
// Substring copying // Substring copying
BString& CopyInto(BString& into, int32 fromOffset, BString& CopyInto(BString& into, int32 fromOffset, int32 length) const;
int32 length) const; void CopyInto(char* into, int32 fromOffset, int32 length) const;
void CopyInto(char* into, int32 fromOffset,
int32 length) const;
// Appending // Appending
BString& operator+=(const BString& string); BString& operator+=(const BString& string);
@@ -69,16 +69,15 @@ class BString {
BString& Prepend(char c, int32 count); BString& Prepend(char c, int32 count);
// Inserting // Inserting
BString& Insert(const char* string, int32 pos); BString& Insert(const char* string, int32 position);
BString& Insert(const char* string, int32 length, int32 pos); BString& Insert(const char* string, int32 length, int32 position);
BString& Insert(const char* string, int32 fromOffset, BString& Insert(const char* string, int32 fromOffset, int32 length,
int32 length, int32 pos); int32 position);
BString& Insert(const BString& string, int32 position);
BString& Insert(const BString& string, int32 pos); BString& Insert(const BString& string, int32 length, int32 position);
BString& Insert(const BString& string, int32 length, int32 pos); BString& Insert(const BString& string, int32 fromOffset, int32 length,
BString& Insert(const BString& string, int32 fromOffset, int32 position);
int32 length, int32 pos); BString& Insert(char c, int32 count, int32 position);
BString& Insert(char, int32 count, int32 pos);
// Removing // Removing
BString& Truncate(int32 newLength, bool lazy = true); BString& Truncate(int32 newLength, bool lazy = true);
@@ -150,40 +149,39 @@ class BString {
// Replacing // Replacing
BString& ReplaceFirst(char replaceThis, char withThis); BString& ReplaceFirst(char replaceThis, char withThis);
BString& ReplaceLast(char replaceThis, char withThis); BString& ReplaceLast(char replaceThis, char withThis);
BString& ReplaceAll(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); 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, BString& Replace(const char* replaceThis, const char* withThis,
int32 maxReplaceCount, int32 fromOffset = 0); int32 maxReplaceCount, int32 fromOffset = 0);
BString& IReplaceFirst(char replaceThis, char withThis); BString& IReplaceFirst(char replaceThis, char withThis);
BString& IReplaceLast(char replaceThis, char withThis); BString& IReplaceLast(char replaceThis, char withThis);
BString& IReplaceAll(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); 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, BString& IReplace(const char* replaceThis, const char* withThis,
int32 maxReplaceCount, int32 fromOffset = 0); int32 maxReplaceCount, int32 fromOffset = 0);
BString& ReplaceSet(const char* setOfChars, char with); BString& ReplaceSet(const char* setOfChars, char with);
BString& ReplaceSet(const char* setOfChars, const char *with); BString& ReplaceSet(const char* setOfChars, const char* with);
// Unchecked char access // Unchecked char access
char operator[](int32 index) const; char operator[](int32 index) const;
#if __GNUC__ > 3
BStringRef operator[](int32 index);
#else
char& operator[](int32 index); char& operator[](int32 index);
#endif
// Checked char access // Checked char access
char ByteAt(int32 index) const; char ByteAt(int32 index) const;
@@ -200,15 +198,13 @@ class BString {
BString& CapitalizeEachWord(); BString& CapitalizeEachWord();
// Escaping and De-escaping // Escaping and De-escaping
BString& CharacterEscape(const char* original, BString& CharacterEscape(const char* original, const char* setOfCharsToEscape,
const char* setOfCharsToEscape, char escapeWith);
BString& CharacterEscape(const char* setOfCharsToEscape,
char escapeWith); char escapeWith);
BString& CharacterEscape(const char* setOfCharsToEscape, char escapeWith);
BString& CharacterDeescape(const char* original, char escapeChar); BString& CharacterDeescape(const char* original, char escapeChar);
BString& CharacterDeescape(char escapeChar); BString& CharacterDeescape(char escapeChar);
// Slower than sprintf() but type and overflow safe // Insert
BString& operator<<(const char* string); BString& operator<<(const char* string);
BString& operator<<(const BString& string); BString& operator<<(const BString& string);
BString& operator<<(char c); BString& operator<<(char c);
@@ -218,45 +214,53 @@ class BString {
BString& operator<<(int32 value); BString& operator<<(int32 value);
BString& operator<<(uint64 value); BString& operator<<(uint64 value);
BString& operator<<(int64 value); BString& operator<<(int64 value);
BString& operator<<(float value);
// float output hardcodes %.2f style formatting // float output hardcodes %.2f style formatting
BString& operator<<(float value);
private: 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;
BString& _DoReplace(const char *, const char *, int32, int32,
bool);
void _SetLength(int32);
#if DEBUG
void _SetUsingAsCString(bool);
void _AssertNotUsingAsCString() const;
#else
void _SetUsingAsCString(bool) {}
void _AssertNotUsingAsCString() const {}
#endif
char* _Alloc(int32 size);
class PosVect; class PosVect;
void _ReplaceAtPositions(const PosVect* positions, friend class BStringRef;
int32 searchLength, const char* with, int32 withLen);
protected: // Management
status_t _Detach();
char* _Realloc(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);
status_t _DetachWith(const char* string, int32 length);
// Data
void _SetLength(int32 length);
void _SetReferenceCount(int32 count);
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 len) const;
int32 _FindAfter(const char* string, int32 offset, int32 strlen) const;
int32 _IFindAfter(const char* string, int32 offset, int32 strlen) const;
int32 _FindBefore(const char* string, int32 offset, int32 strlen) const;
int32 _IFindBefore(const char* string, int32 offset, int32 strlen) 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 searchLen,
const char* with, int32 withLen);
private:
char* fPrivateData; char* fPrivateData;
}; };
// Commutative compare operators // 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);
@@ -265,6 +269,7 @@ 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. // Non-member compare for sorting, etc.
int Compare(const BString& a, const BString& b); int Compare(const BString& a, const BString& b);
int ICompare(const BString& a, const BString& b); int ICompare(const BString& a, const BString& b);
@@ -275,13 +280,13 @@ int ICompare(const BString* a, const BString* b);
inline int32 inline int32
BString::Length() const BString::Length() const
{ {
return fPrivateData ? (*((int32 *)fPrivateData - 1) & 0x7fffffff) : 0; // the most significant bit is reserved; accessing
/* the most significant bit is reserved; accessing // it in any way will cause the computer to explode
* it in any way will cause the computer to explode return fPrivateData ? (*(((int32 *)fPrivateData) - 1) & 0x7fffffff) : 0;
*/
} }
inline const char *
inline const char*
BString::String() const BString::String() const
{ {
if (!fPrivateData) if (!fPrivateData)
@@ -289,18 +294,28 @@ BString::String() const
return fPrivateData; return fPrivateData;
} }
inline int32
BString::ReferenceCount() const
{
return fPrivateData ? (*(((int32 *)fPrivateData) - 2)) : 1;
}
inline BString & inline BString &
BString::SetTo(const char *string) BString::SetTo(const char* string)
{ {
return operator=(string); return operator=(string);
} }
inline char inline char
BString::operator[](int32 index) const BString::operator[](int32 index) const
{ {
return fPrivateData[index]; return fPrivateData[index];
} }
inline char inline char
BString::ByteAt(int32 index) const BString::ByteAt(int32 index) const
{ {
@@ -309,6 +324,7 @@ BString::ByteAt(int32 index) const
return fPrivateData[index]; return fPrivateData[index];
} }
inline BString & inline BString &
BString::operator+=(const BString &string) BString::operator+=(const BString &string)
{ {
@@ -316,6 +332,7 @@ BString::operator+=(const BString &string)
return *this; return *this;
} }
inline BString & inline BString &
BString::Append(const BString &string) BString::Append(const BString &string)
{ {
@@ -323,88 +340,125 @@ BString::Append(const BString &string)
return *this; return *this;
} }
inline BString & inline BString &
BString::Append(const char *str) BString::Append(const char* string)
{ {
return operator+=(str); return operator+=(string);
} }
inline bool inline bool
BString::operator==(const BString &string) const BString::operator==(const BString &string) const
{ {
return strcmp(String(), string.String()) == 0; return strcmp(String(), string.String()) == 0;
} }
inline bool inline bool
BString::operator<(const BString &string) const BString::operator<(const BString &string) const
{ {
return strcmp(String(), string.String()) < 0; return strcmp(String(), string.String()) < 0;
} }
inline bool inline bool
BString::operator<=(const BString &string) const BString::operator<=(const BString &string) const
{ {
return strcmp(String(), string.String()) <= 0; return strcmp(String(), string.String()) <= 0;
} }
inline bool inline bool
BString::operator>=(const BString &string) const BString::operator>=(const BString &string) const
{ {
return strcmp(String(), string.String()) >= 0; return strcmp(String(), string.String()) >= 0;
} }
inline bool inline bool
BString::operator>(const BString &string) const BString::operator>(const BString &string) const
{ {
return strcmp(String(), string.String()) > 0; return strcmp(String(), string.String()) > 0;
} }
inline bool inline bool
BString::operator!=(const BString &string) const BString::operator!=(const BString &string) const
{ {
return strcmp(String(), string.String()) != 0; return strcmp(String(), string.String()) != 0;
} }
inline bool inline bool
BString::operator!=(const char *str) const BString::operator!=(const char* string) const
{ {
return !operator==(str); return !operator==(string);
} }
inline bool inline bool
operator<(const char *str, const BString &string) operator<(const char *str, const BString &string)
{ {
return string > str; return string > str;
} }
inline bool inline bool
operator<=(const char *str, const BString &string) operator<=(const char *str, const BString &string)
{ {
return string >= str; return string >= str;
} }
inline bool inline bool
operator==(const char *str, const BString &string) operator==(const char *str, const BString &string)
{ {
return string == str; return string == str;
} }
inline bool inline bool
operator>(const char *str, const BString &string) operator>(const char *str, const BString &string)
{ {
return string < str; return string < str;
} }
inline bool inline bool
operator>=(const char *str, const BString &string) operator>=(const char *str, const BString &string)
{ {
return string <= str; return string <= str;
} }
inline bool inline bool
operator!=(const char *str, const BString &string) operator!=(const char *str, const BString &string)
{ {
return string != str; return string != str;
} }
#endif /* __BSTRING__ */
// #pragma mark - BStringRef
class BStringRef
{
public:
BStringRef(BString& string, int32 position);
~BStringRef() {}
operator char() const;
char* operator&();
const char* operator&() const;
BStringRef& operator=(char c);
BStringRef &operator=(const BStringRef &rc);
private:
BString& fString;
int32 fPosition;
};
#endif // __BSTRING__
File diff suppressed because it is too large Load Diff