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;
ValuePieceLocation piece;
piece.SetToMemory(parentLocation->PieceAt(0).address
+ sizeof(uint32));
piece.SetSize(sizeof(uint32));
location->AddPiece(piece);
} else {
error = type->ResolveDataMemberLocation(fMember,
*parentLocation, location);
}
status_t error = type->ResolveDataMemberLocation(fMember,
*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,77 +172,83 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
CompoundType* baseType = dynamic_cast<CompoundType*>(fType); CompoundType* baseType = dynamic_cast<CompoundType*>(fType);
for (int32 i = 0; i < baseType->CountDataMembers(); i++) { if (fIsFlatMessage) {
DataMember* member = baseType->DataMemberAt(i); headerAddress.SetTo(location->PieceAt(0).address);
if (strcmp(member->Name(), "fHeader") == 0) { fieldAddress.SetTo(headerAddress.ToUInt64()
error = baseType->ResolveDataMemberLocation(member, + sizeof(BMessage::message_header));
*location, memberLocation); } else {
if (error != B_OK) { for (int32 i = 0; i < baseType->CountDataMembers(); i++) {
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): " DataMember* member = baseType->DataMemberAt(i);
"failed to resolve location of header member: %s\n", if (strcmp(member->Name(), "fHeader") == 0) {
strerror(error)); error = baseType->ResolveDataMemberLocation(member,
delete memberLocation; *location, memberLocation);
return error; if (error != B_OK) {
} TRACE_LOCALS(
"BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of header member: %s\n",
strerror(error));
delete memberLocation;
return error;
}
error = valueLoader->LoadValue(memberLocation, valueType, error = valueLoader->LoadValue(memberLocation, valueType,
false, headerAddress); false, headerAddress);
delete memberLocation;
if (error != B_OK)
return error;
} else if (strcmp(member->Name(), "what") == 0) {
error = baseType->ResolveDataMemberLocation(member,
*location, memberLocation);
if (error != B_OK) {
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of header member: %s\n",
strerror(error));
delete memberLocation; delete memberLocation;
return error; if (error != B_OK)
} return error;
error = valueLoader->LoadValue(memberLocation, valueType, } else if (strcmp(member->Name(), "what") == 0) {
false, what); error = baseType->ResolveDataMemberLocation(member,
delete memberLocation; *location, memberLocation);
if (error != B_OK) if (error != B_OK) {
return error; TRACE_LOCALS(
} else if (strcmp(member->Name(), "fFields") == 0) { "BMessageValueNode::ResolvedLocationAndValue(): "
error = baseType->ResolveDataMemberLocation(member, "failed to resolve location of header member: %s\n",
*location, memberLocation); strerror(error));
if (error != B_OK) { delete memberLocation;
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): " return error;
"failed to resolve location of field member: %s\n", }
strerror(error)); error = valueLoader->LoadValue(memberLocation, valueType,
false, what);
delete memberLocation; delete memberLocation;
return error; if (error != B_OK)
} return error;
error = valueLoader->LoadValue(memberLocation, valueType, } else if (strcmp(member->Name(), "fFields") == 0) {
false, fieldAddress); error = baseType->ResolveDataMemberLocation(member,
delete memberLocation; *location, memberLocation);
if (error != B_OK) if (error != B_OK) {
return error; TRACE_LOCALS(
} else if (strcmp(member->Name(), "fData") == 0) { "BMessageValueNode::ResolvedLocationAndValue(): "
error = baseType->ResolveDataMemberLocation(member, "failed to resolve location of field member: %s\n",
*location, memberLocation); strerror(error));
if (error != B_OK) { delete memberLocation;
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): " return error;
"failed to resolve location of data member: %s\n", }
strerror(error)); error = valueLoader->LoadValue(memberLocation, valueType,
false, fieldAddress);
delete memberLocation; delete memberLocation;
return error; if (error != B_OK)
return error;
} else if (strcmp(member->Name(), "fData") == 0) {
error = baseType->ResolveDataMemberLocation(member,
*location, memberLocation);
if (error != B_OK) {
TRACE_LOCALS(
"BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of data member: %s\n",
strerror(error));
delete memberLocation;
return error;
}
error = valueLoader->LoadValue(memberLocation, valueType,
false, fDataLocation);
delete memberLocation;
if (error != B_OK)
return error;
} }
error = valueLoader->LoadValue(memberLocation, valueType, memberLocation = NULL;
false, fDataLocation);
delete memberLocation;
if (error != B_OK)
return error;
} }
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)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -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;
fHeader->what = what.ToUInt32();
if (fIsFlatMessage)
what.SetTo(fHeader->what);
else
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,32 +329,22 @@ 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(); ValueNodeChild* whatNode
= new(std::nothrow) BMessageWhatNodeChild(this, member,
member->GetType());
if (whatNode == NULL)
return B_NO_MEMORY;
whatNode->SetContainer(fContainer);
fChildren.AddItem(whatNode);
break; break;
} }
} }
ValueNodeChild* whatNode
= new(std::nothrow) BMessageWhatNodeChild(this, member, whatType);
if (whatNode == NULL)
return B_NO_MEMORY;
whatNode->SetContainer(fContainer);
fChildren.AddItem(whatNode);
char* name; char* name;
type_code type; type_code type;
int32 count; int32 count;
@@ -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;
}; };