* Fully switch to the Haiku message format so that it is also used for on-disk

storage.
* Remove reduntant information from the header (field_count vs. fields_size).
* Remove checksums previously used to validate the message passing by area
  mechanism.
* Move variables that are purely used by the instance out of the header and into
  the BMessage object.
* Use more sensible types for the different message fields.
* Reduce some field sizes to realistic values.
* Make size_t values into uint32 values so the message format will not change
  when later moving to 64 bits.
* Pack the structures used for flat message storage so it doesn't change
  because of padding.
* Fix message passing by area. It never worked because the created area was
  never actually filled with any data!
* Some more allocation checks with graceful fallbacks (should be all now).
* Some more checks for negative index values (should also be all now).
* Make printing more inline with how the rest of the class works and make some
  of the output more consistent.
* Also add the new unsigned types to PrintToStream() output.
* Fix printing of unknown types and invalid BMessages, it would always have
  printed only the first entry respectively the same error.
* Added some clarifying comments.
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32039 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2009-07-31 22:19:36 +00:00
parent 2252911973
commit d7a16b238f
7 changed files with 398 additions and 367 deletions
+9 -7
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2007, Haiku Inc. All Rights Reserved. * Copyright 2005-2009, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -291,10 +291,12 @@ class BMessage {
status_t _FlattenToArea(message_header **_header) const; status_t _FlattenToArea(message_header **_header) const;
status_t _CopyForWrite(); status_t _CopyForWrite();
status_t _Reference(message_header *header); status_t _Reference();
status_t _Dereference(); status_t _Dereference();
status_t _ResizeData(int32 offset, int32 change); status_t _ValidateMessage();
status_t _ResizeData(uint32 offset, int32 change);
uint32 _HashName(const char* name) const; uint32 _HashName(const char* name) const;
status_t _FindField(const char* name, type_code type, status_t _FindField(const char* name, type_code type,
@@ -303,9 +305,6 @@ class BMessage {
bool isFixedSize, field_header** _result); bool isFixedSize, field_header** _result);
status_t _RemoveField(field_header* field); status_t _RemoveField(field_header* field);
ssize_t _NativeFlattenedSize() const;
status_t _NativeFlatten(char *buffer, ssize_t size) const;
status_t _NativeFlatten(BDataIO *stream, ssize_t *size = NULL) const;
void _PrintToStream(const char* indent) const; void _PrintToStream(const char* indent) const;
private: private:
@@ -313,12 +312,15 @@ class BMessage {
field_header* fFields; field_header* fFields;
uint8* fData; uint8* fData;
uint32 fFieldsAvailable;
size_t fDataAvailable;
mutable BMessage* fOriginal; mutable BMessage* fOriginal;
BMessage* fQueueLink; BMessage* fQueueLink;
// fQueueLink is used by BMessageQueue to build a linked list // fQueueLink is used by BMessageQueue to build a linked list
uint32 fReserved[11]; uint32 fReserved[9];
// deprecated // deprecated
BMessage(BMessage *message); BMessage(BMessage *message);
+18 -43
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2007, Haiku Inc. All rights reserved. * Copyright 2005-2009, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -14,10 +14,9 @@
#include <TokenSpace.h> #include <TokenSpace.h>
#define MESSAGE_BODY_HASH_TABLE_SIZE 10 #define MESSAGE_BODY_HASH_TABLE_SIZE 5
#define MAX_DATA_PREALLOCATION B_PAGE_SIZE * 10 #define MAX_DATA_PREALLOCATION B_PAGE_SIZE * 10
#define MAX_FIELD_PREALLOCATION 50 #define MAX_FIELD_PREALLOCATION 50
#define MAX_ITEM_PREALLOCATION B_PAGE_SIZE
static const int32 kPortMessageCode = 'pjpp'; static const int32 kPortMessageCode = 'pjpp';
@@ -30,8 +29,8 @@ enum {
MESSAGE_FLAG_IS_REPLY = 0x0008, MESSAGE_FLAG_IS_REPLY = 0x0008,
MESSAGE_FLAG_WAS_DELIVERED = 0x0010, MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020, MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
MESSAGE_FLAG_WAS_DROPPED = 0x0080, MESSAGE_FLAG_WAS_DROPPED = 0x0040,
MESSAGE_FLAG_PASS_BY_AREA = 0x0100 MESSAGE_FLAG_PASS_BY_AREA = 0x0080
}; };
@@ -42,15 +41,14 @@ enum {
struct BMessage::field_header { struct BMessage::field_header {
uint32 flags; uint16 flags;
uint16 name_length;
type_code type; type_code type;
int32 name_length; uint32 count;
int32 count; uint32 data_size;
ssize_t data_size; uint32 offset;
ssize_t allocated;
int32 offset;
int32 next_field; int32 next_field;
}; } _PACKED;
struct BMessage::message_header { struct BMessage::message_header {
@@ -58,14 +56,6 @@ struct BMessage::message_header {
uint32 what; uint32 what;
uint32 flags; uint32 flags;
ssize_t fields_size;
ssize_t data_size;
ssize_t fields_available;
ssize_t data_available;
uint32 fields_checksum;
uint32 data_checksum;
int32 target; int32 target;
int32 current_specifier; int32 current_specifier;
area_id message_area; area_id message_area;
@@ -76,8 +66,9 @@ struct BMessage::message_header {
team_id reply_team; team_id reply_team;
// body info // body info
int32 field_count; uint32 data_size;
int32 hash_table_size; uint32 field_count;
uint32 hash_table_size;
int32 hash_table[MESSAGE_BODY_HASH_TABLE_SIZE]; int32 hash_table[MESSAGE_BODY_HASH_TABLE_SIZE];
/* The hash table does contain indexes into the field list and /* The hash table does contain indexes into the field list and
@@ -86,18 +77,20 @@ struct BMessage::message_header {
The hash table must be reevaluated when we remove a field The hash table must be reevaluated when we remove a field
though. though.
*/ */
}; } _PACKED;
class BMessage::Private { class BMessage::Private {
public: public:
Private(BMessage *msg) Private(BMessage *msg)
: fMessage(msg) :
fMessage(msg)
{ {
} }
Private(BMessage &msg) Private(BMessage &msg)
: fMessage(&msg) :
fMessage(&msg)
{ {
} }
@@ -175,24 +168,6 @@ class BMessage::Private {
return fMessage->fData; return fMessage->fData;
} }
ssize_t
NativeFlattenedSize() const
{
return fMessage->_NativeFlattenedSize();
}
status_t
NativeFlatten(char *buffer, ssize_t size) const
{
return fMessage->_NativeFlatten(buffer, size);
}
status_t
NativeFlatten(BDataIO *stream, ssize_t *size) const
{
return fMessage->_NativeFlatten(stream, size);
}
status_t status_t
FlattenToArea(message_header **header) const FlattenToArea(message_header **header) const
{ {
+356 -309
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -316,7 +316,7 @@ MessageAdapter::_R5FlattenedSize(const BMessage *from)
uint8 *data = messagePrivate.GetMessageData(); uint8 *data = messagePrivate.GetMessageData();
BMessage::field_header *field = messagePrivate.GetMessageFields(); BMessage::field_header *field = messagePrivate.GetMessageFields();
for (int32 i = 0; i < header->field_count; i++, field++) { for (uint32 i = 0; i < header->field_count; i++, field++) {
// flags and type // flags and type
flattenedSize += 1 + sizeof(type_code); flattenedSize += 1 + sizeof(type_code);
@@ -343,7 +343,7 @@ MessageAdapter::_R5FlattenedSize(const BMessage *from)
else { else {
uint8 *source = data + field->offset + field->name_length; uint8 *source = data + field->offset + field->name_length;
for (int32 i = 0; i < field->count; i++) { for (uint32 i = 0; i < field->count; i++) {
ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t); ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t);
flattenedSize += pad_to_8(itemSize); flattenedSize += pad_to_8(itemSize);
source += itemSize; source += itemSize;
@@ -414,7 +414,7 @@ MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from,
// collect and add the data // collect and add the data
BMessage::field_header *field = messagePrivate.GetMessageFields(); BMessage::field_header *field = messagePrivate.GetMessageFields();
for (int32 i = 0; i < header->field_count; i++, field++) { for (uint32 i = 0; i < header->field_count; i++, field++) {
flags = R5_FIELD_FLAG_VALID; flags = R5_FIELD_FLAG_VALID;
if (field->count == 1) if (field->count == 1)
@@ -466,7 +466,7 @@ MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from,
pointer += field->data_size; pointer += field->data_size;
} else { } else {
uint8 *previous = pointer; uint8 *previous = pointer;
for (int32 i = 0; i < field->count; i++) { for (uint32 i = 0; i < field->count; i++) {
ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t); ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t);
memcpy(pointer, source, itemSize); memcpy(pointer, source, itemSize);
ssize_t paddedSize = pad_to_8(itemSize); ssize_t paddedSize = pad_to_8(itemSize);
+8 -1
View File
@@ -44,14 +44,21 @@ CalculateChecksum(const uint8 *buffer, int32 size)
status_t status_t
entry_ref_flatten(char *buffer, size_t *size, const entry_ref *ref) entry_ref_flatten(char *buffer, size_t *size, const entry_ref *ref)
{ {
if (*size < sizeof(ref->device) + sizeof(ref->directory))
return B_BUFFER_OVERFLOW;
memcpy((void *)buffer, (const void *)&ref->device, sizeof(ref->device)); memcpy((void *)buffer, (const void *)&ref->device, sizeof(ref->device));
buffer += sizeof(ref->device); buffer += sizeof(ref->device);
memcpy((void *)buffer, (const void *)&ref->directory, sizeof(ref->directory)); memcpy((void *)buffer, (const void *)&ref->directory, sizeof(ref->directory));
buffer += sizeof (ref->directory); buffer += sizeof (ref->directory);
*size -= sizeof(ref->device) + sizeof(ref->directory);
size_t nameLength = 0; size_t nameLength = 0;
if (ref->name) { if (ref->name) {
nameLength = strlen(ref->name) + 1; nameLength = strlen(ref->name) + 1;
if (*size < nameLength)
return B_BUFFER_OVERFLOW;
memcpy((void *)buffer, (const void *)ref->name, nameLength); memcpy((void *)buffer, (const void *)ref->name, nameLength);
} }
@@ -74,7 +81,7 @@ entry_ref_unflatten(entry_ref *ref, const char *buffer, size_t size)
buffer += sizeof(ref->directory); buffer += sizeof(ref->directory);
if (ref->device != -1 && size > sizeof(ref->device) if (ref->device != -1 && size > sizeof(ref->device)
+ sizeof(ref->directory)) { + sizeof(ref->directory)) {
ref->set_name(buffer); ref->set_name(buffer);
if (ref->name == NULL) { if (ref->name == NULL) {
*ref = entry_ref(); *ref = entry_ref();
+2 -2
View File
@@ -1335,10 +1335,10 @@ BView::DragMessage(BMessage* message, BBitmap* image,
// TODO: create area and flatten message into that area! // TODO: create area and flatten message into that area!
// send area info over port, not the actual message! // send area info over port, not the actual message!
int32 bufferSize = privateMessage.NativeFlattenedSize(); int32 bufferSize = message->FlattenedSize();
char* buffer = new(std::nothrow) char[bufferSize]; char* buffer = new(std::nothrow) char[bufferSize];
if (buffer != NULL) { if (buffer != NULL) {
privateMessage.NativeFlatten(buffer, bufferSize); message->Flatten(buffer, bufferSize);
fOwner->fLink->StartMessage(AS_VIEW_DRAG_IMAGE); fOwner->fLink->StartMessage(AS_VIEW_DRAG_IMAGE);
fOwner->fLink->Attach<int32>(image->_ServerToken()); fOwner->fLink->Attach<int32>(image->_ServerToken());
+1 -1
View File
@@ -608,7 +608,7 @@ MessageDeliverer::DeliverMessage(BMessage *message, MessagingTargetSet &targets,
// flatten the message // flatten the message
BMallocIO mallocIO; BMallocIO mallocIO;
status_t error = BMessage::Private(message).NativeFlatten(&mallocIO, NULL); status_t error = message->Flatten(&mallocIO, NULL);
if (error < B_OK) if (error < B_OK)
return error; return error;