* As found by Karsten, the reference count was not initialized in
_ReplaceAtPositions(), and _DoCharacterEscape() (we don't need to preserve it, though, as it must be 1). * Factored out an _Alloc() method which is now always called when the private data is allocated. It also takes care of correct initialization (and thus fixes the above problem). * This fix finally allows turning on reference counting again, thanks Karsten! * Minor cleanup, renamed "oldAdr"/"newAdr" to "oldString", resp. "newString". git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24348 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -221,6 +221,7 @@ private:
|
|||||||
|
|
||||||
// Management
|
// Management
|
||||||
status_t _Detach();
|
status_t _Detach();
|
||||||
|
char* _Alloc(int32 length);
|
||||||
char* _Realloc(int32 length);
|
char* _Realloc(int32 length);
|
||||||
void _Init(const char* src, int32 length);
|
void _Init(const char* src, int32 length);
|
||||||
char* _Clone(const char* data, int32 length);
|
char* _Clone(const char* data, int32 length);
|
||||||
|
|||||||
+72
-64
@@ -1678,6 +1678,27 @@ BString::_Detach()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
BString::_Alloc(int32 length)
|
||||||
|
{
|
||||||
|
if (length < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char* newData = (char *)malloc(length + kPrivateDataOffset + 1);
|
||||||
|
if (newData == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
newData += kPrivateDataOffset;
|
||||||
|
newData[length] = '\0';
|
||||||
|
|
||||||
|
// initialize reference count & length
|
||||||
|
*(((vint32*)newData) - 2) = 1;
|
||||||
|
*(((int32*)newData) - 1) = length & 0x7fffffff;
|
||||||
|
|
||||||
|
return newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char*
|
char*
|
||||||
BString::_Realloc(int32 length)
|
BString::_Realloc(int32 length)
|
||||||
{
|
{
|
||||||
@@ -1713,18 +1734,11 @@ BString::_Init(const char* src, int32 length)
|
|||||||
char*
|
char*
|
||||||
BString::_Clone(const char* data, int32 length)
|
BString::_Clone(const char* data, int32 length)
|
||||||
{
|
{
|
||||||
char* newData = (char *)malloc(length + kPrivateDataOffset + 1);
|
char* newData = _Alloc(length);
|
||||||
if (newData == NULL)
|
if (newData == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
newData += kPrivateDataOffset;
|
if (data != NULL && length > 0) {
|
||||||
newData[length] = '\0';
|
|
||||||
|
|
||||||
// initialize reference count & length
|
|
||||||
*(((vint32*)newData) - 2) = 1;
|
|
||||||
*(((int32*)newData) - 1) = length & 0x7fffffff;
|
|
||||||
|
|
||||||
if (data && length) {
|
|
||||||
// "data" may not span over the whole length
|
// "data" may not span over the whole length
|
||||||
strncpy(newData, data, length);
|
strncpy(newData, data, length);
|
||||||
}
|
}
|
||||||
@@ -1808,8 +1822,7 @@ BString::_ReferenceCount() const
|
|||||||
inline bool
|
inline bool
|
||||||
BString::_IsShareable() const
|
BString::_IsShareable() const
|
||||||
{
|
{
|
||||||
return false;
|
return fPrivateData != NULL && _ReferenceCount() >= 0;
|
||||||
// return fPrivateData != NULL && _ReferenceCount() >= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1943,50 +1956,48 @@ BString::_DoCharacterEscape(const char* string, const char *setOfCharsToEscape,
|
|||||||
memcpy(fPrivateData, string, Length());
|
memcpy(fPrivateData, string, Length());
|
||||||
|
|
||||||
PosVect positions;
|
PosVect positions;
|
||||||
int32 len = Length();
|
int32 length = Length();
|
||||||
int32 pos = 0;
|
int32 pos = 0;
|
||||||
for (int32 offset = 0; offset < len; offset += pos + 1) {
|
for (int32 offset = 0; offset < length; offset += pos + 1) {
|
||||||
if ((pos = strcspn(fPrivateData + offset, setOfCharsToEscape)) < len - offset) {
|
if ((pos = strcspn(fPrivateData + offset, setOfCharsToEscape))
|
||||||
|
< length - offset) {
|
||||||
if (!positions.Add(offset + pos))
|
if (!positions.Add(offset + pos))
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 count = positions.CountItems();
|
uint32 count = positions.CountItems();
|
||||||
int32 newLength = len + count;
|
int32 newLength = length + count;
|
||||||
if (!newLength) {
|
if (!newLength) {
|
||||||
_Realloc(0);
|
_Realloc(0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 lastPos = 0;
|
char* newData = _Alloc(newLength);
|
||||||
char* oldAdr = fPrivateData;
|
|
||||||
|
|
||||||
char* newData = (char*)malloc(newLength + kPrivateDataOffset + 1);
|
|
||||||
if (newData) {
|
if (newData) {
|
||||||
newData += kPrivateDataOffset;
|
char* oldString = fPrivateData;
|
||||||
char* newAdr = newData;
|
char* newString = newData;
|
||||||
|
int32 lastPos = 0;
|
||||||
|
|
||||||
for (uint32 i = 0; i < count; ++i) {
|
for (uint32 i = 0; i < count; ++i) {
|
||||||
pos = positions.ItemAt(i);
|
pos = positions.ItemAt(i);
|
||||||
len = pos - lastPos;
|
length = pos - lastPos;
|
||||||
if (len > 0) {
|
if (length > 0) {
|
||||||
memcpy(newAdr, oldAdr, len);
|
memcpy(newString, oldString, length);
|
||||||
oldAdr += len;
|
oldString += length;
|
||||||
newAdr += len;
|
newString += length;
|
||||||
}
|
}
|
||||||
*newAdr++ = escapeChar;
|
*newString++ = escapeChar;
|
||||||
*newAdr++ = *oldAdr++;
|
*newString++ = *oldString++;
|
||||||
lastPos = pos + 1;
|
lastPos = pos + 1;
|
||||||
}
|
}
|
||||||
len = Length() + 1 - lastPos;
|
|
||||||
if (len > 0)
|
length = Length() + 1 - lastPos;
|
||||||
memcpy(newAdr, oldAdr, len);
|
if (length > 0)
|
||||||
|
memcpy(newString, oldString, length);
|
||||||
|
|
||||||
_FreePrivateData();
|
_FreePrivateData();
|
||||||
|
|
||||||
fPrivateData = newData;
|
fPrivateData = newData;
|
||||||
_SetLength(newLength);
|
|
||||||
fPrivateData[newLength] = '\0';
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -1999,8 +2010,8 @@ BString::_DoCharacterDeescape(const char* string, char escapeChar)
|
|||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
memcpy(fPrivateData, string, Length());
|
memcpy(fPrivateData, string, Length());
|
||||||
const char temp[2] = { escapeChar, '\0' };
|
const char escape[2] = { escapeChar, '\0' };
|
||||||
return _DoReplace(temp, "", REPLACE_ALL, 0, KEEP_CASE);
|
return _DoReplace(escape, "", REPLACE_ALL, 0, KEEP_CASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2035,48 +2046,45 @@ BString::_DoReplace(const char* findThis, const char* replaceWith,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BString::_ReplaceAtPositions(const PosVect* positions, int32 searchLen,
|
BString::_ReplaceAtPositions(const PosVect* positions, int32 searchLength,
|
||||||
const char* with, int32 withLen)
|
const char* with, int32 withLength)
|
||||||
{
|
{
|
||||||
int32 len = Length();
|
int32 length = Length();
|
||||||
uint32 count = positions->CountItems();
|
uint32 count = positions->CountItems();
|
||||||
int32 newLength = len + count * (withLen - searchLen);
|
int32 newLength = length + count * (withLength - searchLength);
|
||||||
if (!newLength) {
|
if (!newLength) {
|
||||||
_Realloc(0);
|
_Realloc(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 pos;
|
char *newData = _Alloc(newLength);
|
||||||
int32 lastPos = 0;
|
if (newData == NULL)
|
||||||
char *oldAdr = fPrivateData;
|
return;
|
||||||
|
|
||||||
|
char *oldString = fPrivateData;
|
||||||
|
char *newString = newData;
|
||||||
|
int32 lastPos = 0;
|
||||||
|
|
||||||
char *newData = (char *)malloc(newLength + kPrivateDataOffset + 1);
|
|
||||||
if (newData) {
|
|
||||||
newData += kPrivateDataOffset;
|
|
||||||
char *newAdr = newData;
|
|
||||||
for (uint32 i = 0; i < count; ++i) {
|
for (uint32 i = 0; i < count; ++i) {
|
||||||
pos = positions->ItemAt(i);
|
int32 pos = positions->ItemAt(i);
|
||||||
len = pos - lastPos;
|
length = pos - lastPos;
|
||||||
if (len > 0) {
|
if (length > 0) {
|
||||||
memcpy(newAdr, oldAdr, len);
|
memcpy(newString, oldString, length);
|
||||||
oldAdr += len;
|
oldString += length;
|
||||||
newAdr += len;
|
newString += length;
|
||||||
}
|
}
|
||||||
memcpy(newAdr, with, withLen);
|
memcpy(newString, with, withLength);
|
||||||
oldAdr += searchLen;
|
oldString += searchLength;
|
||||||
newAdr += withLen;
|
newString += withLength;
|
||||||
lastPos = pos+searchLen;
|
lastPos = pos + searchLength;
|
||||||
}
|
}
|
||||||
len = Length() + 1 - lastPos;
|
|
||||||
if (len > 0)
|
length = Length() + 1 - lastPos;
|
||||||
memcpy(newAdr, oldAdr, len);
|
if (length > 0)
|
||||||
|
memcpy(newString, oldString, length);
|
||||||
|
|
||||||
_FreePrivateData();
|
_FreePrivateData();
|
||||||
|
|
||||||
fPrivateData = newData;
|
fPrivateData = newData;
|
||||||
_SetLength(newLength);
|
|
||||||
fPrivateData[newLength] = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user