diff --git a/headers/private/app/MessageBody3.h b/headers/private/app/MessageBody3.h index b37faab094..c66aee4683 100644 --- a/headers/private/app/MessageBody3.h +++ b/headers/private/app/MessageBody3.h @@ -12,7 +12,6 @@ #define _MESSAGE_BODY_H_ #include -#include "MessageField3.h" enum { B_FLATTENABLE_TYPE = 'FLAT' @@ -20,6 +19,8 @@ enum { namespace BPrivate { +class BMessageField; + class BMessageBody { public: BMessageBody(); @@ -68,7 +69,7 @@ public: void PrintToStream() const; // flat buffer management - uint8 *FlatBuffer() const { return (uint8 *)fFlatBuffer.Buffer(); }; +inline uint8 *FlatBuffer() const { return (uint8 *)fFlatBuffer.Buffer(); }; uint8 *FlatInsert(int32 offset, ssize_t oldLength, ssize_t newLength); diff --git a/headers/private/app/MessageField3.h b/headers/private/app/MessageField3.h index 8afa68ee1a..c437db5c2d 100644 --- a/headers/private/app/MessageField3.h +++ b/headers/private/app/MessageField3.h @@ -14,6 +14,7 @@ #include #include #include +#include "MessageBody3.h" // we only support those #define MSG_FLAG_VALID 0x01 @@ -56,27 +57,24 @@ struct item_info_s { typedef field_header_s FieldHeader; typedef item_info_s ItemInfo; -class BMessageBody; - class BMessageField { public: BMessageField(BMessageBody *parent, int32 offset, const char *name, type_code type); + // only use this constructor to unflatten BMessageField(BMessageBody *parent); - ~BMessageField(); - int32 Unflatten(int32 offset); - uint8 Flags() const { return fHeader->flags; }; + uint8 Flags() const { return Header()->flags; }; status_t SetFixedSize(int32 itemSize); - bool FixedSize() const { return fHeader->flags & MSG_FLAG_FIXED_SIZE; }; + bool FixedSize() const { return fFixedSize; }; void SetName(const char *newName); const char *Name() const; - uint8 NameLength() const { return fHeader->nameLength; }; - type_code Type() const { return fHeader->type; }; + uint8 NameLength() const { return Header()->nameLength; }; + type_code Type() const { return Header()->type; }; void AddItem(const void *item, ssize_t length); uint8 *AddItem(ssize_t length); @@ -88,11 +86,11 @@ public: void *ItemAt(int32 index, ssize_t *size); void RemoveItem(int32 index); - int32 CountItems() const { return fHeader->count; }; + int32 CountItems() const { return Header()->count; }; void PrintToStream() const; - void SetOffset(int32 offset); + void SetOffset(int32 offset) { fOffset = offset; }; int32 Offset() const { return fOffset; }; // always do MakeEmpty -> RemoveSelf -> delete @@ -104,12 +102,13 @@ public: BMessageField *Next() const { return fNext; }; private: - bool IsFixedSize(type_code type); +inline FieldHeader *Header() const { return (FieldHeader *)(fParent->FlatBuffer() + fOffset); }; BMessageBody *fParent; int32 fOffset; - FieldHeader *fHeader; + int32 fDataOffset; + bool fFixedSize; int32 fItemSize; BList fItemInfos; diff --git a/src/kits/app/Message3.cpp b/src/kits/app/Message3.cpp index 198d3cf308..8ca3e09f7e 100644 --- a/src/kits/app/Message3.cpp +++ b/src/kits/app/Message3.cpp @@ -593,9 +593,10 @@ BMessage::IsReply() const void BMessage::PrintToStream() const { - printf("\nBMessage: what = '%c%c%c%c' (0x%lX or %ld)\n", - (uint8)(what >> 24), (uint8)(what >> 16), (uint8)(what >> 8), - (uint8)what, what, what); + printf("\nBMessage: what = "); + printf("%c%c%c%c", (uint8)(what >> 24), (uint8)(what >> 16), + (uint8)(what >> 8), (uint8)what); + printf(" (0x%lX or %ld)\n", what, what); fBody->PrintToStream(); } @@ -1053,7 +1054,8 @@ BMessage::Find ## fnName(const char *name, int32 index, TYPE *p) const \ status_t error = B_OK; \ \ *p = TYPE(); \ - error = fBody->FindData(name, TYPESPEC, index, (const void **)&ptr, &bytes); \ + error = fBody->FindData(name, TYPESPEC, index, (const void **)&ptr, \ + &bytes); \ \ if (error == B_OK) \ memcpy(p, ptr, sizeof(TYPE)); \ diff --git a/src/kits/app/MessageBody3.cpp b/src/kits/app/MessageBody3.cpp index 5a3d52465f..a36fe8e576 100644 --- a/src/kits/app/MessageBody3.cpp +++ b/src/kits/app/MessageBody3.cpp @@ -12,6 +12,7 @@ #include #include #include "MessageBody3.h" +#include "MessageField3.h" #include "MessageUtils3.h" namespace BPrivate { @@ -237,10 +238,9 @@ BMessageBody::Unflatten(BDataIO *stream, int32 length) int32 offset = 0; uint8 *location = (uint8 *)fFlatBuffer.Buffer(); - while (offset < length && *location & MSG_FLAG_VALID) { + while (offset < error && *location & MSG_FLAG_VALID) { BMessageField *field = new BMessageField(this); int32 fieldLength = field->Unflatten(offset); - //PrintToStream(); if (fieldLength <= 0) { field->MakeEmpty(); diff --git a/src/kits/app/MessageField3.cpp b/src/kits/app/MessageField3.cpp index 8ff80272aa..ec022bd978 100644 --- a/src/kits/app/MessageField3.cpp +++ b/src/kits/app/MessageField3.cpp @@ -14,7 +14,7 @@ namespace BPrivate { -#define DATA_OFFSET (fOffset + sizeof(FieldHeader) + fHeader->nameLength) +#define DATA_OFFSET (fOffset + fDataOffset) inline int32 round_to_8(int32 length) @@ -28,18 +28,22 @@ BMessageField::BMessageField(BMessageBody *parent, int32 offset, const char *name, type_code type) : fParent(parent), fOffset(offset), - fItemSize(0) + fDataOffset(0), + fFixedSize(false), + fItemSize(0), + fItemInfos(5), + fNext(NULL) { // insert space needed for the header fParent->FlatInsert(fOffset, 0, sizeof(FieldHeader)); - // create and fill header - fHeader = (FieldHeader *)(fParent->FlatBuffer() + fOffset); - fHeader->type = type; - fHeader->flags = MSG_FLAG_VALID; - fHeader->count = 0; - fHeader->dataSize = 0; - fHeader->nameLength = 0; + // fill the header + FieldHeader *header = Header(); + header->type = type; + header->flags = MSG_FLAG_VALID; + header->count = 0; + header->dataSize = 0; + header->nameLength = 0; SetName(name); } @@ -48,13 +52,11 @@ BMessageField::BMessageField(BMessageBody *parent, int32 offset, BMessageField::BMessageField(BMessageBody *parent) : fParent(parent), fOffset(0), - fHeader(NULL), - fItemSize(0) -{ -} - - -BMessageField::~BMessageField() + fDataOffset(0), + fFixedSize(false), + fItemSize(0), + fItemInfos(5), + fNext(NULL) { } @@ -65,18 +67,23 @@ BMessageField::Unflatten(int32 _offset) fOffset = _offset; // field is already present, just tap into it - fHeader = (FieldHeader *)(fParent->FlatBuffer() + fOffset); + FieldHeader *header = Header(); + fDataOffset = sizeof(FieldHeader) + header->nameLength; + fFixedSize = header->flags & MSG_FLAG_FIXED_SIZE; - if (fHeader->flags & MSG_FLAG_FIXED_SIZE) { - if (fHeader->count > 0) - fItemSize = fHeader->dataSize / fHeader->count; - return sizeof(FieldHeader) + fHeader->nameLength + fHeader->count * fItemSize; + if (header->nameLength == 0) + return 0; + + if (fFixedSize) { + if (header->count > 0) + fItemSize = header->dataSize / header->count; + return fDataOffset + header->count * fItemSize; } // create the item info list int32 offset = 0; uint8 *location = fParent->FlatBuffer() + DATA_OFFSET; - for (int32 index = 0; index < fHeader->count; index++) { + for (int32 index = 0; index < header->count; index++) { ItemInfo *info = new ItemInfo(offset); info->length = *(size_t *)location; info->paddedLength = round_to_8(info->length); @@ -86,25 +93,22 @@ BMessageField::Unflatten(int32 _offset) location += info->paddedLength; } - return sizeof(FieldHeader) + fHeader->nameLength + offset; -} - - -void -BMessageField::SetOffset(int32 offset) -{ - fOffset = offset; - fHeader = (FieldHeader *)(fParent->FlatBuffer() + fOffset); + return fDataOffset + offset; } void BMessageField::SetName(const char *newName) { + FieldHeader *header = Header(); + int32 newLength = min_c(strlen(newName), 254) + 1; - char *buffer = (char *)fParent->FlatInsert(fOffset + sizeof(FieldHeader), fHeader->nameLength, newLength); - strcpy(buffer, newName); - fHeader->nameLength = newLength; + char *buffer = (char *)fParent->FlatInsert(fOffset + sizeof(FieldHeader), header->nameLength, newLength); + strncpy(buffer, newName, newLength); + buffer[newLength] = 0; + + header->nameLength = newLength; + fDataOffset = sizeof(FieldHeader) + newLength; } @@ -118,12 +122,13 @@ BMessageField::Name() const status_t BMessageField::SetFixedSize(int32 itemSize) { - if ((fItemSize > 0 && fItemSize != itemSize) - || fItemInfos.CountItems() > 0) + if (fItemInfos.CountItems() > 0 + && (fItemSize > 0 && fItemSize != itemSize)) return B_BAD_VALUE; fItemSize = itemSize; - fHeader->flags |= MSG_FLAG_FIXED_SIZE; + Header()->flags |= MSG_FLAG_FIXED_SIZE; + fFixedSize = true; return B_OK; } @@ -138,16 +143,18 @@ BMessageField::AddItem(const void *item, ssize_t length) uint8 * BMessageField::AddItem(ssize_t length) { - if (fHeader->flags & MSG_FLAG_FIXED_SIZE) { - int32 offset = DATA_OFFSET + (fHeader->count * fItemSize); - fHeader->dataSize += fItemSize; - fHeader->count++; + FieldHeader *header = Header(); + + if (fFixedSize) { + int32 offset = DATA_OFFSET + (header->count * fItemSize); + header->dataSize += fItemSize; + header->count++; return fParent->FlatInsert(offset, 0, fItemSize); } int32 newOffset = 0; - if (fHeader->count > 0) { - ItemInfo *info = (ItemInfo *)fItemInfos.ItemAt(fHeader->count - 1); + if (header->count > 0) { + ItemInfo *info = (ItemInfo *)fItemInfos.ItemAt(header->count - 1); newOffset = info->offset + info->paddedLength; } @@ -155,8 +162,8 @@ BMessageField::AddItem(ssize_t length) newInfo->paddedLength = round_to_8(length); fItemInfos.AddItem(newInfo); - fHeader->dataSize += newInfo->paddedLength; - fHeader->count++; + header->dataSize += newInfo->paddedLength; + header->count++; uint8 *result = fParent->FlatInsert(DATA_OFFSET + newInfo->offset, 0, newInfo->paddedLength); *(int32 *)result = length; @@ -174,7 +181,7 @@ BMessageField::ReplaceItem(int32 index, const void *newItem, ssize_t length) uint8 * BMessageField::ReplaceItem(int32 index, ssize_t length) { - if (fHeader->flags & MSG_FLAG_FIXED_SIZE) + if (fFixedSize) return fParent->FlatBuffer() + DATA_OFFSET + (index * fItemSize); ItemInfo *info = (ItemInfo *)fItemInfos.ItemAt(index); @@ -187,10 +194,11 @@ BMessageField::ReplaceItem(int32 index, ssize_t length) return result + sizeof(int32); } + FieldHeader *header = Header(); int32 change = newLength - info->paddedLength; - for (int32 i = index + 1; i < fHeader->count; i++) + for (int32 i = index + 1; i < header->count; i++) ((ItemInfo *)fItemInfos.ItemAt(i))->offset += change; - fHeader->dataSize += change; + header->dataSize += change; int32 oldLength = info->paddedLength; info->length = length; @@ -205,7 +213,7 @@ BMessageField::ReplaceItem(int32 index, ssize_t length) void * BMessageField::ItemAt(int32 index, ssize_t *size) { - if (fHeader->flags & MSG_FLAG_FIXED_SIZE) { + if (fFixedSize) { if (size) *size = fItemSize; @@ -224,21 +232,23 @@ BMessageField::ItemAt(int32 index, ssize_t *size) void BMessageField::RemoveItem(int32 index) { - if (fHeader->flags & MSG_FLAG_FIXED_SIZE) { + FieldHeader *header = Header(); + + if (fFixedSize) { fParent->FlatInsert(DATA_OFFSET + (index * fItemSize), fItemSize, 0); - fHeader->dataSize -= fItemSize; - fHeader->count--; + header->dataSize -= fItemSize; + header->count--; return; } ItemInfo *info = (ItemInfo *)fItemInfos.RemoveItem(index); - for (int32 i = index; i < fHeader->count; i++) + for (int32 i = index; i < header->count; i++) ((ItemInfo *)fItemInfos.ItemAt(i))->offset -= info->paddedLength; fParent->FlatInsert(DATA_OFFSET + info->offset, info->paddedLength, 0); - fHeader->dataSize -= info->paddedLength; - fHeader->count--; + header->dataSize -= info->paddedLength; + header->count--; delete info; } @@ -246,7 +256,8 @@ BMessageField::RemoveItem(int32 index) void BMessageField::PrintToStream() const { - printf("\tname: \"%s\"; items: %ld; dataSize: %ld; flags: %02x;", Name(), fHeader->count, fHeader->dataSize, fHeader->flags); + FieldHeader *header = Header(); + printf("\tname: \"%s\"; items: %ld; dataSize: %ld; flags: %02x; offset: %ld", Name(), header->count, header->dataSize, header->flags, fOffset); // ToDo: implement for real } @@ -264,10 +275,10 @@ BMessageField::MakeEmpty() void BMessageField::RemoveSelf() { - // remove ourselfs from the flat buffer - fParent->FlatInsert(fOffset, sizeof(FieldHeader) + fHeader->nameLength + fHeader->dataSize, 0); + // remove ourself from the flat buffer + FieldHeader *header = Header(); + fParent->FlatInsert(fOffset, fDataOffset + header->dataSize, 0); fOffset = 0; - fHeader = NULL; } } // namespace BPrivate