We now retrieve and unflatten the target BMessage successfully,
though we don't yet create child nodes for the contained fields. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42287 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -8,7 +8,9 @@
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <Message.h>
|
||||
#include <MessagePrivate.h>
|
||||
|
||||
#include "Architecture.h"
|
||||
#include "StringValue.h"
|
||||
@@ -19,6 +21,39 @@
|
||||
#include "ValueNodeContainer.h"
|
||||
|
||||
|
||||
// minimal replica of BMessage's class structure for
|
||||
// extracting fields
|
||||
class BMessageValue {
|
||||
public:
|
||||
uint32 what;
|
||||
|
||||
virtual ~BMessageValue();
|
||||
|
||||
struct message_header;
|
||||
struct field_header;
|
||||
|
||||
message_header* fHeader;
|
||||
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
|
||||
|
||||
void* fArchivingPointer;
|
||||
|
||||
uint32 fReserved[8];
|
||||
|
||||
virtual void _ReservedMessage1();
|
||||
virtual void _ReservedMessage2();
|
||||
virtual void _ReservedMessage3();
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - BMessageValueNode
|
||||
|
||||
|
||||
@@ -77,21 +112,74 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
|
||||
addressData.SetTo(location->PieceAt(0).address);
|
||||
|
||||
|
||||
TRACE_LOCALS("Address: 0x%" B_PRIx64 "\n", addressData.ToUInt64());
|
||||
TRACE_LOCALS("BMessage: Address: 0x%" B_PRIx64 "\n",
|
||||
addressData.ToUInt64());
|
||||
|
||||
uint8 buffer[sizeof(BMessage)];
|
||||
error = valueLoader->LoadRawValue(addressData, sizeof(BMessage), buffer);
|
||||
uint8 classBuffer[sizeof(BMessage)];
|
||||
error = valueLoader->LoadRawValue(addressData, sizeof(BMessage),
|
||||
classBuffer);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
#if APPS_DEBUGGER_TRACE_STACK_FRAME_LOCALS
|
||||
if (error == B_OK) {
|
||||
BMessage* message = (BMessage*)buffer;
|
||||
TRACE_LOCALS("Loaded BMessage('%c%c%c%c')\n",
|
||||
char((message->what >> 24) & 0xff),
|
||||
char((message->what >> 16) & 0xff),
|
||||
char((message->what >> 8) & 0xff),
|
||||
char(message->what & 0xff));
|
||||
BVariant headerAddress;
|
||||
BMessageValue* value = (BMessageValue*)classBuffer;
|
||||
headerAddress.SetTo((target_addr_t)value->fHeader);
|
||||
|
||||
uint8 headerBuffer[sizeof(BMessage::message_header)];
|
||||
error = valueLoader->LoadRawValue(headerAddress, sizeof(headerBuffer),
|
||||
headerBuffer);
|
||||
TRACE_LOCALS("BMessage: Header Address: 0x%" B_PRIx64 ", result: %ld\n",
|
||||
headerAddress.ToUInt64(), error);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
BMessage::message_header* header = (BMessage::message_header*)headerBuffer;
|
||||
size_t fieldsSize = header->field_count * sizeof(BMessage::field_header);
|
||||
size_t totalMessageSize = sizeof(BMessage::message_header)
|
||||
+ fieldsSize + header->data_size;
|
||||
|
||||
uint8* messageBuffer = new(std::nothrow)uint8[totalMessageSize];
|
||||
if (messageBuffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memset(messageBuffer, 0, totalMessageSize);
|
||||
|
||||
ArrayDeleter<uint8> deleter(messageBuffer);
|
||||
|
||||
// This more or less follows the logic of BMessage::Flatten
|
||||
// in order to reconstruct the flattened buffer ; thus if the
|
||||
// internal representation of that changes, this will have to
|
||||
// follow suit
|
||||
header->what = value->what;
|
||||
uint8* currentBuffer = messageBuffer;
|
||||
memcpy(currentBuffer, header,
|
||||
sizeof(BMessage::message_header));
|
||||
|
||||
if (fieldsSize > 0) {
|
||||
headerAddress.SetTo((target_addr_t)value->fFields);
|
||||
currentBuffer += sizeof(BMessage::message_header);
|
||||
error = valueLoader->LoadRawValue(headerAddress, fieldsSize,
|
||||
currentBuffer);
|
||||
TRACE_LOCALS("BMessage: Field Header Address: 0x%" B_PRIx64
|
||||
", result: %ld\n", headerAddress.ToUInt64(), error);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
headerAddress.SetTo((target_addr_t)value->fData);
|
||||
currentBuffer += fieldsSize;
|
||||
error = valueLoader->LoadRawValue(headerAddress, header->data_size,
|
||||
currentBuffer);
|
||||
TRACE_LOCALS("BMessage: Data Address: 0x%" B_PRIx64 ", result: %ld\n",
|
||||
headerAddress.ToUInt64(), error);
|
||||
if (error != B_OK)
|
||||
return B_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
BMessage message;
|
||||
error = message.Unflatten((const char *)messageBuffer);
|
||||
TRACE_LOCALS("BMessage: Unflatten result: %s\n", strerror(error));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user