// // Struct.h // // Library: Foundation // Package: Dynamic // Module: Struct // // Definition of the Struct class. // // Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // SPDX-License-Identifier: BSL-1.0 // #ifndef Foundation_Struct_INCLUDED #define Foundation_Struct_INCLUDED #include "Poco/Foundation.h" #include "Poco/Dynamic/Var.h" #include "Poco/Dynamic/VarHolder.h" #include "Poco/SharedPtr.h" #include #include namespace Poco { namespace Dynamic { template class Struct /// Struct allows to define a named collection of Var objects. { public: typedef typename std::map Data; typedef typename std::set NameSet; typedef typename Data::iterator Iterator; typedef typename Data::const_iterator ConstIterator; typedef typename Struct::Data::value_type ValueType; typedef typename Struct::Data::size_type SizeType; typedef typename std::pair::Iterator, bool> InsRetVal; typedef typename Poco::SharedPtr > Ptr; Struct(): _data() /// Creates an empty Struct { } Struct(const Data& val): _data(val) /// Creates the Struct from the given value. { } template Struct(const std::map& val) { typedef typename std::map::const_iterator MapConstIterator; MapConstIterator it = val.begin(); MapConstIterator end = val.end(); for (; it != end; ++it) _data.insert(ValueType(it->first, Var(it->second))); } virtual ~Struct() /// Destroys the Struct. { } inline Var& operator [] (const K& name) /// Returns the Var with the given name, creates an entry if not found. { return _data[name]; } const Var& operator [] (const K& name) const /// Returns the Var with the given name, throws a /// NotFoundException if the data member is not found. { ConstIterator it = find(name); if (it == end()) throw NotFoundException(name); return it->second; } inline bool contains(const K& name) const /// Returns true if the Struct contains a member with the given name { return find(name) != end(); } inline Iterator find(const K& name) /// Returns an iterator, pointing to the pair containing /// the element, or it returns end() if the member was not found { return _data.find(name); } inline ConstIterator find(const K& name) const /// Returns a const iterator, pointing to the pair containing /// the element, or it returns end() if the member was not found { return _data.find(name); } inline Iterator end() /// Returns the end iterator for the Struct { return _data.end(); } inline ConstIterator end() const /// Returns the end const iterator for the Struct { return _data.end(); } inline Iterator begin() /// Returns the begin iterator for the Struct { return _data.begin(); } inline ConstIterator begin() const /// Returns the begin const iterator for the Struct { return _data.begin(); } template inline InsRetVal insert(const K& key, const T& value) /// Inserts a pair into the Struct, /// returns a pair containing the iterator and a boolean which /// indicates success or not (is true, when insert succeeded, false, /// when already another element was present, in this case Iterator /// points to that other element) { // fix: SunPro C++ is silly ... ValueType valueType(key, value); return insert(valueType); } inline InsRetVal insert(const ValueType& aPair) /// Inserts a pair into the Struct, /// returns a pair containing the iterator and a boolean which /// indicates success or not (is true, when insert succeeded, false, /// when already another element was present, in this case Iterator /// points to that other element) { return _data.insert(aPair); } inline SizeType erase(const K& key) /// Erases the element if found, returns number of elements deleted { return _data.erase(key); } inline void erase(Iterator& it) /// Erases the element at the given position { _data.erase(it); } inline bool empty() const /// Returns true if the Struct doesn't contain any members { return _data.empty(); } inline void clear() /// Clears the Struct contents { _data.clear(); } SizeType size() const /// Returns the number of members the Struct contains { return _data.size(); } inline NameSet members() const /// Returns a sorted collection containing all member names { NameSet keys; ConstIterator it = begin(); ConstIterator itEnd = end(); for (; it != itEnd; ++it) keys.insert(it->first); return keys; } std::string toString() { std::string str; Var(*this).convert(str); return str; } private: Data _data; }; template <> class VarHolderImpl >: public VarHolder { public: VarHolderImpl(const Struct& val): _val(val) { } ~VarHolderImpl() { } const std::type_info& type() const { return typeid(Struct); } void convert(Int8&) const { throw BadCastException("Cannot cast Struct type to Int8"); } void convert(Int16&) const { throw BadCastException("Cannot cast Struct type to Int16"); } void convert(Int32&) const { throw BadCastException("Cannot cast Struct type to Int32"); } void convert(Int64&) const { throw BadCastException("Cannot cast Struct type to Int64"); } void convert(UInt8&) const { throw BadCastException("Cannot cast Struct type to UInt8"); } void convert(UInt16&) const { throw BadCastException("Cannot cast Struct type to UInt16"); } void convert(UInt32&) const { throw BadCastException("Cannot cast Struct type to UInt32"); } void convert(UInt64&) const { throw BadCastException("Cannot cast Struct type to UInt64"); } void convert(bool&) const { throw BadCastException("Cannot cast Struct type to bool"); } void convert(float&) const { throw BadCastException("Cannot cast Struct type to float"); } void convert(double&) const { throw BadCastException("Cannot cast Struct type to double"); } void convert(char&) const { throw BadCastException("Cannot cast Struct type to char"); } void convert(std::string& val) const { val.append("{ "); Struct::ConstIterator it = _val.begin(); Struct::ConstIterator itEnd = _val.end(); if (!_val.empty()) { Var key(it->first); Impl::appendJSONKey(val, key); val.append(" : "); Impl::appendJSONValue(val, it->second); ++it; } for (; it != itEnd; ++it) { val.append(", "); Var key(it->first); Impl::appendJSONKey(val, key); val.append(" : "); Impl::appendJSONValue(val, it->second); } val.append(" }"); } void convert(Poco::DateTime&) const { throw BadCastException("Struct -> Poco::DateTime"); } void convert(Poco::LocalDateTime&) const { throw BadCastException("Struct -> Poco::LocalDateTime"); } void convert(Poco::Timestamp&) const { throw BadCastException("Struct -> Poco::Timestamp"); } VarHolder* clone(Placeholder* pVarHolder = 0) const { return cloneHolder(pVarHolder, _val); } const Struct& value() const { return _val; } bool isArray() const { return false; } bool isStruct() const { return true; } bool isInteger() const { return false; } bool isSigned() const { return false; } bool isNumeric() const { return false; } bool isString() const { return false; } std::size_t size() const { return _val.size(); } Var& operator [] (const std::string& name) { return _val[name]; } const Var& operator [] (const std::string& name) const { return _val[name]; } private: Struct _val; }; template <> class VarHolderImpl >: public VarHolder { public: VarHolderImpl(const Struct& val): _val(val) { } ~VarHolderImpl() { } const std::type_info& type() const { return typeid(Struct); } void convert(Int8&) const { throw BadCastException("Cannot cast Struct type to Int8"); } void convert(Int16&) const { throw BadCastException("Cannot cast Struct type to Int16"); } void convert(Int32&) const { throw BadCastException("Cannot cast Struct type to Int32"); } void convert(Int64&) const { throw BadCastException("Cannot cast Struct type to Int64"); } void convert(UInt8&) const { throw BadCastException("Cannot cast Struct type to UInt8"); } void convert(UInt16&) const { throw BadCastException("Cannot cast Struct type to UInt16"); } void convert(UInt32&) const { throw BadCastException("Cannot cast Struct type to UInt32"); } void convert(UInt64&) const { throw BadCastException("Cannot cast Struct type to UInt64"); } void convert(bool&) const { throw BadCastException("Cannot cast Struct type to bool"); } void convert(float&) const { throw BadCastException("Cannot cast Struct type to float"); } void convert(double&) const { throw BadCastException("Cannot cast Struct type to double"); } void convert(char&) const { throw BadCastException("Cannot cast Struct type to char"); } void convert(std::string& val) const { val.append("{ "); Struct::ConstIterator it = _val.begin(); Struct::ConstIterator itEnd = _val.end(); if (!_val.empty()) { Var key(it->first); Impl::appendJSONKey(val, key); val.append(" : "); Impl::appendJSONValue(val, it->second); ++it; } for (; it != itEnd; ++it) { val.append(", "); Var key(it->first); Impl::appendJSONKey(val, key); val.append(" : "); Impl::appendJSONValue(val, it->second); } val.append(" }"); } void convert(Poco::DateTime&) const { throw BadCastException("Struct -> Poco::DateTime"); } void convert(Poco::LocalDateTime&) const { throw BadCastException("Struct -> Poco::LocalDateTime"); } void convert(Poco::Timestamp&) const { throw BadCastException("Struct -> Poco::Timestamp"); } VarHolder* clone(Placeholder* pVarHolder = 0) const { return cloneHolder(pVarHolder, _val); } const Struct& value() const { return _val; } bool isArray() const { return false; } bool isStruct() const { return true; } bool isInteger() const { return false; } bool isSigned() const { return false; } bool isNumeric() const { return false; } bool isString() const { return false; } std::size_t size() const { return _val.size(); } Var& operator [] (int name) { return _val[name]; } const Var& operator [] (int name) const { return _val[name]; } private: Struct _val; }; } // namespace Dynamic typedef Dynamic::Struct DynamicStruct; } // namespace Poco #endif // Foundation_Struct_INCLUDED