Detect if the message node is contained in a BMessage field child. If so,

handle the message in flat format. This gets messages embedded inside other
messages working.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42388 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent
2011-07-07 21:51:50 +00:00
parent 85b41b15d9
commit f1aea13b5e
2 changed files with 111 additions and 85 deletions
@@ -66,9 +66,22 @@ public:
ValueLocation* parentLocation = fParent->Location(); ValueLocation* parentLocation = fParent->Location();
ValueLocation* location; ValueLocation* location;
CompoundType* type = dynamic_cast<CompoundType*>(fParent->GetType()); CompoundType* type = dynamic_cast<CompoundType*>(fParent->GetType());
status_t error = B_OK;
if (fParent->fIsFlatMessage) {
location = new ValueLocation();
if (location == NULL)
return B_NO_MEMORY;
status_t error = type->ResolveDataMemberLocation(fMember, ValuePieceLocation piece;
piece.SetToMemory(parentLocation->PieceAt(0).address
+ sizeof(uint32));
piece.SetSize(sizeof(uint32));
location->AddPiece(piece);
} else {
error = type->ResolveDataMemberLocation(fMember,
*parentLocation, location); *parentLocation, location);
}
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -95,7 +108,8 @@ BMessageValueNode::BMessageValueNode(ValueNodeChild* nodeChild,
fLoader(NULL), fLoader(NULL),
fHeader(NULL), fHeader(NULL),
fFields(NULL), fFields(NULL),
fData(NULL) fData(NULL),
fIsFlatMessage(false)
{ {
fType->AcquireReference(); fType->AcquireReference();
} }
@@ -125,6 +139,9 @@ status_t
BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
ValueLocation*& _location, Value*& _value) ValueLocation*& _location, Value*& _value)
{ {
fIsFlatMessage = dynamic_cast<BMessageFieldNodeChild*>(NodeChild())
!= NULL;
// get the location // get the location
ValueLocation* location = NodeChild()->Location(); ValueLocation* location = NodeChild()->Location();
if (location == NULL) if (location == NULL)
@@ -155,13 +172,19 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
CompoundType* baseType = dynamic_cast<CompoundType*>(fType); CompoundType* baseType = dynamic_cast<CompoundType*>(fType);
if (fIsFlatMessage) {
headerAddress.SetTo(location->PieceAt(0).address);
fieldAddress.SetTo(headerAddress.ToUInt64()
+ sizeof(BMessage::message_header));
} else {
for (int32 i = 0; i < baseType->CountDataMembers(); i++) { for (int32 i = 0; i < baseType->CountDataMembers(); i++) {
DataMember* member = baseType->DataMemberAt(i); DataMember* member = baseType->DataMemberAt(i);
if (strcmp(member->Name(), "fHeader") == 0) { if (strcmp(member->Name(), "fHeader") == 0) {
error = baseType->ResolveDataMemberLocation(member, error = baseType->ResolveDataMemberLocation(member,
*location, memberLocation); *location, memberLocation);
if (error != B_OK) { if (error != B_OK) {
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): " TRACE_LOCALS(
"BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of header member: %s\n", "failed to resolve location of header member: %s\n",
strerror(error)); strerror(error));
delete memberLocation; delete memberLocation;
@@ -177,7 +200,8 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
error = baseType->ResolveDataMemberLocation(member, error = baseType->ResolveDataMemberLocation(member,
*location, memberLocation); *location, memberLocation);
if (error != B_OK) { if (error != B_OK) {
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): " TRACE_LOCALS(
"BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of header member: %s\n", "failed to resolve location of header member: %s\n",
strerror(error)); strerror(error));
delete memberLocation; delete memberLocation;
@@ -192,7 +216,8 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
error = baseType->ResolveDataMemberLocation(member, error = baseType->ResolveDataMemberLocation(member,
*location, memberLocation); *location, memberLocation);
if (error != B_OK) { if (error != B_OK) {
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): " TRACE_LOCALS(
"BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of field member: %s\n", "failed to resolve location of field member: %s\n",
strerror(error)); strerror(error));
delete memberLocation; delete memberLocation;
@@ -207,7 +232,8 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
error = baseType->ResolveDataMemberLocation(member, error = baseType->ResolveDataMemberLocation(member,
*location, memberLocation); *location, memberLocation);
if (error != B_OK) { if (error != B_OK) {
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): " TRACE_LOCALS(
"BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of data member: %s\n", "failed to resolve location of data member: %s\n",
strerror(error)); strerror(error));
delete memberLocation; delete memberLocation;
@@ -221,10 +247,7 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
} }
memberLocation = NULL; memberLocation = NULL;
} }
}
TRACE_LOCALS("BMessage: what: 0x%" B_PRIx32 ", result: %ld\n",
what.ToUInt32(), error);
fHeader = new(std::nothrow) BMessage::message_header(); fHeader = new(std::nothrow) BMessage::message_header();
if (fHeader == NULL) if (fHeader == NULL)
@@ -235,10 +258,20 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
headerAddress.ToUInt64(), error); headerAddress.ToUInt64(), error);
if (error != B_OK) if (error != B_OK)
return error; return error;
if (fIsFlatMessage)
what.SetTo(fHeader->what);
else
fHeader->what = what.ToUInt32(); fHeader->what = what.ToUInt32();
TRACE_LOCALS("BMessage: what: 0x%" B_PRIx32 ", result: %ld\n",
what.ToUInt32(), error);
size_t fieldsSize = fHeader->field_count * sizeof( size_t fieldsSize = fHeader->field_count * sizeof(
BMessage::field_header); BMessage::field_header);
if (fIsFlatMessage)
fDataLocation.SetTo(fieldAddress.ToUInt64() + fieldsSize);
size_t totalSize = sizeof(BMessage::message_header) + fieldsSize + fHeader->data_size; size_t totalSize = sizeof(BMessage::message_header) + fieldsSize + fHeader->data_size;
uint8* messageBuffer = new(std::nothrow) uint8[totalSize]; uint8* messageBuffer = new(std::nothrow) uint8[totalSize];
if (messageBuffer == NULL) if (messageBuffer == NULL)
@@ -296,31 +329,21 @@ BMessageValueNode::CreateChildren()
return B_OK; return B_OK;
DataMember* member = NULL; DataMember* member = NULL;
Type* whatType = NULL;
CompoundType* messageType = dynamic_cast<CompoundType*>(fType); CompoundType* messageType = dynamic_cast<CompoundType*>(fType);
if (messageType == NULL || messageType->CountDataMembers() == 0) {
if (fContainer != NULL)
fContainer->NotifyValueNodeChildrenCreated(this);
return B_OK;
}
for (int32 i = 0; i < messageType->CountDataMembers(); i++) { for (int32 i = 0; i < messageType->CountDataMembers(); i++) {
member = messageType->DataMemberAt(i); member = messageType->DataMemberAt(i);
if (strcmp(member->Name(), "what") == 0) { if (strcmp(member->Name(), "what") == 0) {
whatType = member->GetType();
break;
}
}
ValueNodeChild* whatNode ValueNodeChild* whatNode
= new(std::nothrow) BMessageWhatNodeChild(this, member, whatType); = new(std::nothrow) BMessageWhatNodeChild(this, member,
member->GetType());
if (whatNode == NULL) if (whatNode == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
whatNode->SetContainer(fContainer); whatNode->SetContainer(fContainer);
fChildren.AddItem(whatNode); fChildren.AddItem(whatNode);
break;
}
}
char* name; char* name;
type_code type; type_code type;
@@ -36,6 +36,7 @@ public:
virtual ValueNodeChild* ChildAt(int32 index) const; virtual ValueNodeChild* ChildAt(int32 index) const;
private: private:
status_t _GetTypeForTypeCode(type_code type, status_t _GetTypeForTypeCode(type_code type,
Type*& _type); Type*& _type);
status_t _FindField(const char* name, status_t _FindField(const char* name,
@@ -53,6 +54,7 @@ private:
// for GCC2 // for GCC2
friend class BMessageFieldNode; friend class BMessageFieldNode;
friend class BMessageFieldNodeChild; friend class BMessageFieldNodeChild;
friend class BMessageWhatNodeChild;
typedef BObjectList<ValueNodeChild> ChildNodeList; typedef BObjectList<ValueNodeChild> ChildNodeList;
@@ -66,6 +68,7 @@ private:
BMessage::field_header* fFields; BMessage::field_header* fFields;
uint8* fData; uint8* fData;
BMessage fMessage; BMessage fMessage;
bool fIsFlatMessage;
}; };