Added padding calculation (not final) so that flattening / unflattening actually works.

Passes all unit tests now and works on Haiku too. Speed is not yet optimized and Message2.cpp is still not cleaned up.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13785 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2005-07-20 23:15:03 +00:00
parent bbe759b31b
commit fcf209d9ce
4 changed files with 47 additions and 19 deletions

View File

@ -67,6 +67,7 @@ public:
void HashClear();
private:
status_t InitCommon();
BMessageField *FindData(const char *name, type_code type,
status_t &error) const;

View File

@ -53,6 +53,7 @@ public:
bool IsFixedSize() const { return fFixedSize; };
size_t TotalSize() const { return fTotalSize; };
size_t TotalPadding() const { return fTotalPadding; };
void PrintToStream() const;
@ -68,6 +69,7 @@ private:
BList fItems;
bool fFixedSize;
size_t fTotalSize;
size_t fTotalPadding;
BMessageField *fNext;
};

View File

@ -10,25 +10,23 @@
#include <stdio.h>
#include <DataIO.h>
#include <MessageUtils.h>
#include <TypeConstants.h>
#include "MessageBody2.h"
namespace BPrivate {
static int64 sPadding[2] = { 0, 0 };
BMessageBody::BMessageBody()
{
fFieldTableSize = 1;
fFieldTable = new BMessageField *[fFieldTableSize];
HashClear();
InitCommon();
}
BMessageBody::BMessageBody(const BMessageBody &other)
{
fFieldTableSize = 1;
fFieldTable = new BMessageField *[fFieldTableSize];
HashClear();
InitCommon();
*this = other;
}
@ -58,6 +56,16 @@ BMessageBody::operator=(const BMessageBody &other)
}
status_t
BMessageBody::InitCommon()
{
fFieldTableSize = 100;
fFieldTable = new BMessageField *[fFieldTableSize];
HashClear();
return B_OK;
}
status_t
BMessageBody::GetInfo(type_code typeRequested, int32 which, char **name,
type_code *typeReturned, int32 *count) const
@ -204,12 +212,10 @@ BMessageBody::FlattenedSize() const
for (int32 index = 0; index < fFieldList.CountItems(); index++) {
BMessageField *field = (BMessageField *)fFieldList.ItemAt(index);
size += field->TotalSize();
size += field->NameLength();
// ToDo: too expensive?
uint8 flags = field->Flags();
size += sizeof(flags);
size += sizeof(type_code);
// count information
if (!(flags & MSG_FLAG_SINGLE_ITEM)) {
@ -225,9 +231,16 @@ BMessageBody::FlattenedSize() const
else
size += sizeof(size_t);
// name length byte and name length
size += 1 + field->NameLength();
// individual sizes
if (!(flags & MSG_FLAG_FIXED_SIZE))
if (!(flags & MSG_FLAG_FIXED_SIZE)) {
size += field->CountItems() * sizeof(size_t);
size += field->TotalPadding();
}
size += field->TotalSize();
}
return size;
@ -265,7 +278,7 @@ BMessageBody::Flatten(BDataIO *stream) const
if (!isFixed) {
// add bytes for holding each items size
size += count * sizeof(size_t);
// ToDo: add padding here
size += field->TotalPadding();
}
if (flags & MSG_FLAG_MINI_DATA) {
@ -294,12 +307,15 @@ BMessageBody::Flatten(BDataIO *stream) const
}
error = stream->Write(field->BufferAt(dataIndex), size);
// ToDo: add padding here too
if (!isFixed)
error = stream->Write(sPadding, calc_padding(size + 4, 8));
}
}
if (error >= B_OK) {
error = stream->Write('\0', 1); // MSG_LAST_ENTRY
uint8 lastEntry = 0;
error = stream->Write(&lastEntry, sizeof(lastEntry));
}
if (error >= B_OK)
@ -538,7 +554,6 @@ BMessageBody::HashRemove(const char *name)
void
BMessageBody::HashClear()
{
if (fFieldTable)
memset(fFieldTable, 0, fFieldTableSize * sizeof(BMessageField *));
}

View File

@ -8,6 +8,7 @@
#include <stdio.h>
#include <DataIO.h>
#include <MessageUtils.h>
#include <TypeConstants.h>
#include "MessageField2.h"
@ -16,6 +17,7 @@ namespace BPrivate {
BMessageField::BMessageField()
: fType(0),
fTotalSize(0),
fTotalPadding(0),
fNext(NULL)
{
}
@ -24,6 +26,7 @@ BMessageField::BMessageField()
BMessageField::BMessageField(const char *name, type_code type)
: fType(type),
fTotalSize(0),
fTotalPadding(0),
fNext(NULL)
{
SetName(name);
@ -49,8 +52,11 @@ BMessageField::operator=(const BMessageField &other)
if (this != &other) {
MakeEmpty();
fType = other.fType;
fName = other.fName;
fType = other.fType;
fFixedSize = other.fFixedSize;
fTotalSize = other.fTotalSize;
fTotalPadding = other.fTotalPadding;
fNext = NULL;
for (int32 index = 0; index < other.fItems.CountItems(); index++) {
@ -85,7 +91,7 @@ BMessageField::Flags()
if (fItems.CountItems() == 1)
flags |= MSG_FLAG_SINGLE_ITEM;
if (fTotalSize < 255)
if (fTotalSize + fTotalPadding < 255)
flags |= MSG_FLAG_MINI_DATA;
if (fFixedSize)
@ -111,6 +117,7 @@ BMessageField::AddItem(BMallocIO *item)
{
fItems.AddItem((void *)item);
fTotalSize += item->BufferLength();
fTotalPadding += calc_padding(item->BufferLength() + 4, 8);
}
@ -119,9 +126,11 @@ BMessageField::ReplaceItem(int32 index, BMallocIO *item, bool deleteOld)
{
BMallocIO *oldItem = (BMallocIO *)fItems.ItemAt(index);
fTotalSize -= oldItem->BufferLength();
fTotalPadding -= calc_padding(oldItem->BufferLength() + 4, 8);
fItems.ReplaceItem(index, item);
fTotalSize += item->BufferLength();
fTotalPadding += calc_padding(item->BufferLength() + 4, 8);
if (deleteOld)
delete oldItem;
@ -134,6 +143,7 @@ BMessageField::RemoveItem(int32 index, bool deleteIt)
BMallocIO *item = (BMallocIO *)fItems.RemoveItem(index);
fTotalSize -= item->BufferLength();
fTotalPadding -= calc_padding(item->BufferLength() + 4, 8);
if (deleteIt)
delete item;
}