From: 王远天 <xia...@ho...> - 2014-04-02 01:43:06
|
From: xia...@ho... To: jso...@li... Subject: Powerful Json::Path Date: Tue, 1 Apr 2014 09:54:45 +0000 Json::Value v;v["a"]["b"][0u] = 1; Json::Path p("a.b.c");const Json::Value &ref = p.resolve(v);// assert The above code with course an assert when call "resolve".That is because "resolve" do not process except conditions. const Value &Path::resolve( const Value &root ) const{ const Value *node = &root; for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) { const PathArgument &arg = *it; if ( arg.kind_ == PathArgument::kindIndex ) { if ( !node->isArray() || node->isValidIndex( arg.index_ ) ) { // Error: unable to resolve path (array value expected at position... } node = &((*node)[arg.index_]); } else if ( arg.kind_ == PathArgument::kindKey ) { if ( !node->isObject() ) { // Error: unable to resolve path (object value expected at position...) } node = &((*node)[arg.key_]); if ( node == &Value::null ) { // Error: unable to resolve path (object has no member named '' at position...) } } } return *node;} Users call "resolve" means they must take the risk of fatal error.so "Path" is useless. But Json::Path should be more powerfull.Suppose we have a function named "bad" in class Value, which specified the value itself is bad. User shall check it like below: Json::Value v;v["a"]["b"][0u] = 1; Json::Path p("a.b.c");const Json::Value &ref = p.resolve(v);// will not assert if (ref.bad()){ std::cout << "ref is bad." << std::endl; ref = 2; // any operation to bad value will cause assert} all we need to do is two step:1,declare a static member in Json::Value: static Value bad; bool bad() const { return &bad == this; }2,replace each "// Error: *" line to return Value::bad; further morewe could use Json::Path to resolve the exact type value, Like this: Json::Value v;v["a"]["b"][0u] = 1; Json::Path p("a.b[0]");Json::Integer i = p.resolveInt(v); if (i.bad()){ //do something} Wish this features will be added to new version. |