#include "GDCore/Serialization/SerializerElement.h" #include namespace gd { SerializerElement SerializerElement::nullElement; SerializerElement::SerializerElement() : valueUndefined(true), isArray(false) {} SerializerElement::SerializerElement(const SerializerValue& value) : valueUndefined(false), elementValue(value), isArray(false) {} SerializerElement::~SerializerElement() {} const SerializerValue& SerializerElement::GetValue() const { if (valueUndefined && attributes.find("value") != attributes.end()) return attributes.find("value")->second; return elementValue; } SerializerElement& SerializerElement::SetAttribute(const gd::String& name, bool value) { attributes[name].SetBool(value); return *this; } SerializerElement& SerializerElement::SetAttribute(const gd::String& name, const gd::String& value) { attributes[name].SetString(value); return *this; } SerializerElement& SerializerElement::SetAttribute(const gd::String& name, int value) { attributes[name].SetInt(value); return *this; } SerializerElement& SerializerElement::SetAttribute(const gd::String& name, double value) { attributes[name].SetDouble(value); return *this; } bool SerializerElement::GetBoolAttribute(const gd::String& name, bool defaultValue, gd::String deprecatedName) const { if (attributes.find(name) != attributes.end()) { return attributes.find(name)->second.GetBool(); } else if (!deprecatedName.empty() && attributes.find(deprecatedName) != attributes.end()) { return attributes.find(deprecatedName)->second.GetBool(); } else { if (HasChild(name, deprecatedName)) { SerializerElement& child = GetChild(name, 0, deprecatedName); if (!child.IsValueUndefined()) { return child.GetValue().GetBool(); } } } std::cout << "Bool attribute \"" << name << "\" not found, returning " << defaultValue; return defaultValue; } gd::String SerializerElement::GetStringAttribute( const gd::String& name, gd::String defaultValue, gd::String deprecatedName) const { if (attributes.find(name) != attributes.end()) return attributes.find(name)->second.GetString(); else if (!deprecatedName.empty() && attributes.find(deprecatedName) != attributes.end()) return attributes.find(deprecatedName)->second.GetString(); else { if (HasChild(name, deprecatedName)) { SerializerElement& child = GetChild(name, 0, deprecatedName); if (!child.IsValueUndefined()) return child.GetValue().GetString(); } } return defaultValue; } int SerializerElement::GetIntAttribute(const gd::String& name, int defaultValue, gd::String deprecatedName) const { if (attributes.find(name) != attributes.end()) return attributes.find(name)->second.GetInt(); else if (!deprecatedName.empty() && attributes.find(deprecatedName) != attributes.end()) return attributes.find(deprecatedName)->second.GetInt(); else { if (HasChild(name, deprecatedName)) { SerializerElement& child = GetChild(name, 0, deprecatedName); if (!child.IsValueUndefined()) return child.GetValue().GetInt(); } } return defaultValue; } double SerializerElement::GetDoubleAttribute(const gd::String& name, double defaultValue, gd::String deprecatedName) const { if (attributes.find(name) != attributes.end()) return attributes.find(name)->second.GetDouble(); else if (!deprecatedName.empty() && attributes.find(deprecatedName) != attributes.end()) return attributes.find(deprecatedName)->second.GetDouble(); else { if (HasChild(name, deprecatedName)) { SerializerElement& child = GetChild(name, 0, deprecatedName); if (!child.IsValueUndefined()) return child.GetValue().GetDouble(); } } return defaultValue; } bool SerializerElement::HasAttribute(const gd::String& name) const { return attributes.find(name) != attributes.end(); } SerializerElement& SerializerElement::AddChild(gd::String name) { if (!arrayOf.empty()) { if (name != arrayOf) { std::cout << "WARNING: Adding a child, to a SerializerElement which is " "considered as an array, with a name (" << name << ") which is not the same as the array elements (" << arrayOf << "). Child was renamed." << std::endl; name = arrayOf; } } std::shared_ptr newElement(new SerializerElement); children.push_back(std::make_pair(name, newElement)); return *newElement; } SerializerElement& SerializerElement::GetChild(std::size_t index) const { if (arrayOf.empty()) { std::cout << "ERROR: Getting a child from its index whereas the parent is " "not considered as an array." << std::endl; return nullElement; } std::size_t currentIndex = 0; for (size_t i = 0; i < children.size(); ++i) { if (children[i].second == std::shared_ptr()) continue; if (children[i].first == arrayOf || children[i].first.empty() || (!deprecatedArrayOf.empty() && children[i].first == deprecatedArrayOf)) { if (index == currentIndex) return *children[i].second; else currentIndex++; } } std::cout << "ERROR: Request out of bound child at index " << index << std::endl; return nullElement; } SerializerElement& SerializerElement::GetChild( gd::String name, std::size_t index, gd::String deprecatedName) const { if (!arrayOf.empty()) { if (name != arrayOf) { std::cout << "WARNING: Getting a child, from a SerializerElement which " "is considered as an array, with a name (" << name << ") which is not the same as the array elements (" << arrayOf << ")." << std::endl; name = arrayOf; } } std::size_t currentIndex = 0; for (size_t i = 0; i < children.size(); ++i) { if (children[i].second == std::shared_ptr()) continue; if (children[i].first == name || (!arrayOf.empty() && children[i].first.empty()) || (!deprecatedName.empty() && children[i].first == deprecatedName)) { if (index == currentIndex) return *children[i].second; else currentIndex++; } } std::cout << "Child " << name << " not found in SerializerElement::GetChild" << std::endl; return nullElement; } std::size_t SerializerElement::GetChildrenCount( gd::String name, gd::String deprecatedName) const { if (name.empty()) { if (arrayOf.empty()) { std::cout << "ERROR: Getting children count without specifying name, from a " "SerializerElement which is NOT considered as an array." << std::endl; return 0; } name = arrayOf; deprecatedName = deprecatedArrayOf; } std::size_t currentIndex = 0; for (size_t i = 0; i < children.size(); ++i) { if (children[i].second == std::shared_ptr()) continue; if (children[i].first == name || (!arrayOf.empty() && children[i].first.empty()) || (!deprecatedName.empty() && children[i].first == deprecatedName)) currentIndex++; } return currentIndex; } bool SerializerElement::HasChild(const gd::String& name, gd::String deprecatedName) const { for (size_t i = 0; i < children.size(); ++i) { if (children[i].second == std::shared_ptr()) continue; if (children[i].first == name || (!deprecatedName.empty() && children[i].first == deprecatedName)) return true; } return false; } } // namespace gd