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:
@@ -43,7 +43,7 @@ public:
|
||||
status_t Flatten(BDataIO *stream) const;
|
||||
status_t Unflatten(BDataIO *stream);
|
||||
|
||||
status_t AddData(const char *name, BMallocIO *buffer,
|
||||
status_t AddData(const char *name, BSimpleMallocIO *buffer,
|
||||
type_code type);
|
||||
status_t RemoveData(const char *name, int32 index = 0);
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
int32 index, const void **data,
|
||||
ssize_t *numBytes) const;
|
||||
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 RemoveName(const char *name);
|
||||
@@ -77,6 +77,8 @@ private:
|
||||
BList fFieldList;
|
||||
BMessageField **fFieldTable;
|
||||
int32 fFieldTableSize;
|
||||
|
||||
mutable ssize_t fFlattenedSize;
|
||||
};
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class BSimpleMallocIO;
|
||||
|
||||
class BMessageField {
|
||||
public:
|
||||
BMessageField();
|
||||
@@ -41,10 +43,9 @@ public:
|
||||
uint8 NameLength() const { return fName.Length(); };
|
||||
type_code Type() const { return fType; };
|
||||
|
||||
void AddItem(BMallocIO *item);
|
||||
void ReplaceItem(int32 index, BMallocIO *item,
|
||||
bool deleteOld = true);
|
||||
void RemoveItem(int32 index, bool deleteIt = true);
|
||||
void AddItem(BSimpleMallocIO *item);
|
||||
void ReplaceItem(int32 index, BSimpleMallocIO *item);
|
||||
void RemoveItem(int32 index);
|
||||
int32 CountItems() const { return fItems.CountItems(); };
|
||||
size_t SizeAt(int32 index) const;
|
||||
const void *BufferAt(int32 index) const;
|
||||
|
||||
@@ -116,15 +116,14 @@ public:
|
||||
if (fError < B_OK)
|
||||
throw fError;
|
||||
|
||||
if (IsSwapping()) {
|
||||
if (IsSwapping())
|
||||
byte_swap(data);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void operator()(T data, size_t len)
|
||||
{
|
||||
fError = fStream->Read((void*)data, len);
|
||||
fError = fStream->Read((void *)data, len);
|
||||
if (fError < B_OK)
|
||||
throw fError;
|
||||
}
|
||||
|
||||
@@ -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
@@ -34,11 +34,12 @@
|
||||
|
||||
#include <AppMisc.h>
|
||||
#include <KMessage.h>
|
||||
#include <MessageUtils2.h>
|
||||
#include <TokenSpace.h>
|
||||
|
||||
#include "MessageBody2.h"
|
||||
#include "MessageField2.h"
|
||||
#include "MessageUtils2.h"
|
||||
#include "SimpleMallocIO.h"
|
||||
#include "dano_message.h"
|
||||
|
||||
// flags for the overall message (the bitfield is 1 byte)
|
||||
@@ -873,9 +874,6 @@ BMessage::Unflatten(BDataIO *stream)
|
||||
header.WriteTo(*this);
|
||||
|
||||
status = fBody->Unflatten(stream);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
} catch (status_t &error) {
|
||||
status = error;
|
||||
}
|
||||
@@ -1152,11 +1150,9 @@ BMessage::AddMessenger(const char *name, BMessenger messenger)
|
||||
status_t
|
||||
BMessage::AddRef(const char* name, const entry_ref* ref)
|
||||
{
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
buffer->SetSize(sizeof(entry_ref) + B_PATH_NAME_LENGTH);
|
||||
|
||||
size_t size;
|
||||
status_t error = entry_ref_flatten((char *)buffer->Buffer(), &size, ref);
|
||||
size_t size = sizeof(entry_ref) + B_PATH_NAME_LENGTH;
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
|
||||
status_t error = entry_ref_flatten(buffer->Buffer(), &size, ref);
|
||||
buffer->SetSize(size);
|
||||
|
||||
if (error >= B_OK)
|
||||
@@ -1172,8 +1168,9 @@ BMessage::AddRef(const char* name, const entry_ref* ref)
|
||||
status_t
|
||||
BMessage::AddMessage(const char *name, const BMessage *msg)
|
||||
{
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
status_t error = msg->Flatten(buffer);
|
||||
size_t size = msg->FlattenedSize();
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
|
||||
status_t error = msg->Flatten(buffer->Buffer(), size);
|
||||
|
||||
if (error >= B_OK)
|
||||
error = fBody->AddData(name, buffer, B_MESSAGE_TYPE);
|
||||
@@ -1189,10 +1186,9 @@ status_t
|
||||
BMessage::AddFlat(const char *name, BFlattenable *object, int32 count)
|
||||
{
|
||||
ssize_t size = object->FlattenedSize();
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
buffer->SetSize(size);
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
|
||||
status_t error = object->Flatten(buffer->Buffer(), size);
|
||||
|
||||
status_t error = object->Flatten((void *)buffer->Buffer(), size);
|
||||
if (error >= B_OK)
|
||||
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
|
||||
// enforce the size thing.
|
||||
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
buffer->Write(data, numBytes);
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(numBytes);
|
||||
buffer->Write(data);
|
||||
status_t error = fBody->AddData(name, buffer, type);
|
||||
|
||||
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);
|
||||
|
||||
if (!error)
|
||||
error = msg->Unflatten((const char*)data);
|
||||
error = msg->Unflatten((const char *)data);
|
||||
else
|
||||
*msg = BMessage();
|
||||
|
||||
@@ -1493,11 +1489,9 @@ BMessage::ReplaceRef(const char *name, const entry_ref *ref)
|
||||
status_t
|
||||
BMessage::ReplaceRef(const char *name, int32 index, const entry_ref *ref)
|
||||
{
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
buffer->SetSize(sizeof(entry_ref) + B_PATH_NAME_LENGTH);
|
||||
|
||||
size_t size;
|
||||
status_t error = entry_ref_flatten((char *)buffer->Buffer(), &size, ref);
|
||||
size_t size = sizeof(entry_ref) + B_PATH_NAME_LENGTH;
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
|
||||
status_t error = entry_ref_flatten(buffer->Buffer(), &size, ref);
|
||||
buffer->SetSize(size);
|
||||
|
||||
if (error >= B_OK)
|
||||
@@ -1520,8 +1514,9 @@ BMessage::ReplaceMessage(const char *name, const BMessage *msg)
|
||||
status_t
|
||||
BMessage::ReplaceMessage(const char *name, int32 index, const BMessage *msg)
|
||||
{
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
status_t error = msg->Flatten(buffer);
|
||||
size_t size = msg->FlattenedSize();
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
|
||||
status_t error = msg->Flatten(buffer->Buffer(), size);
|
||||
|
||||
if (error >= B_OK)
|
||||
error = fBody->ReplaceData(name, index, buffer, B_MESSAGE_TYPE);
|
||||
@@ -1544,10 +1539,9 @@ status_t
|
||||
BMessage::ReplaceFlat(const char *name, int32 index, BFlattenable *object)
|
||||
{
|
||||
ssize_t size = object->FlattenedSize();
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
buffer->SetSize(size);
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(size);
|
||||
status_t error = object->Flatten(buffer->Buffer(), size);
|
||||
|
||||
status_t error = object->Flatten((void *)buffer->Buffer(), size);
|
||||
if (error >= B_OK)
|
||||
error = fBody->ReplaceData(name, index, buffer, object->TypeCode());
|
||||
|
||||
@@ -1570,8 +1564,8 @@ status_t
|
||||
BMessage::ReplaceData(const char *name, type_code type, int32 index,
|
||||
const void *data, ssize_t data_size)
|
||||
{
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
buffer->Write(data, data_size);
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(data_size);
|
||||
buffer->Write(data);
|
||||
status_t error = fBody->ReplaceData(name, index, buffer, type);
|
||||
|
||||
if (error < B_OK)
|
||||
@@ -1629,7 +1623,7 @@ BMessage::operator delete(void *ptr, size_t size)
|
||||
status_t
|
||||
BMessage::real_flatten(char *result, ssize_t size) const
|
||||
{
|
||||
BMemoryIO stream((void*)result, size);
|
||||
BMemoryIO stream((void *)result, size);
|
||||
return real_flatten(&stream, NULL);
|
||||
}
|
||||
|
||||
@@ -1640,9 +1634,12 @@ BMessage::real_flatten(BDataIO *stream, ssize_t *size) const
|
||||
Header header(*this);
|
||||
|
||||
status_t error = header.WriteTo(*stream);
|
||||
if (!error)
|
||||
if (error >= B_OK)
|
||||
error = fBody->Flatten(stream);
|
||||
|
||||
if (size)
|
||||
*size = FlattenedSize();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1686,14 +1683,14 @@ BMessage::calc_hdr_size(uchar flags) const
|
||||
ssize_t size = min_hdr_size();
|
||||
|
||||
if (fTarget != B_NULL_TOKEN)
|
||||
size += sizeof (fTarget);
|
||||
size += sizeof(fTarget);
|
||||
|
||||
if (fReplyTo.port >= 0
|
||||
&& fReplyTo.target != B_NULL_TOKEN
|
||||
&& fReplyTo.team >= 0) {
|
||||
size += sizeof (fReplyTo.port);
|
||||
size += sizeof (fReplyTo.target);
|
||||
size += sizeof (fReplyTo.team);
|
||||
size += sizeof(fReplyTo.port);
|
||||
size += sizeof(fReplyTo.target);
|
||||
size += sizeof(fReplyTo.team);
|
||||
|
||||
size += 4; // For the "big" flags
|
||||
}
|
||||
|
||||
@@ -9,14 +9,17 @@
|
||||
/* BMessageBody handles data storage and retrieval for BMessage. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <DataIO.h>
|
||||
#include <MessageUtils.h>
|
||||
#include <TypeConstants.h>
|
||||
#include "MessageBody2.h"
|
||||
#include "MessageUtils2.h"
|
||||
#include "SimpleMallocIO.h"
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
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()
|
||||
{
|
||||
@@ -59,6 +62,7 @@ BMessageBody::operator=(const BMessageBody &other)
|
||||
status_t
|
||||
BMessageBody::InitCommon()
|
||||
{
|
||||
fFlattenedSize = -1;
|
||||
fFieldTableSize = 100;
|
||||
fFieldTable = new BMessageField *[fFieldTableSize];
|
||||
HashClear();
|
||||
@@ -201,6 +205,7 @@ BMessageBody::Rename(const char *oldName, const char *newName)
|
||||
|
||||
field->SetName(newName);
|
||||
HashInsert(HashRemove(oldName));
|
||||
fFlattenedSize = -1;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -208,6 +213,9 @@ BMessageBody::Rename(const char *oldName, const char *newName)
|
||||
ssize_t
|
||||
BMessageBody::FlattenedSize() const
|
||||
{
|
||||
if (fFlattenedSize > 0)
|
||||
return fFlattenedSize;
|
||||
|
||||
ssize_t size = 1; // for MSG_LAST_ENTRY
|
||||
|
||||
for (int32 index = 0; index < fFieldList.CountItems(); index++) {
|
||||
@@ -233,15 +241,12 @@ BMessageBody::FlattenedSize() const
|
||||
// name length byte and name length
|
||||
size += 1 + field->NameLength();
|
||||
|
||||
// individual sizes
|
||||
if (!(flags & MSG_FLAG_FIXED_SIZE)) {
|
||||
size += field->CountItems() * sizeof(size_t);
|
||||
size += field->TotalPadding();
|
||||
}
|
||||
|
||||
size += field->TotalSize();
|
||||
}
|
||||
|
||||
// cache the value for next time.
|
||||
// changing the body will reset this.
|
||||
fFlattenedSize = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -249,8 +254,6 @@ BMessageBody::FlattenedSize() const
|
||||
status_t
|
||||
BMessageBody::Flatten(BDataIO *stream) const
|
||||
{
|
||||
status_t error = B_OK;
|
||||
|
||||
for (int32 index = 0; index < fFieldList.CountItems(); index++) {
|
||||
BMessageField *field = (BMessageField *)fFieldList.ItemAt(index);
|
||||
|
||||
@@ -270,16 +273,8 @@ BMessageBody::Flatten(BDataIO *stream) const
|
||||
stream->Write(&count, sizeof(count));
|
||||
}
|
||||
|
||||
bool isFixed = flags & MSG_FLAG_FIXED_SIZE;
|
||||
|
||||
// overall data size
|
||||
// overall data size (includes padding for non fixed size fields)
|
||||
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) {
|
||||
uint8 miniSize = (uint8)size;
|
||||
stream->Write(&miniSize, sizeof(miniSize));
|
||||
@@ -293,32 +288,29 @@ BMessageBody::Flatten(BDataIO *stream) const
|
||||
// name
|
||||
stream->Write(field->Name(), nameLength);
|
||||
|
||||
// if we have a fixed size we initialize size once here
|
||||
if (isFixed)
|
||||
size = field->SizeAt(0);
|
||||
|
||||
// data items
|
||||
for (int32 dataIndex = 0; dataIndex < count; dataIndex++) {
|
||||
if (!isFixed) {
|
||||
// set the size for each item
|
||||
if (flags & MSG_FLAG_FIXED_SIZE) {
|
||||
size = field->SizeAt(0);
|
||||
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);
|
||||
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;
|
||||
error = stream->Write(&lastEntry, sizeof(lastEntry));
|
||||
}
|
||||
uint8 lastEntry = 0;
|
||||
size_t error = stream->Write(&lastEntry, sizeof(lastEntry));
|
||||
|
||||
if (error >= B_OK)
|
||||
if (error > B_OK)
|
||||
return B_OK;
|
||||
else if (error == 0)
|
||||
return B_ERROR;
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -344,6 +336,7 @@ BMessageBody::Unflatten(BDataIO *stream)
|
||||
int32 itemCount;
|
||||
int32 dataLength;
|
||||
uint8 littleData;
|
||||
|
||||
if (flags & MSG_FLAG_SINGLE_ITEM) {
|
||||
itemCount = 1;
|
||||
|
||||
@@ -398,9 +391,8 @@ BMessageBody::Unflatten(BDataIO *stream)
|
||||
int32 itemSize = dataLength / itemCount;
|
||||
|
||||
for (int32 index = 0; index < itemCount; index++) {
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
buffer->SetSize(itemSize);
|
||||
reader((char *)buffer->Buffer(), itemSize);
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(itemSize);
|
||||
reader(buffer->Buffer(), itemSize);
|
||||
field->AddItem(buffer);
|
||||
}
|
||||
} else {
|
||||
@@ -408,12 +400,10 @@ BMessageBody::Unflatten(BDataIO *stream)
|
||||
ssize_t dataLength;
|
||||
|
||||
for (int32 index = 0; index < itemCount; index++) {
|
||||
BMallocIO *buffer = new BMallocIO();
|
||||
reader(dataLength);
|
||||
buffer->SetSize(dataLength);
|
||||
|
||||
reader((char *)buffer->Buffer(), dataLength);
|
||||
reader(padding, calc_padding(dataLength + 4, 8));
|
||||
BSimpleMallocIO *buffer = new BSimpleMallocIO(dataLength);
|
||||
reader(buffer->Buffer(), dataLength);
|
||||
reader(padding, CALC_PADDING_8(dataLength));
|
||||
field->AddItem(buffer);
|
||||
}
|
||||
}
|
||||
@@ -429,7 +419,7 @@ BMessageBody::Unflatten(BDataIO *stream)
|
||||
|
||||
|
||||
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;
|
||||
BMessageField *foundField = FindData(name, type, error);
|
||||
@@ -457,6 +447,7 @@ BMessageBody::AddData(const char *name, BMallocIO *buffer, type_code type)
|
||||
foundField->AddItem(buffer);
|
||||
}
|
||||
|
||||
fFlattenedSize = -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -485,7 +476,7 @@ BMessageBody::AddField(const char *name, type_code type, status_t &error)
|
||||
|
||||
|
||||
status_t
|
||||
BMessageBody::ReplaceData(const char *name, int32 index, BMallocIO *buffer,
|
||||
BMessageBody::ReplaceData(const char *name, int32 index, BSimpleMallocIO *buffer,
|
||||
type_code type)
|
||||
{
|
||||
if (type == B_ANY_TYPE)
|
||||
@@ -501,6 +492,7 @@ BMessageBody::ReplaceData(const char *name, int32 index, BMallocIO *buffer,
|
||||
return B_ERROR;
|
||||
|
||||
field->ReplaceItem(index, buffer);
|
||||
fFlattenedSize = -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -508,9 +500,8 @@ BMessageBody::ReplaceData(const char *name, int32 index, BMallocIO *buffer,
|
||||
status_t
|
||||
BMessageBody::RemoveData(const char *name, int32 index)
|
||||
{
|
||||
if (index < 0) {
|
||||
if (index < 0)
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
status_t error = B_OK;
|
||||
BMessageField *field = FindData(name, B_ANY_TYPE, error);
|
||||
@@ -518,10 +509,10 @@ BMessageBody::RemoveData(const char *name, int32 index)
|
||||
if (field) {
|
||||
if (index < field->CountItems()) {
|
||||
field->RemoveItem(index);
|
||||
fFlattenedSize = -1;
|
||||
|
||||
if (field->CountItems() == 0) {
|
||||
if (field->CountItems() == 0)
|
||||
RemoveName(name);
|
||||
}
|
||||
} else
|
||||
error = B_BAD_INDEX;
|
||||
}
|
||||
@@ -538,6 +529,7 @@ BMessageBody::RemoveName(const char *name)
|
||||
|
||||
if (field) {
|
||||
fFieldList.RemoveItem(field);
|
||||
fFlattenedSize = -1;
|
||||
HashRemove(name);
|
||||
delete field;
|
||||
}
|
||||
@@ -555,6 +547,7 @@ BMessageBody::MakeEmpty()
|
||||
}
|
||||
|
||||
fFieldList.MakeEmpty();
|
||||
fFlattenedSize = -1;
|
||||
HashClear();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <DataIO.h>
|
||||
#include <MessageUtils.h>
|
||||
#include <TypeConstants.h>
|
||||
#include "MessageField2.h"
|
||||
#include "SimpleMallocIO.h"
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
#define ROUND_TO_8(x) (fFixedSize ? x : (x + 11) & ~7)
|
||||
|
||||
BMessageField::BMessageField()
|
||||
: fType(0),
|
||||
fFixedSize(false),
|
||||
fTotalSize(0),
|
||||
fTotalPadding(0),
|
||||
fNext(NULL)
|
||||
{
|
||||
SetName("");
|
||||
@@ -28,7 +28,6 @@ BMessageField::BMessageField()
|
||||
BMessageField::BMessageField(const char *name, type_code type)
|
||||
: fType(type),
|
||||
fTotalSize(0),
|
||||
fTotalPadding(0),
|
||||
fNext(NULL)
|
||||
{
|
||||
SetName(name);
|
||||
@@ -58,13 +57,12 @@ BMessageField::operator=(const BMessageField &other)
|
||||
fType = other.fType;
|
||||
fFixedSize = other.fFixedSize;
|
||||
fTotalSize = other.fTotalSize;
|
||||
fTotalPadding = other.fTotalPadding;
|
||||
fNext = NULL;
|
||||
|
||||
for (int32 index = 0; index < other.fItems.CountItems(); index++) {
|
||||
BMallocIO *otherBuffer = (BMallocIO *)other.fItems.ItemAt(index);
|
||||
BMallocIO *newBuffer = new BMallocIO;
|
||||
newBuffer->Write(otherBuffer->Buffer(), otherBuffer->BufferLength());
|
||||
BSimpleMallocIO *otherBuffer = (BSimpleMallocIO *)other.fItems.ItemAt(index);
|
||||
BSimpleMallocIO *newBuffer = new BSimpleMallocIO(otherBuffer->BufferLength());
|
||||
newBuffer->Write(otherBuffer->Buffer());
|
||||
fItems.AddItem((void *)newBuffer);
|
||||
}
|
||||
}
|
||||
@@ -77,7 +75,7 @@ void
|
||||
BMessageField::MakeEmpty()
|
||||
{
|
||||
for (int32 index = 0; index < fItems.CountItems(); index++) {
|
||||
BMallocIO *item = (BMallocIO *)fItems.ItemAt(index);
|
||||
BSimpleMallocIO *item = (BSimpleMallocIO *)fItems.ItemAt(index);
|
||||
delete item;
|
||||
}
|
||||
|
||||
@@ -89,11 +87,11 @@ uint8
|
||||
BMessageField::Flags()
|
||||
{
|
||||
uint8 flags = MSG_FLAG_VALID;
|
||||
|
||||
|
||||
if (fItems.CountItems() == 1)
|
||||
flags |= MSG_FLAG_SINGLE_ITEM;
|
||||
|
||||
if (fTotalSize + fTotalPadding < 255)
|
||||
if (fTotalSize < 255)
|
||||
flags |= MSG_FLAG_MINI_DATA;
|
||||
|
||||
if (fFixedSize)
|
||||
@@ -115,46 +113,39 @@ BMessageField::SetName(const char *name)
|
||||
|
||||
|
||||
void
|
||||
BMessageField::AddItem(BMallocIO *item)
|
||||
BMessageField::AddItem(BSimpleMallocIO *item)
|
||||
{
|
||||
fItems.AddItem((void *)item);
|
||||
fTotalSize += item->BufferLength();
|
||||
fTotalPadding += calc_padding(item->BufferLength() + 4, 8);
|
||||
fTotalSize += ROUND_TO_8(item->BufferLength());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BMessageField::ReplaceItem(int32 index, BMallocIO *item, bool deleteOld)
|
||||
BMessageField::ReplaceItem(int32 index, BSimpleMallocIO *item)
|
||||
{
|
||||
BMallocIO *oldItem = (BMallocIO *)fItems.ItemAt(index);
|
||||
fTotalSize -= oldItem->BufferLength();
|
||||
fTotalPadding -= calc_padding(oldItem->BufferLength() + 4, 8);
|
||||
|
||||
BSimpleMallocIO *oldItem = (BSimpleMallocIO *)fItems.ItemAt(index);
|
||||
fItems.ReplaceItem(index, item);
|
||||
fTotalSize += item->BufferLength();
|
||||
fTotalPadding += calc_padding(item->BufferLength() + 4, 8);
|
||||
|
||||
if (deleteOld)
|
||||
delete oldItem;
|
||||
fTotalSize -= ROUND_TO_8(oldItem->BufferLength());
|
||||
fTotalSize += ROUND_TO_8(item->BufferLength());
|
||||
|
||||
delete oldItem;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BMessageField::RemoveItem(int32 index, bool deleteIt)
|
||||
BMessageField::RemoveItem(int32 index)
|
||||
{
|
||||
BMallocIO *item = (BMallocIO *)fItems.RemoveItem(index);
|
||||
|
||||
fTotalSize -= item->BufferLength();
|
||||
fTotalPadding -= calc_padding(item->BufferLength() + 4, 8);
|
||||
if (deleteIt)
|
||||
delete item;
|
||||
BSimpleMallocIO *item = (BSimpleMallocIO *)fItems.RemoveItem(index);
|
||||
fTotalSize -= ROUND_TO_8(item->BufferLength());
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
BMessageField::SizeAt(int32 index) const
|
||||
{
|
||||
BMallocIO *buffer = (BMallocIO *)fItems.ItemAt(index);
|
||||
BSimpleMallocIO *buffer = (BSimpleMallocIO *)fItems.ItemAt(index);
|
||||
|
||||
if (buffer)
|
||||
return buffer->BufferLength();
|
||||
@@ -166,7 +157,7 @@ BMessageField::SizeAt(int32 index) const
|
||||
const void *
|
||||
BMessageField::BufferAt(int32 index) const
|
||||
{
|
||||
BMallocIO *buffer = (BMallocIO *)fItems.ItemAt(index);
|
||||
BSimpleMallocIO *buffer = (BSimpleMallocIO *)fItems.ItemAt(index);
|
||||
|
||||
if (buffer)
|
||||
return buffer->Buffer();
|
||||
|
||||
Reference in New Issue
Block a user