mirror of
https://github.com/pocoproject/poco.git
synced 2026-01-02 10:43:22 +01:00
* enh(poco): Replace deprecated comments with C++ deprecated attribute. * enh(Poco): Replace some deprecated functionality in Poco sources. (#4426) * enh(Poco): Replace more deprecated functionality in Poco sources. (#4426) * fix(CMake): Variable BUILD_SHARED_LIBS must be defined properly to create valid binaries. * enh: Code improvements done while resolving deprecated functionality (#4426) * Un-deprecate LocalDateTme (#4426) * enh(Poco): Replace usage of deprecated functionality with other functions/classes (#4426) * chore(SSL): temporarily un-deprecate SSL-related functionality (#4426) * chore(SSL): temporarily un-deprecate old MongoDB protocol functionality (#4426) * enh(Poco): Minor Hash improvements (#4426) * enh(Foundation): Compile deprecated hash tests only when POCO_TEST_DEPRECATED is enabled (#4426) * enh(Net): Compile deprecated Socket::select functionality only when POCO_TEST_DEPRECATED is enabled (#4426) * enh(Bonjour): Replace deprecated Socket::select with PollSet (#4426) * enh(Poco): Introduce POCO_DEPRECATED macro to have the ability to disable deprecation warnings in applications (#4426) * test(ODBC): add few asserts to testStoredProcedureDynamicVar * fix(ODBC): rename DynamicAny -> DynamicVar in tests * fix(ODBC): make Dignostics static members inline to prevent explicit instantiation warnings on windows --------- Co-authored-by: Alex Fabijanic <alex@pocoproject.org>
175 lines
3.6 KiB
C++
175 lines
3.6 KiB
C++
//
|
|
// Query.cpp
|
|
//
|
|
// Library: JSON
|
|
// Package: JSON
|
|
// Module: Query
|
|
//
|
|
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
|
// and Contributors.
|
|
//
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
//
|
|
|
|
|
|
#include "Poco/JSON/Query.h"
|
|
#include "Poco/StringTokenizer.h"
|
|
#include "Poco/RegularExpression.h"
|
|
#include "Poco/NumberParser.h"
|
|
#include <sstream>
|
|
|
|
|
|
using Poco::Dynamic::Var;
|
|
|
|
|
|
namespace Poco {
|
|
namespace JSON {
|
|
|
|
|
|
Query::Query(const Var& source): _source(source)
|
|
{
|
|
if (!source.isEmpty() &&
|
|
source.type() != typeid(Object) &&
|
|
source.type() != typeid(Object::Ptr) &&
|
|
source.type() != typeid(Array) &&
|
|
source.type() != typeid(Array::Ptr))
|
|
throw InvalidArgumentException("Only JSON Object, Array or pointers thereof allowed.");
|
|
}
|
|
|
|
|
|
Query::~Query() = default;
|
|
|
|
|
|
Object::Ptr Query::findObject(const std::string& path) const
|
|
{
|
|
Var result = find(path);
|
|
|
|
if (result.type() == typeid(Object::Ptr))
|
|
return result.extract<Object::Ptr>();
|
|
else if (result.type() == typeid(Object))
|
|
return new Object(result.extract<Object>());
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
Object& Query::findObject(const std::string& path, Object& obj) const
|
|
{
|
|
obj.clear();
|
|
|
|
Var result = find(path);
|
|
|
|
if (result.type() == typeid(Object::Ptr))
|
|
obj = *result.extract<Object::Ptr>();
|
|
else if (result.type() == typeid(Object))
|
|
obj = result.extract<Object>();
|
|
|
|
return obj;
|
|
}
|
|
|
|
|
|
Array::Ptr Query::findArray(const std::string& path) const
|
|
{
|
|
Var result = find(path);
|
|
|
|
if (result.type() == typeid(Array::Ptr))
|
|
return result.extract<Array::Ptr>();
|
|
else if (result.type() == typeid(Array))
|
|
return new Array(result.extract<Array>());
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
Array& Query::findArray(const std::string& path, Array& arr) const
|
|
{
|
|
arr.clear();
|
|
|
|
Var result = find(path);
|
|
|
|
if (result.type() == typeid(Array::Ptr))
|
|
arr = *result.extract<Array::Ptr>();
|
|
else if (result.type() == typeid(Array))
|
|
arr = result.extract<Array>();
|
|
|
|
return arr;
|
|
}
|
|
|
|
|
|
Var Query::find(const std::string& path) const
|
|
{
|
|
Var result = _source;
|
|
if (path.empty()) return result;
|
|
bool found = false;
|
|
StringTokenizer tokenizer(path, ".");
|
|
for (const auto& token: tokenizer)
|
|
{
|
|
if (!result.isEmpty())
|
|
{
|
|
std::vector<int> 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<int>(matches[0].offset);
|
|
}
|
|
std::string num(token, matches[1].offset, matches[1].length);
|
|
indexes.push_back(NumberParser::parse(num));
|
|
offset = static_cast<int>(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<Object::Ptr>();
|
|
result = o->get(name);
|
|
found = true;
|
|
}
|
|
else if (result.type() == typeid(Object))
|
|
{
|
|
Object o = result.extract<Object>();
|
|
result = o.get(name);
|
|
found = true;
|
|
}
|
|
else result.clear();
|
|
|
|
}
|
|
|
|
if (!result.isEmpty() && !indexes.empty())
|
|
{
|
|
for (const auto& i: indexes)
|
|
{
|
|
if (result.type() == typeid(Array::Ptr))
|
|
{
|
|
Array::Ptr array = result.extract<Array::Ptr>();
|
|
result = array->get(i);
|
|
if (result.isEmpty()) break;
|
|
}
|
|
else if (result.type() == typeid(Array))
|
|
{
|
|
Array array = result.extract<Array>();
|
|
result = array.get(i);
|
|
if (result.isEmpty()) break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!found) result.clear();
|
|
return result;
|
|
}
|
|
|
|
|
|
} } // namespace Poco::JSON
|