poco/JSON/src/Object.cpp

268 lines
5.0 KiB
C++
Raw Normal View History

2012-04-29 20:09:55 +00:00
//
// Object.cpp
//
// Library: JSON
// Package: JSON
// Module: Object
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
2012-04-29 20:09:55 +00:00
//
2012-10-15 12:27:56 +00:00
2012-04-29 20:09:55 +00:00
#include "Poco/JSON/Object.h"
#include <iostream>
#include <sstream>
using Poco::Dynamic::Var;
namespace Poco {
namespace JSON {
2012-04-29 20:09:55 +00:00
Object::Object(bool preserveInsOrder):
_preserveInsOrder(preserveInsOrder),
_modified(false)
2012-04-29 20:09:55 +00:00
{
}
Object::Object(const Object& copy) : _values(copy._values),
_preserveInsOrder(copy._preserveInsOrder),
_pStruct(!copy._modified ? copy._pStruct : 0),
_modified(copy._modified)
2012-04-29 20:09:55 +00:00
{
if (_preserveInsOrder)
{
// need to update pointers in _keys to point to copied _values
for (KeyPtrList::const_iterator it = copy._keys.begin(); it != copy._keys.end(); ++it)
{
ValueMap::const_iterator itv = _values.find(**it);
poco_assert (itv != _values.end());
_keys.push_back(&itv->first);
}
}
2012-04-29 20:09:55 +00:00
}
#ifdef POCO_ENABLE_CPP11
Object::Object(Object&& other) :
_values(std::move(other._values)),
_keys(std::move(other._keys)),
_preserveInsOrder(other._preserveInsOrder),
_pStruct(!other._modified ? other._pStruct : 0),
_modified(other._modified)
{
}
Object &Object::operator= (Object &&other)
{
if (&other != this)
{
_values = std::move(other._values);
_keys = std::move(other._keys);
_preserveInsOrder = other._preserveInsOrder;
_pStruct = !other._modified ? other._pStruct : 0;
_modified = other._modified;
}
return *this;
}
#endif // POCO_ENABLE_CPP11
2012-04-29 20:09:55 +00:00
Object::~Object()
{
}
Object &Object::operator= (const Object &other)
{
if (&other != this)
{
_values = other._values;
_keys = other._keys;
_preserveInsOrder = other._preserveInsOrder;
_pStruct = !other._modified ? other._pStruct : 0;
_modified = other._modified;
}
return *this;
}
Var Object::get(const std::string& key) const
2012-04-29 20:09:55 +00:00
{
ValueMap::const_iterator it = _values.find(key);
if (it != _values.end())
2012-04-29 20:09:55 +00:00
{
return it->second;
2012-04-29 20:09:55 +00:00
}
return Var();
2012-04-29 20:09:55 +00:00
}
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)))
2012-04-29 20:09:55 +00:00
{
return it->second.extract<Array::Ptr>();
2012-04-29 20:09:55 +00:00
}
return 0;
2012-04-29 20:09:55 +00:00
}
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)))
2012-04-29 20:09:55 +00:00
{
return it->second.extract<Object::Ptr>();
2012-04-29 20:09:55 +00:00
}
return 0;
2012-04-29 20:09:55 +00:00
}
void Object::getNames(std::vector<std::string>& names) const
{
names.clear();
for (ValueMap::const_iterator it = _values.begin(); it != _values.end(); ++it)
2012-04-29 20:09:55 +00:00
{
names.push_back(it->first);
}
}
void Object::stringify(std::ostream& out, unsigned int indent, int step) const
2012-04-29 20:09:55 +00:00
{
if (step < 0) step = indent;
2012-04-29 20:09:55 +00:00
if (!_preserveInsOrder)
doStringify(_values, out, indent, step);
else
doStringify(_keys, out, indent, step);
}
2012-04-29 20:09:55 +00:00
const std::string& Object::getKey(KeyPtrList::const_iterator& iter) const
{
ValueMap::const_iterator it = _values.begin();
ValueMap::const_iterator end = _values.end();
for (; it != end; ++it)
{
2015-06-09 22:41:38 -05:00
if (it->first == **iter) return it->first;
}
2012-04-29 20:09:55 +00:00
2015-06-09 22:41:38 -05:00
throw NotFoundException(**iter);
}
2012-04-29 20:09:55 +00:00
void Object::set(const std::string& key, const Dynamic::Var& value)
{
2015-06-09 22:41:38 -05:00
std::pair<ValueMap::iterator, bool> ret = _values.insert(ValueMap::value_type(key, value));
if (!ret.second) ret.first->second = value;
if (_preserveInsOrder)
{
KeyPtrList::iterator it = _keys.begin();
KeyPtrList::iterator end = _keys.end();
for (; it != end; ++it)
{
if (key == **it) return;
}
2015-06-09 22:41:38 -05:00
_keys.push_back(&ret.first->first);
2012-04-29 20:09:55 +00:00
}
_modified = true;
2012-04-29 20:09:55 +00:00
}
2012-10-15 12:27:56 +00:00
Poco::DynamicStruct Object::makeStruct(const Object::Ptr& obj)
{
Poco::DynamicStruct ds;
ConstIterator it = obj->begin();
ConstIterator end = obj->end();
for (; it != end; ++it)
{
if (obj->isObject(it))
{
Object::Ptr pObj = obj->getObject(it->first);
DynamicStruct str = makeStruct(pObj);
ds.insert(it->first, str);
}
else if (obj->isArray(it))
{
Array::Ptr pArr = obj->getArray(it->first);
std::vector<Poco::Dynamic::Var> v = Poco::JSON::Array::makeArray(pArr);
ds.insert(it->first, v);
}
else
ds.insert(it->first, it->second);
}
return ds;
}
void Object::resetDynStruct() const
{
if (!_pStruct)
_pStruct = new Poco::DynamicStruct;
else
_pStruct->clear();
}
Object::operator const Poco::DynamicStruct& () const
{
if (!_values.size())
{
resetDynStruct();
}
else if (_modified)
{
ValueMap::const_iterator it = _values.begin();
ValueMap::const_iterator end = _values.end();
resetDynStruct();
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;
}
void Object::clear()
{
_values.clear();
_keys.clear();
_pStruct = 0;
_modified = true;
}
2012-10-15 12:27:56 +00:00
} } // namespace Poco::JSON