From fcf209d9ce52997f07a58c86994b340fcc8bca5b Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 20 Jul 2005 23:15:03 +0000 Subject: [PATCH] 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 --- headers/private/app/MessageBody2.h | 1 + headers/private/app/MessageField2.h | 2 ++ src/kits/app/MessageBody2.cpp | 49 +++++++++++++++++++---------- src/kits/app/MessageField2.cpp | 14 +++++++-- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/headers/private/app/MessageBody2.h b/headers/private/app/MessageBody2.h index 9d660c7128..8e5e742c04 100644 --- a/headers/private/app/MessageBody2.h +++ b/headers/private/app/MessageBody2.h @@ -67,6 +67,7 @@ public: void HashClear(); private: + status_t InitCommon(); BMessageField *FindData(const char *name, type_code type, status_t &error) const; diff --git a/headers/private/app/MessageField2.h b/headers/private/app/MessageField2.h index e47b633699..2a22dfc451 100644 --- a/headers/private/app/MessageField2.h +++ b/headers/private/app/MessageField2.h @@ -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; }; diff --git a/src/kits/app/MessageBody2.cpp b/src/kits/app/MessageBody2.cpp index b3d780c7b3..61458c4dfe 100644 --- a/src/kits/app/MessageBody2.cpp +++ b/src/kits/app/MessageBody2.cpp @@ -10,25 +10,23 @@ #include #include +#include #include #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; @@ -241,7 +254,7 @@ BMessageBody::Flatten(BDataIO *stream) const for (int32 index = 0; index < fFieldList.CountItems(); index++) { BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - + uint8 flags = field->Flags(); stream->Write(&flags, sizeof(flags)); @@ -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,8 +554,7 @@ BMessageBody::HashRemove(const char *name) void BMessageBody::HashClear() { - if (fFieldTable) - memset(fFieldTable, 0, fFieldTableSize * sizeof(BMessageField *)); + memset(fFieldTable, 0, fFieldTableSize * sizeof(BMessageField *)); } diff --git a/src/kits/app/MessageField2.cpp b/src/kits/app/MessageField2.cpp index 161fd5aadc..8d4f8c5722 100644 --- a/src/kits/app/MessageField2.cpp +++ b/src/kits/app/MessageField2.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #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; }