Skip to content
Browse files

Assignment to Node

  • Loading branch information...
1 parent 8f5b0c4 commit 718b6099227b6a6dd597c96a55458ed56f5be5a7 Rob Meijer committed Feb 25, 2012
Showing with 88 additions and 25 deletions.
  1. +1 −1 CMakeLists.txt
  2. +65 −11 Node.cpp
  3. +12 −12 gobj/GobjectImplNode.cpp
  4. +10 −1 json-me.hpp
View
2 CMakeLists.txt
@@ -42,7 +42,7 @@ IF(GOBJ_JSON_LIBRARY)
IF(EXISTS "/usr/lib/x86_64-linux-gnu/glib-2.0/include/")
ADD_DEFINITIONS( -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/)
ENDIF()
- add_library(jsonme SHARED JsonMeLib.cpp Scalar.cpp Node.cpp ParseError.cpp gobj/GobjectLibImpl.cpp gobj/GobjectImplParser.cpp gobj/GobjectImplFsTopNode.cpp gobj/GobjectImplStringTopNode.cpp gobj/GobjectImplError.cpp gobj/GobjectImplNode.cpp gobj/GobjectImplScalar.cpp gobj/GobjectImplKeys.cpp)
+ add_library(jsonme SHARED JsonMeLib.cpp Scalar.cpp Node.cpp ParseError.cpp JsonStructureError.cpp gobj/GobjectLibImpl.cpp gobj/GobjectImplParser.cpp gobj/GobjectImplFsTopNode.cpp gobj/GobjectImplStringTopNode.cpp gobj/GobjectImplError.cpp gobj/GobjectImplNode.cpp gobj/GobjectImplScalar.cpp gobj/GobjectImplKeys.cpp)
ELSE()
message(STATUS "Found the json-glib library but not the relevant header files.")
ENDIF()
View
76 Node.cpp
@@ -27,13 +27,27 @@ namespace jsonme {
NullNode(AbstractNode const *parent):mParent(parent),mNullKeys(){}
AbstractKeys & keys() { return mNullKeys;}
jsonme::nodetype nodetype() const {return INVALID;}
- Node operator[](std::string const & name) const { return Node(0,this);}
+ Node operator[](std::string const & name) const { return Node(0,this,name);}
size_t size() const { return 0;}
- Node operator[](size_t index) const { return Node(0,this);}
+ Node operator[](size_t index) const { return Node(0,this,index);}
operator Scalar() const { return Scalar(this); }
};
+ class NullObjectMember: public NullNode {
+ std::string mKey;
+ public:
+ NullObjectMember(AbstractNode const *parent,std::string key):NullNode(parent),mKey(key){}
+ ~NullObjectMember() throw(){}
+ };
+ class NullArrayMember: public NullNode {
+ size_t mIndex;
+ public:
+ NullArrayMember(AbstractNode const *parent,size_t index):NullNode(parent),mIndex(index){}
+ ~NullArrayMember() throw(){}
+ };
+
Node::Node(AbstractNode *node):mNode(node){}
- Node::Node(AbstractNode *node,AbstractNode const *parent):mNode(new NullNode(parent)){}
+ Node::Node(AbstractNode *node,AbstractNode const *parent,std::string key):mNode(new NullObjectMember(parent,key)){}
+ Node::Node(AbstractNode *node,AbstractNode const *parent,size_t index):mNode(new NullArrayMember(parent,index)){}
//Simply forward method to the implementation.
jsonme::nodetype Node::nodetype() const {
return mNode->nodetype();
@@ -109,23 +123,63 @@ namespace jsonme {
return s.isNull();
}
Node & Node::operator=(long double i){
- Scalar s(*mNode);
- s=i;
+ switch (mNode->nodetype()) {
+ case OBJECT: //Can't assign a long double to an existing object
+ throw JsonStructureError("Can't assign a float scalar value to an existing object");
+ case ARRAY: // Can't assign a long double to an excisting array
+ throw JsonStructureError("Can't assign a float scalar value to an existing array");
+ case INVALID: //For invalid nodes try autovivification first
+ mNode->autoVivivicate(SCALAR);
+ //Intentional fall-truegh, if autoVivivicate succeeds we have an empty scalar, if it doesnt it throws.
+ case SCALAR: //Its a scalar, we can assign it a new value.
+ Scalar s(*mNode);
+ s=i;
+ }
return *this;
}
Node & Node::operator=(long long i){
- Scalar s(*mNode);
- s=i;
+ switch (mNode->nodetype()) {
+ case OBJECT: //Can't assign a long double to an existing object
+ throw JsonStructureError("Can't assign an integer scalar value to an existing object");
+ case ARRAY: // Can't assign a long double to an excisting array
+ throw JsonStructureError("Can't assign an integer scalar value to an existing array");
+ case INVALID: //For invalid nodes try autovivification first
+ mNode->autoVivivicate(SCALAR);
+ //Intentional fall-truegh, if autoVivivicate succeeds we have an empty scalar, if it doesnt it throws.
+ case SCALAR: //Its a scalar, we can assign it a new value.
+ Scalar s(*mNode);
+ s=i;
+ }
return *this;
}
Node & Node::operator=(std::string i){
- Scalar s(*mNode);
- s=i;
+ switch (mNode->nodetype()) {
+ case OBJECT: //Can't assign a long double to an existing object
+ throw JsonStructureError("Can't assign a string scalar value to an existing object");
+ case ARRAY: // Can't assign a long double to an excisting array
+ throw JsonStructureError("Can't assign an integer scalar value to an existing array");
+ case INVALID: //For invalid nodes try autovivification first
+ mNode->autoVivivicate(SCALAR);
+ //Intentional fall-truegh, if autoVivivicate succeeds we have an empty scalar, if it doesnt it throws.
+ case SCALAR: //Its a scalar, we can assign it a new value.
+ Scalar s(*mNode);
+ s=i;
+ }
return *this;
}
Node & Node::operator=(bool i){
- Scalar s(*mNode);
- s=i;
+ switch (mNode->nodetype()) {
+ case OBJECT: //Can't assign a long double to an existing object
+ throw JsonStructureError("Can't assign a boolean scalar value to an existing object");
+ case ARRAY: // Can't assign a long double to an excisting array
+ throw JsonStructureError("Can't assign a boolean scalar value to an existing array");
+ case INVALID: //For invalid nodes try autovivification first
+ mNode->autoVivivicate(SCALAR);
+ //Intentional fall-truegh, if autoVivivicate succeeds we have an empty scalar, if it doesnt it throws.
+ case SCALAR: //Its a scalar, we can assign it a new value.
+ Scalar s(*mNode);
+ s=i;
+ }
return *this;
}
}
View
24 gobj/GobjectImplNode.cpp
@@ -39,13 +39,13 @@ namespace jsonme {
Node GobjectImplNode::operator[](std::string const & name) const {
//Calling this operator on a non object returns a wrapped NullNode.
if (!mNode) {
- return Node(0,this);
+ return Node(0,this,name);
}
switch (json_node_get_node_type(mNode)) {
case JSON_NODE_OBJECT: break;
- case JSON_NODE_ARRAY: return Node(0,this);
- case JSON_NODE_VALUE: return Node(0,this);
- case JSON_NODE_NULL: return Node(0,this);
+ case JSON_NODE_ARRAY: return Node(0,this,name);
+ case JSON_NODE_VALUE: return Node(0,this,name);
+ case JSON_NODE_NULL: return Node(0,this,name);
}
JsonObject *asobject=json_node_get_object(mNode);
if (asobject) {
@@ -56,10 +56,10 @@ namespace jsonme {
return Node(new GobjectImplNode(member));
} else {
//If there uis no such property return a wrapped NullNode
- return Node(0,this);
+ return Node(0,this,name);
}
} else {
- return Node(0,this); //This is probably dead code, just there in case.
+ return Node(0,this,name); //This is probably dead code, just there in case.
}
}
@@ -85,13 +85,13 @@ namespace jsonme {
Node GobjectImplNode::operator[](size_t index) const {
//Calling this operator on a non array returns a wrapped NullNode.
if (!mNode) {
- return Node(0,this);
+ return Node(0,this,index);
}
switch (json_node_get_node_type(mNode)) {
- case JSON_NODE_OBJECT: return Node(0,this);
+ case JSON_NODE_OBJECT: return Node(0,this,index);
case JSON_NODE_ARRAY: break;
- case JSON_NODE_VALUE: return Node(0,this);
- case JSON_NODE_NULL: return Node(0,this);
+ case JSON_NODE_VALUE: return Node(0,this,index);
+ case JSON_NODE_NULL: return Node(0,this,index);
}
JsonArray *asarray=json_node_get_array(mNode);
if (asarray) {
@@ -100,10 +100,10 @@ namespace jsonme {
if (member) {
return Node(new GobjectImplNode(member)); //return the sub node.
} else {
- return Node(0,this); //Or a wraped NullNode if we can't find it.
+ return Node(0,this,index); //Or a wraped NullNode if we can't find it.
}
} else {
- return Node(0,this); //This is probably dead code, just there in case.
+ return Node(0,this,index); //This is probably dead code, just there in case.
}
}
GobjectImplNode::operator Scalar() const {
View
11 json-me.hpp
@@ -36,6 +36,13 @@ namespace jsonme {
~ParseError() throw();
const char * what() const throw();
};
+ class JsonStructureError: public std::exception {
+ std::string mMessage;
+ public:
+ JsonStructureError(std::string msg);
+ ~JsonStructureError() throw();
+ const char * what() const throw();
+ };
//The scalar has a type and can be cast to that type. Casting to any other type shall
//result in a lexical conversion if possible or a default null value if not.
class AbstractScalar {
@@ -95,14 +102,16 @@ namespace jsonme {
virtual size_t size() const=0;
virtual Node operator[](size_t index) const=0;
virtual operator Scalar() const=0;
+ void autoVivivicate(jsonme::nodetype) {} //Should be refactored, first get autovivification working the non-clean way.
};
//A value semantics proxy to the implementation specific node.
class Node: public AbstractNode, public AbstractScalar {
boost::shared_ptr<AbstractNode> mNode;
public:
// Node();
Node(AbstractNode *node);
- Node(AbstractNode *node,AbstractNode const *parent);
+ Node(AbstractNode *node,AbstractNode const *parent,std::string key);
+ Node(AbstractNode *node,AbstractNode const *parent,size_t index);
~Node() throw() {}
AbstractKeys & keys();
jsonme::nodetype nodetype() const;

0 comments on commit 718b609

Please sign in to comment.
Something went wrong with that request. Please try again.