* 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.
*
* Authors:
@@ -291,10 +291,12 @@ class BMessage {
status_t _FlattenToArea(message_header **_header) const;
status_t _CopyForWrite();
status_t _Reference(message_header *header);
status_t _Reference();
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;
status_t _FindField(const char* name, type_code type,
@@ -303,9 +305,6 @@ class BMessage {
bool isFixedSize, field_header** _result);
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;
private:
@@ -313,12 +312,15 @@ class BMessage {
field_header* fFields;
uint8* fData;
uint32 fFieldsAvailable;
size_t fDataAvailable;
mutable BMessage* fOriginal;
BMessage* fQueueLink;
// fQueueLink is used by BMessageQueue to build a linked list
uint32 fReserved[11];
uint32 fReserved[9];
// deprecated
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.
*
* Authors:
@@ -14,10 +14,9 @@
#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_FIELD_PREALLOCATION 50
#define MAX_ITEM_PREALLOCATION B_PAGE_SIZE
static const int32 kPortMessageCode = 'pjpp';
@@ -30,8 +29,8 @@ enum {
MESSAGE_FLAG_IS_REPLY = 0x0008,
MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
MESSAGE_FLAG_WAS_DROPPED = 0x0080,
MESSAGE_FLAG_PASS_BY_AREA = 0x0100
MESSAGE_FLAG_WAS_DROPPED = 0x0040,
MESSAGE_FLAG_PASS_BY_AREA = 0x0080
};
@@ -42,15 +41,14 @@ enum {
struct BMessage::field_header {
uint32 flags;
uint16 flags;
uint16 name_length;
type_code type;
int32 name_length;
int32 count;
ssize_t data_size;
ssize_t allocated;
int32 offset;
uint32 count;
uint32 data_size;
uint32 offset;
int32 next_field;
};
} _PACKED;
struct BMessage::message_header {
@@ -58,14 +56,6 @@ struct BMessage::message_header {
uint32 what;
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 current_specifier;
area_id message_area;
@@ -76,8 +66,9 @@ struct BMessage::message_header {
team_id reply_team;
// body info
int32 field_count;
int32 hash_table_size;
uint32 data_size;
uint32 field_count;
uint32 hash_table_size;
int32 hash_table[MESSAGE_BODY_HASH_TABLE_SIZE];
/* 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
though.
*/
};
} _PACKED;
class BMessage::Private {
public:
Private(BMessage *msg)
: fMessage(msg)
:
fMessage(msg)
{
}
Private(BMessage &msg)
: fMessage(&msg)
:
fMessage(&msg)
{
}
@@ -175,24 +168,6 @@ class BMessage::Private {
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
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();
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
flattenedSize += 1 + sizeof(type_code);
@@ -343,7 +343,7 @@ MessageAdapter::_R5FlattenedSize(const BMessage *from)
else {
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);
flattenedSize += pad_to_8(itemSize);
source += itemSize;
@@ -414,7 +414,7 @@ MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from,
// collect and add the data
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;
if (field->count == 1)
@@ -466,7 +466,7 @@ MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from,
pointer += field->data_size;
} else {
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);
memcpy(pointer, source, itemSize);
ssize_t paddedSize = pad_to_8(itemSize);
+8 -1
View File
@@ -44,14 +44,21 @@ CalculateChecksum(const uint8 *buffer, int32 size)
status_t
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));
buffer += sizeof(ref->device);
memcpy((void *)buffer, (const void *)&ref->directory, sizeof(ref->directory));
buffer += sizeof (ref->directory);
*size -= sizeof(ref->device) + sizeof(ref->directory);
size_t nameLength = 0;
if (ref->name) {
nameLength = strlen(ref->name) + 1;
if (*size < nameLength)
return B_BUFFER_OVERFLOW;
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);
if (ref->device != -1 && size > sizeof(ref->device)
+ sizeof(ref->directory)) {
+ sizeof(ref->directory)) {
ref->set_name(buffer);
if (ref->name == NULL) {
*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!
// send area info over port, not the actual message!
int32 bufferSize = privateMessage.NativeFlattenedSize();
int32 bufferSize = message->FlattenedSize();
char* buffer = new(std::nothrow) char[bufferSize];
if (buffer != NULL) {
privateMessage.NativeFlatten(buffer, bufferSize);
message->Flatten(buffer, bufferSize);
fOwner->fLink->StartMessage(AS_VIEW_DRAG_IMAGE);
fOwner->fLink->Attach<int32>(image->_ServerToken());
+1 -1
View File
@@ -608,7 +608,7 @@ MessageDeliverer::DeliverMessage(BMessage *message, MessagingTargetSet &targets,
// flatten the message
BMallocIO mallocIO;
status_t error = BMessage::Private(message).NativeFlatten(&mallocIO, NULL);
status_t error = message->Flatten(&mallocIO, NULL);
if (error < B_OK)
return error;