* 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:
@@ -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);
|
||||||
|
|||||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user