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

View File

@ -66,9 +66,22 @@ public:
ValueLocation* parentLocation = fParent->Location();
ValueLocation* location;
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)
return error;
@ -95,7 +108,8 @@ BMessageValueNode::BMessageValueNode(ValueNodeChild* nodeChild,
fLoader(NULL),
fHeader(NULL),
fFields(NULL),
fData(NULL)
fData(NULL),
fIsFlatMessage(false)
{
fType->AcquireReference();
}
@ -125,6 +139,9 @@ status_t
BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
ValueLocation*& _location, Value*& _value)
{
fIsFlatMessage = dynamic_cast<BMessageFieldNodeChild*>(NodeChild())
!= NULL;
// get the location
ValueLocation* location = NodeChild()->Location();
if (location == NULL)
@ -155,77 +172,83 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
CompoundType* baseType = dynamic_cast<CompoundType*>(fType);
for (int32 i = 0; i < baseType->CountDataMembers(); i++) {
DataMember* member = baseType->DataMemberAt(i);
if (strcmp(member->Name(), "fHeader") == 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;
return error;
}
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++) {
DataMember* member = baseType->DataMemberAt(i);
if (strcmp(member->Name(), "fHeader") == 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;
return error;
}
error = valueLoader->LoadValue(memberLocation, valueType,
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));
error = valueLoader->LoadValue(memberLocation, valueType,
false, headerAddress);
delete memberLocation;
return error;
}
error = valueLoader->LoadValue(memberLocation, valueType,
false, what);
delete memberLocation;
if (error != B_OK)
return error;
} else if (strcmp(member->Name(), "fFields") == 0) {
error = baseType->ResolveDataMemberLocation(member,
*location, memberLocation);
if (error != B_OK) {
TRACE_LOCALS("BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of field member: %s\n",
strerror(error));
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;
return error;
}
error = valueLoader->LoadValue(memberLocation, valueType,
false, what);
delete memberLocation;
return error;
}
error = valueLoader->LoadValue(memberLocation, valueType,
false, fieldAddress);
delete memberLocation;
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));
if (error != B_OK)
return error;
} else if (strcmp(member->Name(), "fFields") == 0) {
error = baseType->ResolveDataMemberLocation(member,
*location, memberLocation);
if (error != B_OK) {
TRACE_LOCALS(
"BMessageValueNode::ResolvedLocationAndValue(): "
"failed to resolve location of field member: %s\n",
strerror(error));
delete memberLocation;
return error;
}
error = valueLoader->LoadValue(memberLocation, valueType,
false, fieldAddress);
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,
false, fDataLocation);
delete memberLocation;
if (error != B_OK)
return error;
memberLocation = NULL;
}
memberLocation = NULL;
}
TRACE_LOCALS("BMessage: what: 0x%" B_PRIx32 ", result: %ld\n",
what.ToUInt32(), error);
fHeader = new(std::nothrow) BMessage::message_header();
if (fHeader == NULL)
return B_NO_MEMORY;
@ -235,10 +258,20 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
headerAddress.ToUInt64(), error);
if (error != B_OK)
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(
BMessage::field_header);
if (fIsFlatMessage)
fDataLocation.SetTo(fieldAddress.ToUInt64() + fieldsSize);
size_t totalSize = sizeof(BMessage::message_header) + fieldsSize + fHeader->data_size;
uint8* messageBuffer = new(std::nothrow) uint8[totalSize];
if (messageBuffer == NULL)
@ -296,32 +329,22 @@ BMessageValueNode::CreateChildren()
return B_OK;
DataMember* member = NULL;
Type* whatType = NULL;
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++) {
member = messageType->DataMemberAt(i);
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;
}
}
ValueNodeChild* whatNode
= new(std::nothrow) BMessageWhatNodeChild(this, member, whatType);
if (whatNode == NULL)
return B_NO_MEMORY;
whatNode->SetContainer(fContainer);
fChildren.AddItem(whatNode);
char* name;
type_code type;
int32 count;

View File

@ -36,6 +36,7 @@ public:
virtual ValueNodeChild* ChildAt(int32 index) const;
private:
status_t _GetTypeForTypeCode(type_code type,
Type*& _type);
status_t _FindField(const char* name,
@ -53,6 +54,7 @@ private:
// for GCC2
friend class BMessageFieldNode;
friend class BMessageFieldNodeChild;
friend class BMessageWhatNodeChild;
typedef BObjectList<ValueNodeChild> ChildNodeList;
@ -66,6 +68,7 @@ private:
BMessage::field_header* fFields;
uint8* fData;
BMessage fMessage;
bool fIsFlatMessage;
};