More optimization for Message2. It now uses a more lightweight BSimpleMallocIO instead of the full blown BMallocIO. This wastes less memory and reduces unnecessary overhead when unflattening.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13861 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2005-07-31 11:48:38 +00:00
parent 4835f2d292
commit 43abf8a345
7 changed files with 197 additions and 126 deletions
+4 -2
View File
@@ -43,7 +43,7 @@ public:
status_t Flatten(BDataIO *stream) const; status_t Flatten(BDataIO *stream) const;
status_t Unflatten(BDataIO *stream); status_t Unflatten(BDataIO *stream);
status_t AddData(const char *name, BMallocIO *buffer, status_t AddData(const char *name, BSimpleMallocIO *buffer,
type_code type); type_code type);
status_t RemoveData(const char *name, int32 index = 0); status_t RemoveData(const char *name, int32 index = 0);
@@ -52,7 +52,7 @@ public:
int32 index, const void **data, int32 index, const void **data,
ssize_t *numBytes) const; ssize_t *numBytes) const;
status_t ReplaceData(const char *name, int32 index, status_t ReplaceData(const char *name, int32 index,
BMallocIO *buffer, type_code type); BSimpleMallocIO *buffer, type_code type);
status_t Rename(const char *oldName, const char *newName); status_t Rename(const char *oldName, const char *newName);
status_t RemoveName(const char *name); status_t RemoveName(const char *name);
@@ -77,6 +77,8 @@ private:
BList fFieldList; BList fFieldList;
BMessageField **fFieldTable; BMessageField **fFieldTable;
int32 fFieldTableSize; int32 fFieldTableSize;
mutable ssize_t fFlattenedSize;
}; };
} // namespace BPrivate } // namespace BPrivate
+5 -4
View File
@@ -25,6 +25,8 @@
namespace BPrivate { namespace BPrivate {
class BSimpleMallocIO;
class BMessageField { class BMessageField {
public: public:
BMessageField(); BMessageField();
@@ -41,10 +43,9 @@ public:
uint8 NameLength() const { return fName.Length(); }; uint8 NameLength() const { return fName.Length(); };
type_code Type() const { return fType; }; type_code Type() const { return fType; };
void AddItem(BMallocIO *item); void AddItem(BSimpleMallocIO *item);
void ReplaceItem(int32 index, BMallocIO *item, void ReplaceItem(int32 index, BSimpleMallocIO *item);
bool deleteOld = true); void RemoveItem(int32 index);
void RemoveItem(int32 index, bool deleteIt = true);
int32 CountItems() const { return fItems.CountItems(); }; int32 CountItems() const { return fItems.CountItems(); };
size_t SizeAt(int32 index) const; size_t SizeAt(int32 index) const;
const void *BufferAt(int32 index) const; const void *BufferAt(int32 index) const;
+2 -3
View File
@@ -116,15 +116,14 @@ public:
if (fError < B_OK) if (fError < B_OK)
throw fError; throw fError;
if (IsSwapping()) { if (IsSwapping())
byte_swap(data); byte_swap(data);
}
} }
template<class T> template<class T>
inline void operator()(T data, size_t len) inline void operator()(T data, size_t len)
{ {
fError = fStream->Read((void*)data, len); fError = fStream->Read((void *)data, len);
if (fError < B_OK) if (fError < B_OK)
throw fError; throw fError;
} }
+88
View File
@@ -0,0 +1,88 @@
/*
* Copyright 2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <[email protected]>
*/
/* A BMallocIO similar structure but with less overhead */
#ifndef _SIMPLE_MALLOC_IO_H_
#define _SIMPLE_MALLOC_IO_H_
#include <malloc.h>
namespace BPrivate {
class BSimpleMallocIO {
public:
BSimpleMallocIO(size_t size)
: fSize(size)
{
fBuffer = (char *)malloc(size);
}
~BSimpleMallocIO()
{
free(fBuffer);
}
void Read(void *buffer)
{
memcpy(buffer, fBuffer, fSize);
}
void Read(void *buffer, size_t size)
{
memcpy(buffer, fBuffer, size);
}
void ReadAt(off_t pos, void *buffer, size_t size)
{
memcpy(buffer, fBuffer + pos, size);
}
void Write(const void *buffer)
{
memcpy(fBuffer, buffer, fSize);
}
void Write(const void *buffer, size_t size)
{
memcpy(fBuffer, buffer, size);
}
void WriteAt(off_t pos, const void *buffer, size_t size)
{
memcpy(fBuffer + pos, buffer, size);
}
status_t SetSize(off_t size)
{
fBuffer = (char *)realloc(fBuffer, size);
if (!fBuffer)
return B_NO_MEMORY;
fSize = size;
return B_OK;
}
char *Buffer()
{
return fBuffer;
}
size_t BufferLength()
{
return fSize;
}
private:
char *fBuffer;
size_t fSize;
};
} // namespace BPivate
#endif // _SIMPLE_MALLOC_IO_H_
+32 -35
View File
@@ -34,11 +34,12 @@
#include <AppMisc.h> #include <AppMisc.h>
#include <KMessage.h> #include <KMessage.h>
#include <MessageUtils2.h>
#include <TokenSpace.h> #include <TokenSpace.h>
#include "MessageBody2.h" #include "MessageBody2.h"
#include "MessageField2.h" #include "MessageField2.h"
#include "MessageUtils2.h"
#include "SimpleMallocIO.h"
#include "dano_message.h" #include "dano_message.h"
// flags for the overall message (the bitfield is 1 byte) // flags for the overall message (the bitfield is 1 byte)
@@ -873,9 +874,6 @@ BMessage::Unflatten(BDataIO *stream)
header.WriteTo(*this); header.WriteTo(*this);
status = fBody->Unflatten(stream); status = fBody->Unflatten(stream);
if (status < B_OK)
return status;
} catch (status_t &error) { } catch (status_t &error) {
status = error; status = error;
} }
@@ -1152,11 +1150,9 @@ BMessage::AddMessenger(const char *name, BMessenger messenger)
status_t status_t
BMessage::AddRef(const char* name, const entry_ref* ref) BMessage::AddRef(const char* name, const entry_ref* ref)
{ {
BMallocIO *buffer = new BMallocIO(); size_t size = sizeof(entry_ref) + B_PATH_NAME_LENGTH;
buffer->SetSize(sizeof(entry_ref) + B_PATH_NAME_LENGTH); BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
status_t error = entry_ref_flatten(buffer->Buffer(), &size, ref);
size_t size;
status_t error = entry_ref_flatten((char *)buffer->Buffer(), &size, ref);
buffer->SetSize(size); buffer->SetSize(size);
if (error >= B_OK) if (error >= B_OK)
@@ -1172,8 +1168,9 @@ BMessage::AddRef(const char* name, const entry_ref* ref)
status_t status_t
BMessage::AddMessage(const char *name, const BMessage *msg) BMessage::AddMessage(const char *name, const BMessage *msg)
{ {
BMallocIO *buffer = new BMallocIO(); size_t size = msg->FlattenedSize();
status_t error = msg->Flatten(buffer); BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
status_t error = msg->Flatten(buffer->Buffer(), size);
if (error >= B_OK) if (error >= B_OK)
error = fBody->AddData(name, buffer, B_MESSAGE_TYPE); error = fBody->AddData(name, buffer, B_MESSAGE_TYPE);
@@ -1189,10 +1186,9 @@ status_t
BMessage::AddFlat(const char *name, BFlattenable *object, int32 count) BMessage::AddFlat(const char *name, BFlattenable *object, int32 count)
{ {
ssize_t size = object->FlattenedSize(); ssize_t size = object->FlattenedSize();
BMallocIO *buffer = new BMallocIO(); BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
buffer->SetSize(size); status_t error = object->Flatten(buffer->Buffer(), size);
status_t error = object->Flatten((void *)buffer->Buffer(), size);
if (error >= B_OK) if (error >= B_OK)
error = fBody->AddData(name, buffer, object->TypeCode()); error = fBody->AddData(name, buffer, object->TypeCode());
@@ -1212,8 +1208,8 @@ BMessage::AddData(const char *name, type_code type, const void *data,
// the user attempts to add something bigger or smaller. We may need to // the user attempts to add something bigger or smaller. We may need to
// enforce the size thing. // enforce the size thing.
BMallocIO *buffer = new BMallocIO(); BSimpleMallocIO *buffer = new BSimpleMallocIO(numBytes);
buffer->Write(data, numBytes); buffer->Write(data);
status_t error = fBody->AddData(name, buffer, type); status_t error = fBody->AddData(name, buffer, type);
if (error < B_OK) if (error < B_OK)
@@ -1364,7 +1360,7 @@ BMessage::FindMessage(const char *name, int32 index, BMessage *msg) const
status_t error = FindData(name, B_MESSAGE_TYPE, index, (const void **)&data, &size); status_t error = FindData(name, B_MESSAGE_TYPE, index, (const void **)&data, &size);
if (!error) if (!error)
error = msg->Unflatten((const char*)data); error = msg->Unflatten((const char *)data);
else else
*msg = BMessage(); *msg = BMessage();
@@ -1493,11 +1489,9 @@ BMessage::ReplaceRef(const char *name, const entry_ref *ref)
status_t status_t
BMessage::ReplaceRef(const char *name, int32 index, const entry_ref *ref) BMessage::ReplaceRef(const char *name, int32 index, const entry_ref *ref)
{ {
BMallocIO *buffer = new BMallocIO(); size_t size = sizeof(entry_ref) + B_PATH_NAME_LENGTH;
buffer->SetSize(sizeof(entry_ref) + B_PATH_NAME_LENGTH); BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
status_t error = entry_ref_flatten(buffer->Buffer(), &size, ref);
size_t size;
status_t error = entry_ref_flatten((char *)buffer->Buffer(), &size, ref);
buffer->SetSize(size); buffer->SetSize(size);
if (error >= B_OK) if (error >= B_OK)
@@ -1520,8 +1514,9 @@ BMessage::ReplaceMessage(const char *name, const BMessage *msg)
status_t status_t
BMessage::ReplaceMessage(const char *name, int32 index, const BMessage *msg) BMessage::ReplaceMessage(const char *name, int32 index, const BMessage *msg)
{ {
BMallocIO *buffer = new BMallocIO(); size_t size = msg->FlattenedSize();
status_t error = msg->Flatten(buffer); BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
status_t error = msg->Flatten(buffer->Buffer(), size);
if (error >= B_OK) if (error >= B_OK)
error = fBody->ReplaceData(name, index, buffer, B_MESSAGE_TYPE); error = fBody->ReplaceData(name, index, buffer, B_MESSAGE_TYPE);
@@ -1544,10 +1539,9 @@ status_t
BMessage::ReplaceFlat(const char *name, int32 index, BFlattenable *object) BMessage::ReplaceFlat(const char *name, int32 index, BFlattenable *object)
{ {
ssize_t size = object->FlattenedSize(); ssize_t size = object->FlattenedSize();
BMallocIO *buffer = new BMallocIO(); BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
buffer->SetSize(size); status_t error = object->Flatten(buffer->Buffer(), size);
status_t error = object->Flatten((void *)buffer->Buffer(), size);
if (error >= B_OK) if (error >= B_OK)
error = fBody->ReplaceData(name, index, buffer, object->TypeCode()); error = fBody->ReplaceData(name, index, buffer, object->TypeCode());
@@ -1570,8 +1564,8 @@ status_t
BMessage::ReplaceData(const char *name, type_code type, int32 index, BMessage::ReplaceData(const char *name, type_code type, int32 index,
const void *data, ssize_t data_size) const void *data, ssize_t data_size)
{ {
BMallocIO *buffer = new BMallocIO(); BSimpleMallocIO *buffer = new BSimpleMallocIO(data_size);
buffer->Write(data, data_size); buffer->Write(data);
status_t error = fBody->ReplaceData(name, index, buffer, type); status_t error = fBody->ReplaceData(name, index, buffer, type);
if (error < B_OK) if (error < B_OK)
@@ -1629,7 +1623,7 @@ BMessage::operator delete(void *ptr, size_t size)
status_t status_t
BMessage::real_flatten(char *result, ssize_t size) const BMessage::real_flatten(char *result, ssize_t size) const
{ {
BMemoryIO stream((void*)result, size); BMemoryIO stream((void *)result, size);
return real_flatten(&stream, NULL); return real_flatten(&stream, NULL);
} }
@@ -1640,9 +1634,12 @@ BMessage::real_flatten(BDataIO *stream, ssize_t *size) const
Header header(*this); Header header(*this);
status_t error = header.WriteTo(*stream); status_t error = header.WriteTo(*stream);
if (!error) if (error >= B_OK)
error = fBody->Flatten(stream); error = fBody->Flatten(stream);
if (size)
*size = FlattenedSize();
return error; return error;
} }
@@ -1686,14 +1683,14 @@ BMessage::calc_hdr_size(uchar flags) const
ssize_t size = min_hdr_size(); ssize_t size = min_hdr_size();
if (fTarget != B_NULL_TOKEN) if (fTarget != B_NULL_TOKEN)
size += sizeof (fTarget); size += sizeof(fTarget);
if (fReplyTo.port >= 0 if (fReplyTo.port >= 0
&& fReplyTo.target != B_NULL_TOKEN && fReplyTo.target != B_NULL_TOKEN
&& fReplyTo.team >= 0) { && fReplyTo.team >= 0) {
size += sizeof (fReplyTo.port); size += sizeof(fReplyTo.port);
size += sizeof (fReplyTo.target); size += sizeof(fReplyTo.target);
size += sizeof (fReplyTo.team); size += sizeof(fReplyTo.team);
size += 4; // For the "big" flags size += 4; // For the "big" flags
} }
+43 -50
View File
@@ -9,14 +9,17 @@
/* BMessageBody handles data storage and retrieval for BMessage. */ /* BMessageBody handles data storage and retrieval for BMessage. */
#include <stdio.h> #include <stdio.h>
#include <DataIO.h>
#include <MessageUtils.h>
#include <TypeConstants.h> #include <TypeConstants.h>
#include "MessageBody2.h" #include "MessageBody2.h"
#include "MessageUtils2.h"
#include "SimpleMallocIO.h"
namespace BPrivate { namespace BPrivate {
static int64 sPadding[2] = { 0, 0 }; static int64 sPadding[2] = { 0, 0 };
static uint8 sPadLengths[8] = { 4, 3, 2, 1, 0, 7, 6, 5 };
#define CALC_PADDING_8(x) sPadLengths[x % 8]
BMessageBody::BMessageBody() BMessageBody::BMessageBody()
{ {
@@ -59,6 +62,7 @@ BMessageBody::operator=(const BMessageBody &other)
status_t status_t
BMessageBody::InitCommon() BMessageBody::InitCommon()
{ {
fFlattenedSize = -1;
fFieldTableSize = 100; fFieldTableSize = 100;
fFieldTable = new BMessageField *[fFieldTableSize]; fFieldTable = new BMessageField *[fFieldTableSize];
HashClear(); HashClear();
@@ -201,6 +205,7 @@ BMessageBody::Rename(const char *oldName, const char *newName)
field->SetName(newName); field->SetName(newName);
HashInsert(HashRemove(oldName)); HashInsert(HashRemove(oldName));
fFlattenedSize = -1;
return B_OK; return B_OK;
} }
@@ -208,6 +213,9 @@ BMessageBody::Rename(const char *oldName, const char *newName)
ssize_t ssize_t
BMessageBody::FlattenedSize() const BMessageBody::FlattenedSize() const
{ {
if (fFlattenedSize > 0)
return fFlattenedSize;
ssize_t size = 1; // for MSG_LAST_ENTRY ssize_t size = 1; // for MSG_LAST_ENTRY
for (int32 index = 0; index < fFieldList.CountItems(); index++) { for (int32 index = 0; index < fFieldList.CountItems(); index++) {
@@ -233,15 +241,12 @@ BMessageBody::FlattenedSize() const
// name length byte and name length // name length byte and name length
size += 1 + field->NameLength(); size += 1 + field->NameLength();
// individual sizes
if (!(flags & MSG_FLAG_FIXED_SIZE)) {
size += field->CountItems() * sizeof(size_t);
size += field->TotalPadding();
}
size += field->TotalSize(); size += field->TotalSize();
} }
// cache the value for next time.
// changing the body will reset this.
fFlattenedSize = size;
return size; return size;
} }
@@ -249,8 +254,6 @@ BMessageBody::FlattenedSize() const
status_t status_t
BMessageBody::Flatten(BDataIO *stream) const BMessageBody::Flatten(BDataIO *stream) const
{ {
status_t error = B_OK;
for (int32 index = 0; index < fFieldList.CountItems(); index++) { for (int32 index = 0; index < fFieldList.CountItems(); index++) {
BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); BMessageField *field = (BMessageField *)fFieldList.ItemAt(index);
@@ -270,16 +273,8 @@ BMessageBody::Flatten(BDataIO *stream) const
stream->Write(&count, sizeof(count)); stream->Write(&count, sizeof(count));
} }
bool isFixed = flags & MSG_FLAG_FIXED_SIZE; // overall data size (includes padding for non fixed size fields)
// overall data size
size_t size = field->TotalSize(); size_t size = field->TotalSize();
if (!isFixed) {
// add bytes for holding each items size
size += count * sizeof(size_t);
size += field->TotalPadding();
}
if (flags & MSG_FLAG_MINI_DATA) { if (flags & MSG_FLAG_MINI_DATA) {
uint8 miniSize = (uint8)size; uint8 miniSize = (uint8)size;
stream->Write(&miniSize, sizeof(miniSize)); stream->Write(&miniSize, sizeof(miniSize));
@@ -293,32 +288,29 @@ BMessageBody::Flatten(BDataIO *stream) const
// name // name
stream->Write(field->Name(), nameLength); stream->Write(field->Name(), nameLength);
// if we have a fixed size we initialize size once here
if (isFixed)
size = field->SizeAt(0);
// data items // data items
for (int32 dataIndex = 0; dataIndex < count; dataIndex++) { if (flags & MSG_FLAG_FIXED_SIZE) {
if (!isFixed) { size = field->SizeAt(0);
// set the size for each item for (int32 dataIndex = 0; dataIndex < count; dataIndex++)
stream->Write(field->BufferAt(dataIndex), size);
} else {
for (int32 dataIndex = 0; dataIndex < count; dataIndex++) {
size = field->SizeAt(dataIndex); size = field->SizeAt(dataIndex);
stream->Write(&size, sizeof(size)); stream->Write(&size, sizeof(size));
stream->Write(field->BufferAt(dataIndex), size);
size_t error = stream->Write(sPadding, CALC_PADDING_8(size));
} }
error = stream->Write(field->BufferAt(dataIndex), size);
if (!isFixed)
error = stream->Write(sPadding, calc_padding(size + 4, 8));
} }
} }
if (error >= B_OK) { uint8 lastEntry = 0;
uint8 lastEntry = 0; size_t error = stream->Write(&lastEntry, sizeof(lastEntry));
error = stream->Write(&lastEntry, sizeof(lastEntry));
}
if (error >= B_OK) if (error > B_OK)
return B_OK; return B_OK;
else if (error == 0)
return B_ERROR;
return error; return error;
} }
@@ -344,6 +336,7 @@ BMessageBody::Unflatten(BDataIO *stream)
int32 itemCount; int32 itemCount;
int32 dataLength; int32 dataLength;
uint8 littleData; uint8 littleData;
if (flags & MSG_FLAG_SINGLE_ITEM) { if (flags & MSG_FLAG_SINGLE_ITEM) {
itemCount = 1; itemCount = 1;
@@ -398,9 +391,8 @@ BMessageBody::Unflatten(BDataIO *stream)
int32 itemSize = dataLength / itemCount; int32 itemSize = dataLength / itemCount;
for (int32 index = 0; index < itemCount; index++) { for (int32 index = 0; index < itemCount; index++) {
BMallocIO *buffer = new BMallocIO(); BSimpleMallocIO *buffer = new BSimpleMallocIO(itemSize);
buffer->SetSize(itemSize); reader(buffer->Buffer(), itemSize);
reader((char *)buffer->Buffer(), itemSize);
field->AddItem(buffer); field->AddItem(buffer);
} }
} else { } else {
@@ -408,12 +400,10 @@ BMessageBody::Unflatten(BDataIO *stream)
ssize_t dataLength; ssize_t dataLength;
for (int32 index = 0; index < itemCount; index++) { for (int32 index = 0; index < itemCount; index++) {
BMallocIO *buffer = new BMallocIO();
reader(dataLength); reader(dataLength);
buffer->SetSize(dataLength); BSimpleMallocIO *buffer = new BSimpleMallocIO(dataLength);
reader(buffer->Buffer(), dataLength);
reader((char *)buffer->Buffer(), dataLength); reader(padding, CALC_PADDING_8(dataLength));
reader(padding, calc_padding(dataLength + 4, 8));
field->AddItem(buffer); field->AddItem(buffer);
} }
} }
@@ -429,7 +419,7 @@ BMessageBody::Unflatten(BDataIO *stream)
status_t status_t
BMessageBody::AddData(const char *name, BMallocIO *buffer, type_code type) BMessageBody::AddData(const char *name, BSimpleMallocIO *buffer, type_code type)
{ {
status_t error = B_OK; status_t error = B_OK;
BMessageField *foundField = FindData(name, type, error); BMessageField *foundField = FindData(name, type, error);
@@ -457,6 +447,7 @@ BMessageBody::AddData(const char *name, BMallocIO *buffer, type_code type)
foundField->AddItem(buffer); foundField->AddItem(buffer);
} }
fFlattenedSize = -1;
return error; return error;
} }
@@ -485,7 +476,7 @@ BMessageBody::AddField(const char *name, type_code type, status_t &error)
status_t status_t
BMessageBody::ReplaceData(const char *name, int32 index, BMallocIO *buffer, BMessageBody::ReplaceData(const char *name, int32 index, BSimpleMallocIO *buffer,
type_code type) type_code type)
{ {
if (type == B_ANY_TYPE) if (type == B_ANY_TYPE)
@@ -501,6 +492,7 @@ BMessageBody::ReplaceData(const char *name, int32 index, BMallocIO *buffer,
return B_ERROR; return B_ERROR;
field->ReplaceItem(index, buffer); field->ReplaceItem(index, buffer);
fFlattenedSize = -1;
return error; return error;
} }
@@ -508,9 +500,8 @@ BMessageBody::ReplaceData(const char *name, int32 index, BMallocIO *buffer,
status_t status_t
BMessageBody::RemoveData(const char *name, int32 index) BMessageBody::RemoveData(const char *name, int32 index)
{ {
if (index < 0) { if (index < 0)
return B_BAD_VALUE; return B_BAD_VALUE;
}
status_t error = B_OK; status_t error = B_OK;
BMessageField *field = FindData(name, B_ANY_TYPE, error); BMessageField *field = FindData(name, B_ANY_TYPE, error);
@@ -518,10 +509,10 @@ BMessageBody::RemoveData(const char *name, int32 index)
if (field) { if (field) {
if (index < field->CountItems()) { if (index < field->CountItems()) {
field->RemoveItem(index); field->RemoveItem(index);
fFlattenedSize = -1;
if (field->CountItems() == 0) { if (field->CountItems() == 0)
RemoveName(name); RemoveName(name);
}
} else } else
error = B_BAD_INDEX; error = B_BAD_INDEX;
} }
@@ -538,6 +529,7 @@ BMessageBody::RemoveName(const char *name)
if (field) { if (field) {
fFieldList.RemoveItem(field); fFieldList.RemoveItem(field);
fFlattenedSize = -1;
HashRemove(name); HashRemove(name);
delete field; delete field;
} }
@@ -555,6 +547,7 @@ BMessageBody::MakeEmpty()
} }
fFieldList.MakeEmpty(); fFieldList.MakeEmpty();
fFlattenedSize = -1;
HashClear(); HashClear();
return B_OK; return B_OK;
} }
+23 -32
View File
@@ -7,18 +7,18 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <DataIO.h>
#include <MessageUtils.h>
#include <TypeConstants.h> #include <TypeConstants.h>
#include "MessageField2.h" #include "MessageField2.h"
#include "SimpleMallocIO.h"
namespace BPrivate { namespace BPrivate {
#define ROUND_TO_8(x) (fFixedSize ? x : (x + 11) & ~7)
BMessageField::BMessageField() BMessageField::BMessageField()
: fType(0), : fType(0),
fFixedSize(false), fFixedSize(false),
fTotalSize(0), fTotalSize(0),
fTotalPadding(0),
fNext(NULL) fNext(NULL)
{ {
SetName(""); SetName("");
@@ -28,7 +28,6 @@ BMessageField::BMessageField()
BMessageField::BMessageField(const char *name, type_code type) BMessageField::BMessageField(const char *name, type_code type)
: fType(type), : fType(type),
fTotalSize(0), fTotalSize(0),
fTotalPadding(0),
fNext(NULL) fNext(NULL)
{ {
SetName(name); SetName(name);
@@ -58,13 +57,12 @@ BMessageField::operator=(const BMessageField &other)
fType = other.fType; fType = other.fType;
fFixedSize = other.fFixedSize; fFixedSize = other.fFixedSize;
fTotalSize = other.fTotalSize; fTotalSize = other.fTotalSize;
fTotalPadding = other.fTotalPadding;
fNext = NULL; fNext = NULL;
for (int32 index = 0; index < other.fItems.CountItems(); index++) { for (int32 index = 0; index < other.fItems.CountItems(); index++) {
BMallocIO *otherBuffer = (BMallocIO *)other.fItems.ItemAt(index); BSimpleMallocIO *otherBuffer = (BSimpleMallocIO *)other.fItems.ItemAt(index);
BMallocIO *newBuffer = new BMallocIO; BSimpleMallocIO *newBuffer = new BSimpleMallocIO(otherBuffer->BufferLength());
newBuffer->Write(otherBuffer->Buffer(), otherBuffer->BufferLength()); newBuffer->Write(otherBuffer->Buffer());
fItems.AddItem((void *)newBuffer); fItems.AddItem((void *)newBuffer);
} }
} }
@@ -77,7 +75,7 @@ void
BMessageField::MakeEmpty() BMessageField::MakeEmpty()
{ {
for (int32 index = 0; index < fItems.CountItems(); index++) { for (int32 index = 0; index < fItems.CountItems(); index++) {
BMallocIO *item = (BMallocIO *)fItems.ItemAt(index); BSimpleMallocIO *item = (BSimpleMallocIO *)fItems.ItemAt(index);
delete item; delete item;
} }
@@ -89,11 +87,11 @@ uint8
BMessageField::Flags() BMessageField::Flags()
{ {
uint8 flags = MSG_FLAG_VALID; uint8 flags = MSG_FLAG_VALID;
if (fItems.CountItems() == 1) if (fItems.CountItems() == 1)
flags |= MSG_FLAG_SINGLE_ITEM; flags |= MSG_FLAG_SINGLE_ITEM;
if (fTotalSize + fTotalPadding < 255) if (fTotalSize < 255)
flags |= MSG_FLAG_MINI_DATA; flags |= MSG_FLAG_MINI_DATA;
if (fFixedSize) if (fFixedSize)
@@ -115,46 +113,39 @@ BMessageField::SetName(const char *name)
void void
BMessageField::AddItem(BMallocIO *item) BMessageField::AddItem(BSimpleMallocIO *item)
{ {
fItems.AddItem((void *)item); fItems.AddItem((void *)item);
fTotalSize += item->BufferLength(); fTotalSize += ROUND_TO_8(item->BufferLength());
fTotalPadding += calc_padding(item->BufferLength() + 4, 8);
} }
void void
BMessageField::ReplaceItem(int32 index, BMallocIO *item, bool deleteOld) BMessageField::ReplaceItem(int32 index, BSimpleMallocIO *item)
{ {
BMallocIO *oldItem = (BMallocIO *)fItems.ItemAt(index); BSimpleMallocIO *oldItem = (BSimpleMallocIO *)fItems.ItemAt(index);
fTotalSize -= oldItem->BufferLength();
fTotalPadding -= calc_padding(oldItem->BufferLength() + 4, 8);
fItems.ReplaceItem(index, item); fItems.ReplaceItem(index, item);
fTotalSize += item->BufferLength();
fTotalPadding += calc_padding(item->BufferLength() + 4, 8);
if (deleteOld) fTotalSize -= ROUND_TO_8(oldItem->BufferLength());
delete oldItem; fTotalSize += ROUND_TO_8(item->BufferLength());
delete oldItem;
} }
void void
BMessageField::RemoveItem(int32 index, bool deleteIt) BMessageField::RemoveItem(int32 index)
{ {
BMallocIO *item = (BMallocIO *)fItems.RemoveItem(index); BSimpleMallocIO *item = (BSimpleMallocIO *)fItems.RemoveItem(index);
fTotalSize -= ROUND_TO_8(item->BufferLength());
fTotalSize -= item->BufferLength(); delete item;
fTotalPadding -= calc_padding(item->BufferLength() + 4, 8);
if (deleteIt)
delete item;
} }
size_t size_t
BMessageField::SizeAt(int32 index) const BMessageField::SizeAt(int32 index) const
{ {
BMallocIO *buffer = (BMallocIO *)fItems.ItemAt(index); BSimpleMallocIO *buffer = (BSimpleMallocIO *)fItems.ItemAt(index);
if (buffer) if (buffer)
return buffer->BufferLength(); return buffer->BufferLength();
@@ -166,7 +157,7 @@ BMessageField::SizeAt(int32 index) const
const void * const void *
BMessageField::BufferAt(int32 index) const BMessageField::BufferAt(int32 index) const
{ {
BMallocIO *buffer = (BMallocIO *)fItems.ItemAt(index); BSimpleMallocIO *buffer = (BSimpleMallocIO *)fItems.ItemAt(index);
if (buffer) if (buffer)
return buffer->Buffer(); return buffer->Buffer();