Adding utf-8 aware version of most functions to BString. They are named after
the corresponding normal functions but have a "Chars" in the name like "MoveCharsInto" or "AppendChars". Also added CountBytes() and CharAt(). This should make everyday string handling with multibyte strings a bit easier. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35371 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2009, Haiku Inc. All Rights Reserved.
|
||||
* Copyright 2001-2010, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef __BSTRING__
|
||||
@@ -26,6 +26,8 @@ public:
|
||||
const char* String() const;
|
||||
int32 Length() const;
|
||||
int32 CountChars() const;
|
||||
int32 CountBytes(int32 fromCharOffset,
|
||||
int32 charCount) const;
|
||||
|
||||
// Assignment
|
||||
BString& operator=(const BString& string);
|
||||
@@ -43,12 +45,21 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
|
||||
// Appending
|
||||
BString& operator+=(const BString& string);
|
||||
BString& operator+=(const char* string);
|
||||
@@ -61,6 +72,9 @@ public:
|
||||
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);
|
||||
@@ -68,6 +82,10 @@ public:
|
||||
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,
|
||||
@@ -81,9 +99,26 @@ public:
|
||||
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);
|
||||
@@ -93,11 +128,17 @@ public:
|
||||
BString& RemoveLast(const char* string);
|
||||
BString& RemoveAll(const char* string);
|
||||
|
||||
BString& RemoveSet(const char* setOfCharsToRemove);
|
||||
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;
|
||||
@@ -120,6 +161,12 @@ public:
|
||||
int Compare(const char* string) const;
|
||||
int Compare(const BString& string, int32 length) const;
|
||||
int Compare(const char* 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;
|
||||
@@ -135,6 +182,11 @@ public:
|
||||
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,
|
||||
@@ -144,6 +196,11 @@ public:
|
||||
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,
|
||||
@@ -175,6 +232,12 @@ public:
|
||||
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,
|
||||
@@ -191,8 +254,12 @@ public:
|
||||
const char* withThis, int32 maxReplaceCount,
|
||||
int32 fromOffset = 0);
|
||||
|
||||
BString& ReplaceSet(const char* setOfChars, char with);
|
||||
BString& ReplaceSet(const char* setOfChars, const char* with);
|
||||
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;
|
||||
@@ -205,6 +272,9 @@ public:
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -2,7 +2,7 @@ SubDir HAIKU_TOP src kits support ;
|
||||
|
||||
SetSubDirSupportedPlatforms haiku libbe_test ;
|
||||
|
||||
UsePrivateHeaders shared app media support ;
|
||||
UsePrivateHeaders app interface media shared support ;
|
||||
|
||||
MergeObject <libbe>support_kit.o :
|
||||
Archivable.cpp
|
||||
|
||||
+330
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2010, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -8,6 +8,7 @@
|
||||
* Oliver Tappe ([email protected])
|
||||
* Axel Dörfler, [email protected]
|
||||
* Julun <[email protected]>
|
||||
* Michael Lotz <[email protected]>
|
||||
*/
|
||||
|
||||
|
||||
@@ -23,6 +24,8 @@
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
#include <utf8_functions.h>
|
||||
|
||||
|
||||
// define proper names for case-option of _DoReplace()
|
||||
#define KEEP_CASE false
|
||||
@@ -268,19 +271,15 @@ BString::~BString()
|
||||
int32
|
||||
BString::CountChars() const
|
||||
{
|
||||
int32 count = 0;
|
||||
return UTF8CountChars(fPrivateData, Length());
|
||||
}
|
||||
|
||||
const char* start = fPrivateData;
|
||||
const char* end = fPrivateData + Length();
|
||||
|
||||
while (start++ != end) {
|
||||
count++;
|
||||
|
||||
// Jump to next UTF8 character
|
||||
for (; (*start & 0xc0) == 0x80; start++);
|
||||
}
|
||||
|
||||
return count;
|
||||
int32
|
||||
BString::CountBytes(int32 fromCharOffset, int32 charCount) const
|
||||
{
|
||||
return UTF8CountBytes(
|
||||
fPrivateData + UTF8CountBytes(fPrivateData, fromCharOffset), charCount);
|
||||
}
|
||||
|
||||
|
||||
@@ -404,6 +403,27 @@ BString::SetTo(char c, int32 count)
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::SetToChars(const char* string, int32 charCount)
|
||||
{
|
||||
return SetTo(string, UTF8CountBytes(string, charCount));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::SetToChars(const BString& string, int32 charCount)
|
||||
{
|
||||
return SetTo(string, UTF8CountBytes(string.String(), charCount));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::AdoptChars(BString& string, int32 charCount)
|
||||
{
|
||||
return Adopt(string, UTF8CountBytes(string.String(), charCount));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Substring copying
|
||||
|
||||
|
||||
@@ -426,6 +446,38 @@ BString::CopyInto(char* into, int32 fromOffset, int32 length) const
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::CopyCharsInto(BString& into, int32 fromCharOffset,
|
||||
int32 charCount) const
|
||||
{
|
||||
int32 fromOffset = UTF8CountBytes(fPrivateData, fromCharOffset);
|
||||
int32 length = UTF8CountBytes(fPrivateData + fromOffset, charCount);
|
||||
return CopyInto(into, fromOffset, length);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BString::CopyCharsInto(char* into, int32* intoLength, int32 fromCharOffset,
|
||||
int32 charCount) const
|
||||
{
|
||||
if (into == NULL)
|
||||
return false;
|
||||
|
||||
int32 fromOffset = UTF8CountBytes(fPrivateData, fromCharOffset);
|
||||
int32 length = UTF8CountBytes(fPrivateData + fromOffset, charCount);
|
||||
length = min_clamp0(length, Length() - fromOffset);
|
||||
|
||||
if (intoLength != NULL) {
|
||||
if (*intoLength < length)
|
||||
return false;
|
||||
*intoLength = length;
|
||||
}
|
||||
|
||||
memcpy(into, fPrivateData + fromOffset, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Appending
|
||||
|
||||
|
||||
@@ -483,6 +535,20 @@ BString::Append(char c, int32 count)
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::AppendChars(const BString& string, int32 charCount)
|
||||
{
|
||||
return Append(string, UTF8CountBytes(string.String(), charCount));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::AppendChars(const char* string, int32 charCount)
|
||||
{
|
||||
return Append(string, UTF8CountBytes(string, charCount));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Prepending
|
||||
|
||||
|
||||
@@ -531,6 +597,20 @@ BString::Prepend(char c, int32 count)
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::PrependChars(const char* string, int32 charCount)
|
||||
{
|
||||
return Prepend(string, UTF8CountBytes(string, charCount));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::PrependChars(const BString& string, int32 charCount)
|
||||
{
|
||||
return Prepend(string, UTF8CountBytes(string.String(), charCount));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Inserting
|
||||
|
||||
|
||||
@@ -626,6 +706,58 @@ BString::Insert(char c, int32 count, int32 position)
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::InsertChars(const char* string, int32 charPosition)
|
||||
{
|
||||
return Insert(string, UTF8CountBytes(fPrivateData, charPosition));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::InsertChars(const char* string, int32 charCount, int32 charPosition)
|
||||
{
|
||||
return Insert(string, UTF8CountBytes(string, charCount),
|
||||
UTF8CountBytes(fPrivateData, charPosition));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::InsertChars(const char* string, int32 fromCharOffset,
|
||||
int32 charCount, int32 charPosition)
|
||||
{
|
||||
int32 fromOffset = UTF8CountBytes(string, fromCharOffset);
|
||||
return Insert(string, fromOffset,
|
||||
UTF8CountBytes(string + fromOffset, charCount),
|
||||
UTF8CountBytes(fPrivateData, charPosition));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::InsertChars(const BString& string, int32 charPosition)
|
||||
{
|
||||
return Insert(string, UTF8CountBytes(fPrivateData, charPosition));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::InsertChars(const BString& string, int32 charCount, int32 charPosition)
|
||||
{
|
||||
return Insert(string, UTF8CountBytes(string.String(), charCount),
|
||||
UTF8CountBytes(fPrivateData, charPosition));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::InsertChars(const BString& string, int32 fromCharOffset,
|
||||
int32 charCount, int32 charPosition)
|
||||
{
|
||||
int32 fromOffset = UTF8CountBytes(string.String(), fromCharOffset);
|
||||
return Insert(string, fromOffset,
|
||||
UTF8CountBytes(string.String() + fromOffset, charCount),
|
||||
UTF8CountBytes(fPrivateData, charPosition));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Removing
|
||||
|
||||
|
||||
@@ -644,6 +776,13 @@ BString::Truncate(int32 newLength, bool lazy)
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::TruncateChars(int32 newCharCount, bool lazy)
|
||||
{
|
||||
return Truncate(UTF8CountBytes(fPrivateData, newCharCount));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::Remove(int32 from, int32 length)
|
||||
{
|
||||
@@ -653,6 +792,15 @@ BString::Remove(int32 from, int32 length)
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::RemoveChars(int32 fromCharOffset, int32 charCount)
|
||||
{
|
||||
int32 fromOffset = UTF8CountBytes(fPrivateData, fromCharOffset);
|
||||
return Remove(fromOffset,
|
||||
UTF8CountBytes(fPrivateData + fromOffset, charCount));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::RemoveFirst(const BString& string)
|
||||
{
|
||||
@@ -729,9 +877,16 @@ BString::RemoveAll(const char* string)
|
||||
|
||||
|
||||
BString&
|
||||
BString::RemoveSet(const char* setOfCharsToRemove)
|
||||
BString::RemoveSet(const char* setOfBytesToRemove)
|
||||
{
|
||||
return ReplaceSet(setOfCharsToRemove, "");
|
||||
return ReplaceSet(setOfBytesToRemove, "");
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::RemoveCharsSet(const char* setOfCharsToRemove)
|
||||
{
|
||||
return ReplaceCharsSet(setOfCharsToRemove, "");
|
||||
}
|
||||
|
||||
|
||||
@@ -756,6 +911,30 @@ BString::MoveInto(char* into, int32 from, int32 length)
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::MoveCharsInto(BString& into, int32 fromCharOffset, int32 charCount)
|
||||
{
|
||||
if (charCount > 0) {
|
||||
CopyCharsInto(into, fromCharOffset, charCount);
|
||||
RemoveChars(fromCharOffset, charCount);
|
||||
}
|
||||
|
||||
return into;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BString::MoveCharsInto(char* into, int32* intoLength, int32 fromCharOffset,
|
||||
int32 charCount)
|
||||
{
|
||||
if (!CopyCharsInto(into, intoLength, fromCharOffset, charCount))
|
||||
return false;
|
||||
|
||||
RemoveChars(fromCharOffset, charCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Compare functions
|
||||
|
||||
|
||||
@@ -825,6 +1004,20 @@ BString::Compare(const char* string, int32 length) const
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BString::CompareChars(const BString& string, int32 charCount) const
|
||||
{
|
||||
return Compare(string, UTF8CountBytes(fPrivateData, charCount));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BString::CompareChars(const char* string, int32 charCount) const
|
||||
{
|
||||
return Compare(string, UTF8CountBytes(fPrivateData, charCount));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BString::ICompare(const BString& string) const
|
||||
{
|
||||
@@ -939,6 +1132,20 @@ BString::FindFirst(char c, int32 fromOffset) const
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BString::FindFirstChars(const BString& string, int32 fromCharOffset) const
|
||||
{
|
||||
return FindFirst(string, UTF8CountBytes(fPrivateData, fromCharOffset));
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BString::FindFirstChars(const char* string, int32 fromCharOffset) const
|
||||
{
|
||||
return FindFirst(string, UTF8CountBytes(fPrivateData, fromCharOffset));
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BString::FindLast(const BString& string) const
|
||||
{
|
||||
@@ -1022,6 +1229,20 @@ BString::FindLast(char c, int32 beforeOffset) const
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BString::FindLastChars(const BString& string, int32 beforeCharOffset) const
|
||||
{
|
||||
return FindLast(string, UTF8CountBytes(fPrivateData, beforeCharOffset));
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BString::FindLastChars(const char* string, int32 beforeCharOffset) const
|
||||
{
|
||||
return FindLast(string, UTF8CountBytes(fPrivateData, beforeCharOffset));
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BString::IFindFirst(const BString& string) const
|
||||
{
|
||||
@@ -1244,6 +1465,24 @@ BString::Replace(const char* replaceThis, const char* withThis,
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::ReplaceAllChars(const char* replaceThis, const char* withThis,
|
||||
int32 fromCharOffset)
|
||||
{
|
||||
return ReplaceAll(replaceThis, withThis,
|
||||
UTF8CountBytes(fPrivateData, fromCharOffset));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::ReplaceChars(const char* replaceThis, const char* withThis,
|
||||
int32 maxReplaceCount, int32 fromCharOffset)
|
||||
{
|
||||
return Replace(replaceThis, withThis, maxReplaceCount,
|
||||
UTF8CountBytes(fPrivateData, fromCharOffset));
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::IReplaceFirst(char replaceThis, char withThis)
|
||||
{
|
||||
@@ -1385,9 +1624,9 @@ BString::IReplace(const char* replaceThis, const char* withThis,
|
||||
|
||||
|
||||
BString&
|
||||
BString::ReplaceSet(const char* setOfChars, char with)
|
||||
BString::ReplaceSet(const char* setOfBytes, char with)
|
||||
{
|
||||
if (!setOfChars || strcspn(fPrivateData, setOfChars) >= uint32(Length()))
|
||||
if (!setOfBytes || strcspn(fPrivateData, setOfBytes) >= uint32(Length()))
|
||||
return *this;
|
||||
|
||||
if (_MakeWritable() != B_OK)
|
||||
@@ -1396,7 +1635,7 @@ BString::ReplaceSet(const char* setOfChars, char with)
|
||||
int32 offset = 0;
|
||||
int32 length = Length();
|
||||
for (int32 pos;;) {
|
||||
pos = strcspn(fPrivateData + offset, setOfChars);
|
||||
pos = strcspn(fPrivateData + offset, setOfBytes);
|
||||
|
||||
offset += pos;
|
||||
if (offset >= length)
|
||||
@@ -1411,16 +1650,16 @@ BString::ReplaceSet(const char* setOfChars, char with)
|
||||
|
||||
|
||||
BString&
|
||||
BString::ReplaceSet(const char* setOfChars, const char* with)
|
||||
BString::ReplaceSet(const char* setOfBytes, const char* with)
|
||||
{
|
||||
if (!setOfChars || !with
|
||||
|| strcspn(fPrivateData, setOfChars) >= uint32(Length()))
|
||||
if (!setOfBytes || !with
|
||||
|| strcspn(fPrivateData, setOfBytes) >= uint32(Length()))
|
||||
return *this;
|
||||
|
||||
// delegate simple case
|
||||
int32 withLen = strlen(with);
|
||||
if (withLen == 1)
|
||||
return ReplaceSet(setOfChars, *with);
|
||||
return ReplaceSet(setOfBytes, *with);
|
||||
|
||||
if (_MakeWritable() != B_OK)
|
||||
return *this;
|
||||
@@ -1431,7 +1670,7 @@ BString::ReplaceSet(const char* setOfChars, const char* with)
|
||||
|
||||
PosVect positions;
|
||||
for (int32 offset = 0; offset < len; offset += (pos + searchLen)) {
|
||||
pos = strcspn(fPrivateData + offset, setOfChars);
|
||||
pos = strcspn(fPrivateData + offset, setOfBytes);
|
||||
if (pos + offset >= len)
|
||||
break;
|
||||
if (!positions.Add(offset + pos))
|
||||
@@ -1443,6 +1682,49 @@ BString::ReplaceSet(const char* setOfChars, const char* with)
|
||||
}
|
||||
|
||||
|
||||
BString&
|
||||
BString::ReplaceCharsSet(const char* setOfChars, const char* with)
|
||||
{
|
||||
if (!setOfChars || !with)
|
||||
return *this;
|
||||
|
||||
int32 setCharCount = UTF8CountChars(setOfChars, -1);
|
||||
if ((uint32)setCharCount == strlen(setOfChars)) {
|
||||
// no multi-byte chars at all
|
||||
return ReplaceSet(setOfChars, with);
|
||||
}
|
||||
|
||||
BString setString(setOfChars);
|
||||
BString result;
|
||||
|
||||
int32 withLength = withLength;
|
||||
int32 charCount = CountChars();
|
||||
for (int32 i = 0; i < charCount; i++) {
|
||||
int32 charLength;
|
||||
const char* sourceChar = CharAt(i, &charLength);
|
||||
bool match = false;
|
||||
|
||||
for (int32 j = 0; j < setCharCount; j++) {
|
||||
int32 setCharLength;
|
||||
const char* setChar = setString.CharAt(j, &setCharLength);
|
||||
if (charLength == setCharLength
|
||||
&& memcmp(sourceChar, setChar, charLength) == 0) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match)
|
||||
result.Append(with, withLength);
|
||||
else
|
||||
result.Append(sourceChar, charLength);
|
||||
}
|
||||
|
||||
*this = result;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Unchecked char access
|
||||
|
||||
|
||||
@@ -1469,6 +1751,32 @@ BString::operator[](int32 index)
|
||||
#endif
|
||||
|
||||
|
||||
const char*
|
||||
BString::CharAt(int32 charIndex, int32* bytes) const
|
||||
{
|
||||
int32 offset = UTF8CountBytes(fPrivateData, charIndex);
|
||||
if (bytes != NULL)
|
||||
*bytes = UTF8NextCharLen(fPrivateData + offset);
|
||||
return fPrivateData + offset;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BString::CharAt(int32 charIndex, char* buffer, int32* bytes) const
|
||||
{
|
||||
int32 length;
|
||||
const char* charAt = CharAt(charIndex, &length);
|
||||
if (bytes != NULL) {
|
||||
if (*bytes < length)
|
||||
return false;
|
||||
*bytes = length;
|
||||
}
|
||||
|
||||
memcpy(buffer, charAt, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Fast low-level manipulation
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user