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 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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 <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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user