BMessageValueNode now publishes a BMessageFieldNode child, which in turn

exposes child nodes for all the fields detected in the target BMessage.
Doesn't yet exposes the indices/values for each field though.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42324 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent 2011-06-26 18:35:56 +00:00
parent 6b61d62e98
commit f225c7e944
2 changed files with 488 additions and 29 deletions

View File

@ -9,7 +9,6 @@
#include <new>
#include <AutoDeleter.h>
#include <Message.h>
#include <MessagePrivate.h>
#include "Architecture.h"
@ -21,6 +20,324 @@
#include "ValueNodeContainer.h"
// #pragma mark - BMessageValueNode::BMessageFieldHeaderNode
BMessageValueNode::BMessageFieldHeaderNode::BMessageFieldHeaderNode(
BMessageFieldHeaderNodeChild *child, BMessageValueNode* parent,
const BString &name, type_code type, int32 count)
:
ValueNode(child),
fName(name),
fType(parent->GetType()),
fParent(parent),
fFieldType(type),
fFieldCount(count)
{
fParent->AcquireReference();
fType->AcquireReference();
}
BMessageValueNode::BMessageFieldHeaderNode::~BMessageFieldHeaderNode()
{
fParent->ReleaseReference();
fType->ReleaseReference();
}
Type*
BMessageValueNode::BMessageFieldHeaderNode::GetType() const
{
return fType;
}
status_t
BMessageValueNode::BMessageFieldHeaderNode::CreateChildren()
{
return B_OK;
}
int32
BMessageValueNode::BMessageFieldHeaderNode::CountChildren() const
{
return 0;
}
ValueNodeChild*
BMessageValueNode::BMessageFieldHeaderNode::ChildAt(int32 index) const
{
return NULL;
}
status_t
BMessageValueNode::BMessageFieldHeaderNode::ResolvedLocationAndValue(
ValueLoader* loader, ValueLocation *& _location, Value*& _value)
{
_location = fParent->Location();
_value = NULL;
return B_OK;
}
// #pragma mark - BMessageValueNode::BMessageFieldHeaderNodeChild
BMessageValueNode::BMessageFieldHeaderNodeChild::BMessageFieldHeaderNodeChild(
BMessageFieldNode* parent, BMessageValueNode* messageNode,
const BString &name, type_code type, int32 count)
:
ValueNodeChild(),
fName(name),
fType(parent->GetType()),
fMessageNode(messageNode),
fParent(parent),
fFieldType(type),
fFieldCount(count)
{
fMessageNode->AcquireReference();
fParent->AcquireReference();
fType->AcquireReference();
}
BMessageValueNode::BMessageFieldHeaderNodeChild::~BMessageFieldHeaderNodeChild()
{
fMessageNode->ReleaseReference();
fParent->ReleaseReference();
fType->ReleaseReference();
}
const BString&
BMessageValueNode::BMessageFieldHeaderNodeChild::Name() const
{
return fName;
}
Type*
BMessageValueNode::BMessageFieldHeaderNodeChild::GetType() const
{
return fType;
}
ValueNode*
BMessageValueNode::BMessageFieldHeaderNodeChild::Parent() const
{
return fParent;
}
bool
BMessageValueNode::BMessageFieldHeaderNodeChild::IsInternal() const
{
return true;
}
status_t
BMessageValueNode::BMessageFieldHeaderNodeChild::CreateInternalNode(
ValueNode*& _node)
{
BMessageFieldHeaderNode* node = new(std::nothrow)
BMessageFieldHeaderNode(this, fMessageNode, fName, fFieldType,
fFieldCount);
if (node == NULL)
return B_NO_MEMORY;
_node = node;
return B_OK;
}
status_t
BMessageValueNode::BMessageFieldHeaderNodeChild::ResolveLocation(
ValueLoader* valueLoader, ValueLocation*& _location)
{
_location = fParent->Location();
return B_OK;
}
status_t
BMessageValueNode::BMessageFieldHeaderNodeChild::CreateChildren()
{
return B_OK;
}
int32
BMessageValueNode::BMessageFieldHeaderNodeChild::CountChildren() const
{
return 0;
}
ValueNodeChild*
BMessageValueNode::BMessageFieldHeaderNodeChild::ChildAt(int32 index) const
{
return NULL;
}
// #pragma mark - BMessageValueNode::BMessageFieldNode
BMessageValueNode::BMessageFieldNode::BMessageFieldNode(
BMessageFieldNodeChild *child, BMessageValueNode* parent)
:
ValueNode(child),
fType(parent->GetType()),
fParent(parent)
{
fParent->AcquireReference();
fType->AcquireReference();
}
BMessageValueNode::BMessageFieldNode::~BMessageFieldNode()
{
fParent->ReleaseReference();
fType->ReleaseReference();
}
Type*
BMessageValueNode::BMessageFieldNode::GetType() const
{
return fType;
}
status_t
BMessageValueNode::BMessageFieldNode::CreateChildren()
{
if (!fChildren.IsEmpty())
return B_OK;
char* name;
type_code type;
int32 count;
for (int32 i = 0;
fParent->fMessage.GetInfo(B_ANY_TYPE, i, &name, &type,
&count) == B_OK; i++) {
BMessageFieldHeaderNodeChild* node = new(std::nothrow)
BMessageFieldHeaderNodeChild(this, fParent, name, type, count);
if (node == NULL)
return B_NO_MEMORY;
node->SetContainer(fContainer);
fChildren.AddItem(node);
}
if (fContainer != NULL)
fContainer->NotifyValueNodeChildrenCreated(this);
return B_OK;
}
int32
BMessageValueNode::BMessageFieldNode::CountChildren() const
{
return fChildren.CountItems();
}
ValueNodeChild*
BMessageValueNode::BMessageFieldNode::ChildAt(int32 index) const
{
return fChildren.ItemAt(index);
}
status_t
BMessageValueNode::BMessageFieldNode::ResolvedLocationAndValue(
ValueLoader* loader, ValueLocation*& _location, Value*& _value)
{
_location = fParent->Location();
_value = NULL;
return B_OK;
}
// #pragma mark - BMessageValueNode::BMessageFieldNodeChild
BMessageValueNode::BMessageFieldNodeChild::BMessageFieldNodeChild(
BMessageValueNode* parent)
:
ValueNodeChild(),
fType(parent->GetType()),
fParent(parent),
fName("Fields")
{
fParent->AcquireReference();
fType->AcquireReference();
}
BMessageValueNode::BMessageFieldNodeChild::~BMessageFieldNodeChild()
{
fParent->ReleaseReference();
fType->ReleaseReference();
}
const BString&
BMessageValueNode::BMessageFieldNodeChild::Name() const
{
return fName;
}
Type*
BMessageValueNode::BMessageFieldNodeChild::GetType() const
{
return fType;
}
ValueNode*
BMessageValueNode::BMessageFieldNodeChild::Parent() const
{
return fParent;
}
bool
BMessageValueNode::BMessageFieldNodeChild::IsInternal() const
{
return true;
}
status_t
BMessageValueNode::BMessageFieldNodeChild::CreateInternalNode(
ValueNode*& _node)
{
ValueNode* node = new(std::nothrow) BMessageFieldNode(this, fParent);
if (node == NULL)
return B_NO_MEMORY;
_node = node;
return B_OK;
}
status_t
BMessageValueNode::BMessageFieldNodeChild::ResolveLocation(
ValueLoader* valueLoader, ValueLocation*& _location)
{
_location = fParent->Location();
return B_OK;
}
// #pragma mark - BMessageValueNode
@ -28,7 +345,9 @@ BMessageValueNode::BMessageValueNode(ValueNodeChild* nodeChild,
Type* type)
:
ValueNode(nodeChild),
fType(type)
fType(type),
fMessage(),
fFields(NULL)
{
fType->AcquireReference();
}
@ -70,23 +389,17 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
// load the value data
BVariant addressData;
status_t error = B_OK;
CompoundType* baseType = dynamic_cast<CompoundType*>(
fType->ResolveRawType(false));
AddressType* addressType = dynamic_cast<AddressType*>(fType);
if (addressType) {
if (addressType != NULL) {
baseType = dynamic_cast<CompoundType*>(addressType->BaseType()
->ResolveRawType(false));
error = valueLoader->LoadValue(location, valueType, false,
addressData);
} else
addressData.SetTo(location->PieceAt(0).address);
}
TRACE_LOCALS("BMessage: Address: 0x%" B_PRIx64 "\n",
addressData.ToUInt64());
_location = location;
_value = NULL;
ValueLocation* memberLocation = NULL;
@ -214,21 +527,29 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
return B_ERROR;
}
BMessage message;
error = message.Unflatten((const char *)messageBuffer);
error = fMessage.Unflatten((const char *)messageBuffer);
TRACE_LOCALS("BMessage: Unflatten result: %s\n", strerror(error));
if (error != B_OK)
return error;
message.PrintToStream();
return B_BAD_VALUE;
return B_OK;
}
status_t
BMessageValueNode::CreateChildren()
{
if (fFields == NULL) {
fFields = new(std::nothrow) BMessageFieldNodeChild(this);
if (fFields == NULL)
return B_NO_MEMORY;
fFields->SetContainer(fContainer);
}
if (fContainer != NULL)
fContainer->NotifyValueNodeChildrenCreated(this);
return B_OK;
}
@ -236,6 +557,8 @@ BMessageValueNode::CreateChildren()
int32
BMessageValueNode::CountChildren() const
{
if (fFields != NULL)
return 1;
return 0;
}
@ -243,5 +566,8 @@ BMessageValueNode::CountChildren() const
ValueNodeChild*
BMessageValueNode::ChildAt(int32 index) const
{
if (index == 0)
return fFields;
return NULL;
}

