#include "pointer.hpp" #include "tree.hpp" #include "../parse.hpp" #include #include /////////////////////////////////////////////////////////////////////////////// ::json::tree::node& util::json::pointer::resolve (std::string const &path, ::json::tree::node &root) { // we only handle fragment represenations currently, which start with a '#' auto cursor = path.begin (); if (cursor == path.end () || *cursor != '#') throw std::invalid_argument ("must be fragment representation"); ++cursor; auto obj = &root; // * step over each path segment // * index into the current node // * advance the node // * repeat until we reach the end of the query string for ( ; cursor != path.end (); ) { // step over the delimiting '/' if (*cursor != '/') break; ++cursor; // find the start of the next segment (or the end of the string) // and extract the key. auto next = std::find (cursor, path.end (), '/'); std::string const key { cursor, next }; // try to index into the node and advance the node we're operating on switch (obj->type ()) { case ::json::tree::OBJECT: obj = &(*obj)[key]; break; case ::json::tree::ARRAY: obj = &(*obj)[util::parse (key)]; break; case ::json::tree::STRING: case ::json::tree::NUMBER: case ::json::tree::BOOLEAN: case ::json::tree::NONE: throw std::invalid_argument ("indexing into wrong type"); } // step to the beginning of the next component cursor = next; } return *obj; }