BString::Private class to access BString internals

This commit is contained in:
Ingo Weinhold 2011-07-16 15:59:49 +02:00
parent 10e1bc5267
commit d0c417848b
5 changed files with 106 additions and 23 deletions

View File

@ -0,0 +1 @@
#include <../private/support/StringPrivate.h>

View File

@ -321,9 +321,20 @@ public:
BString& operator<<(float value);
BString& operator<<(double value);
public:
class Private;
friend class Private;
private:
class PosVect;
friend class BStringRef;
class PosVect;
friend class BStringRef;
enum PrivateDataTag {
PRIVATE_DATA
};
private:
BString(char* privateData, PrivateDataTag tag);
// Management
status_t _MakeWritable();

View File

@ -0,0 +1,75 @@
/*
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _SUPPORT_BSTRING_PRIVATE_H_
#define _SUPPORT_BSTRING_PRIVATE_H_
#include <stdlib.h>
#include <String.h>
class BString::Private {
public:
static const uint32 kPrivateDataOffset = 2 * sizeof(int32);
public:
Private(const BString& string)
:
fString(string)
{
}
char* Data()
{
return fString.fPrivateData;
}
static vint32& DataRefCount(char* data)
{
return *(((int32 *)data) - 2);
}
vint32& DataRefCount()
{
return DataRefCount(Data());
}
static int32& DataLength(char* data)
{
return *(((int32*)data) - 1);
}
int32& DataLength()
{
return DataLength(Data());
}
static void IncrementDataRefCount(char* data)
{
if (data != NULL)
atomic_add(&DataRefCount(data), 1);
}
static void DecrementDataRefCount(char* data)
{
if (data != NULL) {
if (atomic_add(&DataRefCount(data), -1) == 1)
free(data - kPrivateDataOffset);
}
}
static BString StringFromData(char* data)
{
return BString(data, BString::PRIVATE_DATA);
}
private:
const BString& fString;
};
#endif // _SUPPORT_BSTRING_PRIVATE_H_

View File

@ -1,6 +1,6 @@
SubDir HAIKU_TOP src build libbe support ;
UsePrivateBuildHeaders app interface shared ;
UsePrivateBuildHeaders app interface shared support ;
USES_BE_API on <libbe_build>support_kit.o = true ;

View File

@ -23,6 +23,7 @@
#include <Debug.h>
#include <StringPrivate.h>
#include <utf8_functions.h>
@ -34,7 +35,7 @@
#define REPLACE_ALL 0x7FFFFFFF
const uint32 kPrivateDataOffset = 2 * sizeof(int32);
static const uint32 kPrivateDataOffset = BString::Private::kPrivateDataOffset;
const char* B_EMPTY_STRING = "";
@ -79,20 +80,6 @@ safestr(const char* str)
}
static inline vint32&
data_reference_count(char* data)
{
return *(((int32 *)data) - 2);
}
static inline int32&
data_length(char* data)
{
return *(((int32*)data) - 1);
}
// #pragma mark - PosVect
@ -202,14 +189,14 @@ BStringRef::operator&()
inline vint32&
BString::_ReferenceCount()
{
return data_reference_count(fPrivateData);
return Private::DataRefCount(fPrivateData);
}
inline const vint32&
BString::_ReferenceCount() const
{
return data_reference_count(fPrivateData);
return Private::DataRefCount(fPrivateData);
}
@ -2148,6 +2135,15 @@ BString::operator<<(double value)
// #pragma mark - Private or reserved
BString::BString(char* privateData, PrivateDataTag tag)
:
fPrivateData(privateData)
{
if (fPrivateData != NULL)
atomic_add(&_ReferenceCount(), 1);
}
/*! Detaches this string from an eventually shared fPrivateData, ie. this makes
this string writable.
*/
@ -2226,8 +2222,8 @@ BString::_Allocate(int32 length)
newData[length] = '\0';
// initialize reference count & length
data_reference_count(newData) = 1;
data_length(newData) = length & 0x7fffffff;
Private::DataRefCount(newData) = 1;
Private::DataLength(newData) = length & 0x7fffffff;
return newData;
}
@ -2319,7 +2315,7 @@ BString::_ShrinkAtBy(int32 offset, int32 length)
void
BString::_SetLength(int32 length)
{
data_length(fPrivateData) = length & 0x7fffffff;
Private::DataLength(fPrivateData) = length & 0x7fffffff;
}