mirror of https://github.com/Icinga/icinga2.git
SerializeInternal(): allow to optionally not malloc() anything
This effectively just checks for circular refs.
This commit is contained in:
parent
f59f361f09
commit
e53ec2a50f
|
@ -48,6 +48,18 @@ void Namespace::Set(const String& field, const Value& value, bool overrideFrozen
|
||||||
return SetFieldByName(field, value, overrideFrozen, DebugInfo());
|
return SetFieldByName(field, value, overrideFrozen, DebugInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of elements in the namespace.
|
||||||
|
*
|
||||||
|
* @returns Number of elements.
|
||||||
|
*/
|
||||||
|
size_t Namespace::GetLength() const
|
||||||
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
|
return m_Data.size();
|
||||||
|
}
|
||||||
|
|
||||||
bool Namespace::Contains(const String& field) const
|
bool Namespace::Contains(const String& field) const
|
||||||
{
|
{
|
||||||
ObjectLock olock(this);
|
ObjectLock olock(this);
|
||||||
|
|
|
@ -88,6 +88,8 @@ public:
|
||||||
Iterator Begin();
|
Iterator Begin();
|
||||||
Iterator End();
|
Iterator End();
|
||||||
|
|
||||||
|
size_t GetLength() const;
|
||||||
|
|
||||||
Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;
|
Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;
|
||||||
void SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) override;
|
void SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) override;
|
||||||
bool HasOwnField(const String& field) const override;
|
bool HasOwnField(const String& field) const override;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "base/namespace.hpp"
|
#include "base/namespace.hpp"
|
||||||
#include <boost/algorithm/string/join.hpp>
|
#include <boost/algorithm/string/join.hpp>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
@ -64,13 +65,15 @@ struct SerializeStack
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Value SerializeInternal(const Value& value, int attributeTypes, SerializeStack& stack);
|
static Value SerializeInternal(const Value& value, int attributeTypes, SerializeStack& stack, bool dryRun);
|
||||||
|
|
||||||
static Array::Ptr SerializeArray(const Array::Ptr& input, int attributeTypes, SerializeStack& stack)
|
static Array::Ptr SerializeArray(const Array::Ptr& input, int attributeTypes, SerializeStack& stack, bool dryRun)
|
||||||
{
|
{
|
||||||
ArrayData result;
|
ArrayData result;
|
||||||
|
|
||||||
result.reserve(input->GetLength());
|
if (!dryRun) {
|
||||||
|
result.reserve(input->GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
ObjectLock olock(input);
|
ObjectLock olock(input);
|
||||||
|
|
||||||
|
@ -78,48 +81,72 @@ static Array::Ptr SerializeArray(const Array::Ptr& input, int attributeTypes, Se
|
||||||
|
|
||||||
for (const Value& value : input) {
|
for (const Value& value : input) {
|
||||||
stack.Push(Convert::ToString(index), value);
|
stack.Push(Convert::ToString(index), value);
|
||||||
result.emplace_back(SerializeInternal(value, attributeTypes, stack));
|
|
||||||
|
auto serialized (SerializeInternal(value, attributeTypes, stack, dryRun));
|
||||||
|
|
||||||
|
if (!dryRun) {
|
||||||
|
result.emplace_back(std::move(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
stack.Pop();
|
stack.Pop();
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Array(std::move(result));
|
return dryRun ? nullptr : new Array(std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Dictionary::Ptr SerializeDictionary(const Dictionary::Ptr& input, int attributeTypes, SerializeStack& stack)
|
static Dictionary::Ptr SerializeDictionary(const Dictionary::Ptr& input, int attributeTypes, SerializeStack& stack, bool dryRun)
|
||||||
{
|
{
|
||||||
DictionaryData result;
|
DictionaryData result;
|
||||||
|
|
||||||
result.reserve(input->GetLength());
|
if (!dryRun) {
|
||||||
|
result.reserve(input->GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
ObjectLock olock(input);
|
ObjectLock olock(input);
|
||||||
|
|
||||||
for (const Dictionary::Pair& kv : input) {
|
for (const Dictionary::Pair& kv : input) {
|
||||||
stack.Push(kv.first, kv.second);
|
stack.Push(kv.first, kv.second);
|
||||||
result.emplace_back(kv.first, SerializeInternal(kv.second, attributeTypes, stack));
|
|
||||||
|
auto serialized (SerializeInternal(kv.second, attributeTypes, stack, dryRun));
|
||||||
|
|
||||||
|
if (!dryRun) {
|
||||||
|
result.emplace_back(kv.first, std::move(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
stack.Pop();
|
stack.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Dictionary(std::move(result));
|
return dryRun ? nullptr : new Dictionary(std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Dictionary::Ptr SerializeNamespace(const Namespace::Ptr& input, int attributeTypes, SerializeStack& stack)
|
static Dictionary::Ptr SerializeNamespace(const Namespace::Ptr& input, int attributeTypes, SerializeStack& stack, bool dryRun)
|
||||||
{
|
{
|
||||||
DictionaryData result;
|
DictionaryData result;
|
||||||
|
|
||||||
|
if (!dryRun) {
|
||||||
|
result.reserve(input->GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
ObjectLock olock(input);
|
ObjectLock olock(input);
|
||||||
|
|
||||||
for (const Namespace::Pair& kv : input) {
|
for (const Namespace::Pair& kv : input) {
|
||||||
Value val = kv.second->Get();
|
Value val = kv.second->Get();
|
||||||
stack.Push(kv.first, val);
|
stack.Push(kv.first, val);
|
||||||
result.emplace_back(kv.first, Serialize(val, attributeTypes));
|
|
||||||
|
auto serialized (SerializeInternal(val, attributeTypes, stack, dryRun));
|
||||||
|
|
||||||
|
if (!dryRun) {
|
||||||
|
result.emplace_back(kv.first, std::move(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
stack.Pop();
|
stack.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Dictionary(std::move(result));
|
return dryRun ? nullptr : new Dictionary(std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object::Ptr SerializeObject(const Object::Ptr& input, int attributeTypes, SerializeStack& stack)
|
static Object::Ptr SerializeObject(const Object::Ptr& input, int attributeTypes, SerializeStack& stack, bool dryRun)
|
||||||
{
|
{
|
||||||
Type::Ptr type = input->GetReflectionType();
|
Type::Ptr type = input->GetReflectionType();
|
||||||
|
|
||||||
|
@ -127,7 +154,10 @@ static Object::Ptr SerializeObject(const Object::Ptr& input, int attributeTypes,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
DictionaryData fields;
|
DictionaryData fields;
|
||||||
fields.reserve(type->GetFieldCount() + 1);
|
|
||||||
|
if (!dryRun) {
|
||||||
|
fields.reserve(type->GetFieldCount() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
ObjectLock olock(input);
|
ObjectLock olock(input);
|
||||||
|
|
||||||
|
@ -142,13 +172,21 @@ static Object::Ptr SerializeObject(const Object::Ptr& input, int attributeTypes,
|
||||||
|
|
||||||
Value value = input->GetField(i);
|
Value value = input->GetField(i);
|
||||||
stack.Push(field.Name, value);
|
stack.Push(field.Name, value);
|
||||||
fields.emplace_back(field.Name, SerializeInternal(value, attributeTypes, stack));
|
|
||||||
|
auto serialized (SerializeInternal(value, attributeTypes, stack, dryRun));
|
||||||
|
|
||||||
|
if (!dryRun) {
|
||||||
|
fields.emplace_back(field.Name, std::move(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
stack.Pop();
|
stack.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
fields.emplace_back("type", type->GetName());
|
if (!dryRun) {
|
||||||
|
fields.emplace_back("type", type->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
return new Dictionary(std::move(fields));
|
return dryRun ? nullptr : new Dictionary(std::move(fields));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Array::Ptr DeserializeArray(const Array::Ptr& input, bool safe_mode, int attributeTypes)
|
static Array::Ptr DeserializeArray(const Array::Ptr& input, bool safe_mode, int attributeTypes)
|
||||||
|
@ -228,35 +266,35 @@ static Object::Ptr DeserializeObject(const Object::Ptr& object, const Dictionary
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Value SerializeInternal(const Value& value, int attributeTypes, SerializeStack& stack)
|
static Value SerializeInternal(const Value& value, int attributeTypes, SerializeStack& stack, bool dryRun)
|
||||||
{
|
{
|
||||||
if (!value.IsObject())
|
if (!value.IsObject())
|
||||||
return value;
|
return dryRun ? Empty : value;
|
||||||
|
|
||||||
Object::Ptr input = value;
|
Object::Ptr input = value;
|
||||||
|
|
||||||
Array::Ptr array = dynamic_pointer_cast<Array>(input);
|
Array::Ptr array = dynamic_pointer_cast<Array>(input);
|
||||||
|
|
||||||
if (array)
|
if (array)
|
||||||
return SerializeArray(array, attributeTypes, stack);
|
return SerializeArray(array, attributeTypes, stack, dryRun);
|
||||||
|
|
||||||
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(input);
|
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(input);
|
||||||
|
|
||||||
if (dict)
|
if (dict)
|
||||||
return SerializeDictionary(dict, attributeTypes, stack);
|
return SerializeDictionary(dict, attributeTypes, stack, dryRun);
|
||||||
|
|
||||||
Namespace::Ptr ns = dynamic_pointer_cast<Namespace>(input);
|
Namespace::Ptr ns = dynamic_pointer_cast<Namespace>(input);
|
||||||
|
|
||||||
if (ns)
|
if (ns)
|
||||||
return SerializeNamespace(ns, attributeTypes, stack);
|
return SerializeNamespace(ns, attributeTypes, stack, dryRun);
|
||||||
|
|
||||||
return SerializeObject(input, attributeTypes, stack);
|
return SerializeObject(input, attributeTypes, stack, dryRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value icinga::Serialize(const Value& value, int attributeTypes)
|
Value icinga::Serialize(const Value& value, int attributeTypes)
|
||||||
{
|
{
|
||||||
SerializeStack stack;
|
SerializeStack stack;
|
||||||
return SerializeInternal(value, attributeTypes, stack);
|
return SerializeInternal(value, attributeTypes, stack, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value icinga::Deserialize(const Value& value, bool safe_mode, int attributeTypes)
|
Value icinga::Deserialize(const Value& value, bool safe_mode, int attributeTypes)
|
||||||
|
|
Loading…
Reference in New Issue