// // Query.cpp // // $Id$ // // Library: JSON // Package: JSON // Module: Query // // Copyright (c) 2012, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization // obtaining a copy of the software and accompanying documentation covered by // this license (the "Software") to use, reproduce, display, distribute, // execute, and transmit the Software, and to prepare derivative works of the // Software, and to permit third-parties to whom the Software is furnished to // do so, all subject to the following: // // The copyright notices in the Software and this entire statement, including // the above license grant, this restriction and the following disclaimer, // must be included in all copies of the Software, in whole or in part, and // all derivative works of the Software, unless such copies or derivative // works are solely in the form of machine-executable object code generated by // a source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // #include "Poco/JSON/Query.h" #include "Poco/StringTokenizer.h" #include "Poco/RegularExpression.h" #include "Poco/NumberParser.h" #include using Poco::Dynamic::Var; namespace Poco { namespace JSON { Query::Query(const Var& source): _source(source) { } Query::~Query() { } Object::Ptr Query::findObject(const std::string& path) const { Object::Ptr obj; Var result = find(path); if ( result.type() == typeid(Object::Ptr) ) { obj = result.extract(); } return obj; } Array::Ptr Query::findArray(const std::string& path) const { Array::Ptr arr; Var result = find(path); if ( result.type() == typeid(Array::Ptr) ) { arr = result.extract(); } return arr; } Var Query::find(const std::string& path) const { Var result = _source; StringTokenizer tokenizer(path, "."); for(StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); token++) { if ( !result.isEmpty() ) { std::vector indexes; RegularExpression::MatchVec matches; int firstOffset = -1; int offset = 0; RegularExpression regex("\\[([0-9]+)\\]"); while(regex.match(*token, offset, matches) > 0 ) { if ( firstOffset == -1 ) { firstOffset = static_cast(matches[0].offset); } std::string num = token->substr(matches[1].offset, matches[1].length); indexes.push_back(NumberParser::parse(num)); offset = static_cast(matches[0].offset + matches[0].length); } std::string name(*token); if ( firstOffset != -1 ) { name = name.substr(0, firstOffset); } if ( name.length() > 0 ) { if ( result.type() == typeid(Object::Ptr) ) { Object::Ptr o = result.extract(); result = o->get(name); } } if (!result.isEmpty() && !indexes.empty() ) { for(std::vector::iterator it = indexes.begin(); it != indexes.end(); ++it ) { if ( result.type() == typeid(Array::Ptr) ) { Array::Ptr array = result.extract(); result = array->get(*it); if ( result.isEmpty() ) { break; } } } } } } return result; } } } // Namespace Poco::JSON