mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-01-19 03:57:14 +01:00
4a6bfc086c
Switched to POCO library for unified platform/library interface. Deprecated the external module API. It was creating more problems than solving. Removed most built-in libraries in favor of system libraries for easier maintenance. Cleaned and secured code with help from static analyzers.
343 lines
6.5 KiB
C++
343 lines
6.5 KiB
C++
//
|
|
// Object.cpp
|
|
//
|
|
// Library: JSON
|
|
// Package: JSON
|
|
// Module: Object
|
|
//
|
|
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
|
// and Contributors.
|
|
//
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
//
|
|
|
|
|
|
#include "Poco/JSON/Object.h"
|
|
#include <iostream>
|
|
#include <sstream>
|
|
|
|
|
|
using Poco::Dynamic::Var;
|
|
|
|
|
|
namespace Poco {
|
|
namespace JSON {
|
|
|
|
|
|
Object::Object(int options):
|
|
_preserveInsOrder((options & Poco::JSON_PRESERVE_KEY_ORDER) != 0),
|
|
_escapeUnicode((options & Poco::JSON_ESCAPE_UNICODE) != 0),
|
|
_modified(false)
|
|
{
|
|
}
|
|
|
|
|
|
Object::Object(const Object& other) : _values(other._values),
|
|
_preserveInsOrder(other._preserveInsOrder),
|
|
_escapeUnicode(other._escapeUnicode),
|
|
_pStruct(!other._modified ? other._pStruct : 0),
|
|
_modified(other._modified)
|
|
{
|
|
syncKeys(other._keys);
|
|
}
|
|
|
|
|
|
Object::Object(Object&& other) noexcept:
|
|
_values(std::move(other._values)),
|
|
_keys(std::move(other._keys)),
|
|
_preserveInsOrder(other._preserveInsOrder),
|
|
_escapeUnicode(other._escapeUnicode),
|
|
_pStruct(std::move(other._pStruct)),
|
|
_pOrdStruct(std::move(other._pOrdStruct)),
|
|
_modified(other._modified)
|
|
{
|
|
}
|
|
|
|
|
|
Object::~Object()
|
|
{
|
|
}
|
|
|
|
|
|
Object &Object::operator = (const Object &other)
|
|
{
|
|
if (&other != this)
|
|
{
|
|
_values = other._values;
|
|
_keys = other._keys;
|
|
_preserveInsOrder = other._preserveInsOrder;
|
|
_escapeUnicode = other._escapeUnicode;
|
|
_pStruct = !other._modified ? other._pStruct : 0;
|
|
_modified = other._modified;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
|
|
Object& Object::operator = (Object&& other) noexcept
|
|
{
|
|
_values = std::move(other._values);
|
|
_keys = std::move(other._keys);
|
|
_preserveInsOrder = other._preserveInsOrder;
|
|
_escapeUnicode = other._escapeUnicode;
|
|
_pStruct = std::move(other._pStruct);
|
|
_pOrdStruct = std::move(other._pOrdStruct);
|
|
_modified = other._modified;
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
void Object::syncKeys(const KeyList& keys)
|
|
{
|
|
if(_preserveInsOrder)
|
|
{
|
|
// update iterators in _keys to point to copied _values
|
|
for(KeyList::const_iterator it = keys.begin(); it != keys.end(); ++it)
|
|
{
|
|
ValueMap::const_iterator itv = _values.find((*it)->first);
|
|
poco_assert (itv != _values.end());
|
|
_keys.push_back(itv);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Var Object::get(const std::string& key) const
|
|
{
|
|
ValueMap::const_iterator it = _values.find(key);
|
|
if (it != _values.end())
|
|
{
|
|
return it->second;
|
|
}
|
|
|
|
return Var();
|
|
}
|
|
|
|
|
|
Array::Ptr Object::getArray(const std::string& key) const
|
|
{
|
|
ValueMap::const_iterator it = _values.find(key);
|
|
if ((it != _values.end()) && (it->second.type() == typeid(Array::Ptr)))
|
|
{
|
|
return it->second.extract<Array::Ptr>();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
Object::Ptr Object::getObject(const std::string& key) const
|
|
{
|
|
ValueMap::const_iterator it = _values.find(key);
|
|
if ((it != _values.end()) && (it->second.type() == typeid(Object::Ptr)))
|
|
{
|
|
return it->second.extract<Object::Ptr>();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void Object::getNames(NameList& names) const
|
|
{
|
|
names.clear();
|
|
if (_preserveInsOrder)
|
|
{
|
|
for(KeyList::const_iterator it = _keys.begin(); it != _keys.end(); ++it)
|
|
{
|
|
names.push_back((*it)->first);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(ValueMap::const_iterator it = _values.begin(); it != _values.end(); ++it)
|
|
{
|
|
names.push_back(it->first);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Object::NameList Object::getNames() const
|
|
{
|
|
NameList names;
|
|
getNames(names);
|
|
return names;
|
|
}
|
|
|
|
|
|
void Object::stringify(std::ostream& out, unsigned int indent, int step) const
|
|
{
|
|
if (step < 0) step = indent;
|
|
|
|
if (!_preserveInsOrder)
|
|
doStringify(_values, out, indent, step);
|
|
else
|
|
doStringify(_keys, out, indent, step);
|
|
}
|
|
|
|
|
|
const std::string& Object::getKey(KeyList::const_iterator& iter) const
|
|
{
|
|
ValueMap::const_iterator it = _values.begin();
|
|
ValueMap::const_iterator end = _values.end();
|
|
for (; it != end; ++it)
|
|
{
|
|
if (it == *iter) return it->first;
|
|
}
|
|
|
|
throw NotFoundException((*iter)->first);
|
|
}
|
|
|
|
|
|
Object& Object::set(const std::string& key, const Dynamic::Var& value)
|
|
{
|
|
std::pair<ValueMap::iterator, bool> ret = _values.insert(ValueMap::value_type(key, value));
|
|
if (!ret.second) ret.first->second = value;
|
|
if (_preserveInsOrder)
|
|
{
|
|
KeyList::iterator it = _keys.begin();
|
|
KeyList::iterator end = _keys.end();
|
|
for (; it != end; ++it)
|
|
{
|
|
if (key == (*it)->first) return *this;
|
|
}
|
|
_keys.push_back(ret.first);
|
|
}
|
|
_modified = true;
|
|
return *this;
|
|
}
|
|
|
|
|
|
Poco::DynamicStruct Object::makeStruct(const Object::Ptr& obj)
|
|
{
|
|
return makeStructImpl<Poco::DynamicStruct>(obj);
|
|
}
|
|
|
|
|
|
Poco::OrderedDynamicStruct Object::makeOrderedStruct(const Object::Ptr& obj)
|
|
{
|
|
return makeStructImpl<Poco::OrderedDynamicStruct>(obj);
|
|
}
|
|
|
|
/*
|
|
void Object::resetOrdDynStruct() const
|
|
{
|
|
if (!_pOrdStruct)
|
|
_pOrdStruct = new Poco::OrderedDynamicStruct;
|
|
else
|
|
_pOrdStruct->clear();
|
|
}
|
|
*/
|
|
|
|
|
|
/*
|
|
void Object::resetDynStruct() const
|
|
{
|
|
if (!_pStruct)
|
|
_pStruct = new Poco::DynamicStruct;
|
|
else
|
|
_pStruct->clear();
|
|
}*/
|
|
|
|
|
|
Object::operator const Poco::DynamicStruct& () const
|
|
{
|
|
if (!_values.size())
|
|
{
|
|
resetDynStruct(_pStruct);
|
|
}
|
|
else if (_modified)
|
|
{
|
|
ValueMap::const_iterator it = _values.begin();
|
|
ValueMap::const_iterator end = _values.end();
|
|
resetDynStruct(_pStruct);
|
|
for (; it != end; ++it)
|
|
{
|
|
if (isObject(it))
|
|
{
|
|
_pStruct->insert(it->first, makeStruct(getObject(it->first)));
|
|
}
|
|
else if (isArray(it))
|
|
{
|
|
_pStruct->insert(it->first, Poco::JSON::Array::makeArray(getArray(it->first)));
|
|
}
|
|
else
|
|
{
|
|
_pStruct->insert(it->first, it->second);
|
|
}
|
|
}
|
|
}
|
|
|
|
return *_pStruct;
|
|
}
|
|
|
|
|
|
Object::operator const Poco::OrderedDynamicStruct& () const
|
|
{
|
|
if (!_values.size())
|
|
{
|
|
resetDynStruct(_pOrdStruct);
|
|
}
|
|
else if (_modified)
|
|
{
|
|
if (_preserveInsOrder)
|
|
{
|
|
KeyList::const_iterator it = _keys.begin();
|
|
KeyList::const_iterator end = _keys.end();
|
|
resetDynStruct(_pOrdStruct);
|
|
for (; it != end; ++it)
|
|
{
|
|
if (isObject((*it)->first))
|
|
{
|
|
_pOrdStruct->insert((*it)->first, makeOrderedStruct(getObject((*it)->first)));
|
|
}
|
|
else if (isArray((*it)->first))
|
|
{
|
|
_pOrdStruct->insert((*it)->first, Poco::JSON::Array::makeArray(getArray((*it)->first)));
|
|
}
|
|
else
|
|
{
|
|
_pOrdStruct->insert((*it)->first, (*it)->second);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ValueMap::const_iterator it = _values.begin();
|
|
ValueMap::const_iterator end = _values.end();
|
|
resetDynStruct(_pOrdStruct);
|
|
for (; it != end; ++it)
|
|
{
|
|
if (isObject(it))
|
|
{
|
|
_pOrdStruct->insert(it->first, makeOrderedStruct(getObject(it->first)));
|
|
}
|
|
else if (isArray(it))
|
|
{
|
|
_pOrdStruct->insert(it->first, Poco::JSON::Array::makeArray(getArray(it->first)));
|
|
}
|
|
else
|
|
{
|
|
_pOrdStruct->insert(it->first, it->second);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return *_pOrdStruct;
|
|
}
|
|
|
|
|
|
void Object::clear()
|
|
{
|
|
_values.clear();
|
|
_keys.clear();
|
|
_pStruct = 0;
|
|
_modified = true;
|
|
}
|
|
|
|
|
|
} } // namespace Poco::JSON
|