View File

@ -5,29 +5,162 @@
#ifndef BMESSAGE_VALUE_NODE_H
#define BMESSAGE_VALUE_NODE_H
#include <Message.h>
#include <ObjectList.h>
#include "ValueNode.h"
class BMessageValueNode : public ValueNode {
public:
BMessageValueNode(ValueNodeChild* nodeChild,
Type* type);
virtual ~BMessageValueNode();
BMessageValueNode(ValueNodeChild* nodeChild,
Type* type);
virtual ~BMessageValueNode();
virtual Type* GetType() const;
virtual Type* GetType() const;
virtual status_t ResolvedLocationAndValue(
ValueLoader* valueLoader,
ValueLocation*& _location,
Value*& _value);
virtual status_t ResolvedLocationAndValue(
ValueLoader* valueLoader,
ValueLocation*& _location,
Value*& _value);
virtual status_t CreateChildren();
virtual int32 CountChildren() const;
virtual ValueNodeChild* ChildAt(int32 index) const;
virtual status_t CreateChildren();
virtual int32 CountChildren() const;
virtual ValueNodeChild* ChildAt(int32 index) const;
private:
Type* fType;
class BMessageFieldNode;
class BMessageFieldNodeChild;
class BMessageFieldHeaderNode;
class BMessageFieldHeaderNodeChild;
// for GCC2
friend class BMessageFieldNode;
friend class BMessageFieldNodeChild;
friend class BMessageFieldHeaderNode;
friend class BMessageFieldHeaderNodeChild;
private:
Type* fType;
BMessage fMessage;
BMessageFieldNodeChild* fFields;
};
class BMessageValueNode::BMessageFieldHeaderNode : public ValueNode {
public:
BMessageFieldHeaderNode(
BMessageFieldHeaderNodeChild *child,
BMessageValueNode* parent,
const BString& name,
type_code type, int32 count);
virtual ~BMessageFieldHeaderNode();
virtual Type* GetType() const;
virtual status_t CreateChildren();
virtual int32 CountChildren() const;
virtual ValueNodeChild* ChildAt(int32 index) const;
virtual status_t ResolvedLocationAndValue(
ValueLoader* loader,
ValueLocation *& _location,
Value*& _value);
private:
BString fName;
Type* fType;
BMessageValueNode* fParent;
type_code fFieldType;
int32 fFieldCount;
};
class BMessageValueNode::BMessageFieldHeaderNodeChild : public ValueNodeChild {
public:
BMessageFieldHeaderNodeChild(
BMessageFieldNode* parent,
BMessageValueNode* messageNode,
const BString &name,
type_code type, int32 count);
virtual ~BMessageFieldHeaderNodeChild();
virtual const BString& Name() const;
virtual Type* GetType() const;
virtual ValueNode* Parent() const;
virtual bool IsInternal() const;
virtual status_t CreateInternalNode(
ValueNode*& _node);
virtual status_t ResolveLocation(ValueLoader* valueLoader,
ValueLocation*& _location);
virtual status_t CreateChildren();
virtual int32 CountChildren() const;
virtual ValueNodeChild* ChildAt(int32 index) const;
private:
BString fName;
Type* fType;
BMessageValueNode* fMessageNode;
BMessageFieldNode* fParent;
type_code fFieldType;
int32 fFieldCount;
};
class BMessageValueNode::BMessageFieldNode : public ValueNode {
public:
BMessageFieldNode(
BMessageFieldNodeChild *child,
BMessageValueNode* parent);
virtual ~BMessageFieldNode();
virtual Type* GetType() const;
virtual status_t CreateChildren();
virtual int32 CountChildren() const;
virtual ValueNodeChild* ChildAt(int32 index) const;
virtual status_t ResolvedLocationAndValue(
ValueLoader* loader,
ValueLocation *& _location,
Value*& _value);
private:
typedef BObjectList<BMessageFieldHeaderNodeChild>
FieldHeaderNodeList;
private:
Type* fType;
BMessageValueNode* fParent;
FieldHeaderNodeList fChildren;
};
class BMessageValueNode::BMessageFieldNodeChild : public ValueNodeChild {
public:
BMessageFieldNodeChild(
BMessageValueNode* parent);
virtual ~BMessageFieldNodeChild();
virtual const BString& Name() const;
virtual Type* GetType() const;
virtual ValueNode* Parent() const;
virtual bool IsInternal() const;
virtual status_t CreateInternalNode(ValueNode*& _node);
virtual status_t ResolveLocation(ValueLoader* valueLoader,
ValueLocation*& _location);
private:
Type* fType;
BMessageValueNode* fParent;
BString fName;
};
#endif // BMESSAGE_VALUE_NODE_H