mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 18:20:26 +01:00
* Preserve entries order in DynamicStruct #2410 * disable C++11 default * ifdef C++11 code
This commit is contained in:
parent
6107b43a7b
commit
231ef2762d
@ -22,6 +22,8 @@
|
|||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include "Poco/Dynamic/VarHolder.h"
|
#include "Poco/Dynamic/VarHolder.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
|
#include "Poco/OrderedMap.h"
|
||||||
|
#include "Poco/OrderedSet.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@ -30,19 +32,19 @@ namespace Poco {
|
|||||||
namespace Dynamic {
|
namespace Dynamic {
|
||||||
|
|
||||||
|
|
||||||
template <typename K>
|
template <typename K, typename M = std::map<K, Var>, typename S = std::set<K> >
|
||||||
class Struct
|
class Struct
|
||||||
/// Struct allows to define a named collection of Var objects.
|
/// Struct allows to define a named collection of Var objects.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename std::map<K, Var> Data;
|
typedef M Data;
|
||||||
typedef typename std::set<K> NameSet;
|
typedef S NameSet;
|
||||||
typedef typename Data::iterator Iterator;
|
typedef typename Data::iterator Iterator;
|
||||||
typedef typename Data::const_iterator ConstIterator;
|
typedef typename Data::const_iterator ConstIterator;
|
||||||
typedef typename Struct<K>::Data::value_type ValueType;
|
typedef typename Struct<K>::Data::value_type ValueType;
|
||||||
typedef typename Struct<K>::Data::size_type SizeType;
|
typedef typename Struct<K>::Data::size_type SizeType;
|
||||||
typedef typename std::pair<typename Struct<K>::Iterator, bool> InsRetVal;
|
typedef typename std::pair<typename Struct<K, M, S>::Iterator, bool> InsRetVal;
|
||||||
typedef typename Poco::SharedPtr<Struct<K> > Ptr;
|
typedef typename Poco::SharedPtr<Struct<K, M, S> > Ptr;
|
||||||
|
|
||||||
Struct(): _data()
|
Struct(): _data()
|
||||||
/// Creates an empty Struct
|
/// Creates an empty Struct
|
||||||
@ -57,13 +59,19 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
Struct(const std::map<K, T>& val)
|
Struct(const std::map<K, T>& val)
|
||||||
{
|
{
|
||||||
typedef typename std::map<K, T>::const_iterator MapConstIterator;
|
assignMap(val);
|
||||||
|
|
||||||
MapConstIterator it = val.begin();
|
|
||||||
MapConstIterator end = val.end();
|
|
||||||
for (; it != end; ++it) _data.insert(ValueType(it->first, Var(it->second)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Struct(const OrderedMap<K, T>& val)
|
||||||
|
{
|
||||||
|
assignMap(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
virtual ~Struct()
|
virtual ~Struct()
|
||||||
/// Destroys the Struct.
|
/// Destroys the Struct.
|
||||||
{
|
{
|
||||||
@ -199,15 +207,30 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <typename T>
|
||||||
|
void assignMap(const T& map)
|
||||||
|
{
|
||||||
|
typedef typename T::const_iterator MapConstIterator;
|
||||||
|
|
||||||
|
MapConstIterator it = map.begin();
|
||||||
|
MapConstIterator end = map.end();
|
||||||
|
for (; it != end; ++it) _data.insert(ValueType(it->first, Var(it->second)));
|
||||||
|
}
|
||||||
|
|
||||||
Data _data;
|
Data _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class VarHolderImpl<Struct<std::string> >: public VarHolder
|
class VarHolderImpl<Struct<std::string, std::map<std::string, Var>, std::set<std::string> > >: public VarHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VarHolderImpl(const Struct<std::string>& val): _val(val)
|
typedef std::string KeyType;
|
||||||
|
typedef std::map<KeyType, Var> MapType;
|
||||||
|
typedef std::set<KeyType> SetType;
|
||||||
|
typedef Struct<KeyType, MapType, SetType> ValueType;
|
||||||
|
|
||||||
|
VarHolderImpl(const ValueType& val): _val(val)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +240,7 @@ public:
|
|||||||
|
|
||||||
const std::type_info& type() const
|
const std::type_info& type() const
|
||||||
{
|
{
|
||||||
return typeid(Struct<std::string>);
|
return typeid(ValueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Int8&) const
|
void convert(Int8&) const
|
||||||
@ -283,8 +306,8 @@ public:
|
|||||||
void convert(std::string& val) const
|
void convert(std::string& val) const
|
||||||
{
|
{
|
||||||
val.append("{ ");
|
val.append("{ ");
|
||||||
Struct<std::string>::ConstIterator it = _val.begin();
|
ValueType::ConstIterator it = _val.begin();
|
||||||
Struct<std::string>::ConstIterator itEnd = _val.end();
|
ValueType::ConstIterator itEnd = _val.end();
|
||||||
if (!_val.empty())
|
if (!_val.empty())
|
||||||
{
|
{
|
||||||
Var key(it->first);
|
Var key(it->first);
|
||||||
@ -324,7 +347,7 @@ public:
|
|||||||
return cloneHolder(pVarHolder, _val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Struct<std::string>& value() const
|
const ValueType& value() const
|
||||||
{
|
{
|
||||||
return _val;
|
return _val;
|
||||||
}
|
}
|
||||||
@ -339,6 +362,11 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isOrdered() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool isInteger() const
|
bool isInteger() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -364,36 +392,41 @@ public:
|
|||||||
return _val.size();
|
return _val.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Var& operator [] (const std::string& name)
|
Var& operator [] (const KeyType& name)
|
||||||
{
|
{
|
||||||
return _val[name];
|
return _val[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Var& operator [] (const std::string& name) const
|
const Var& operator [] (const KeyType& name) const
|
||||||
{
|
{
|
||||||
return _val[name];
|
return _val[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Struct<std::string> _val;
|
ValueType _val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class VarHolderImpl<Struct<int> >: public VarHolder
|
class VarHolderImpl<Struct<int, std::map<int, Var>, std::set<int> > > : public VarHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VarHolderImpl(const Struct<int>& val): _val(val)
|
typedef int KeyType;
|
||||||
|
typedef std::map<KeyType, Var> MapType;
|
||||||
|
typedef std::set<KeyType> SetType;
|
||||||
|
typedef Struct<KeyType, MapType, SetType> ValueType;
|
||||||
|
|
||||||
|
VarHolderImpl(const ValueType& val) : _val(val)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~VarHolderImpl()
|
~VarHolderImpl()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::type_info& type() const
|
const std::type_info& type() const
|
||||||
{
|
{
|
||||||
return typeid(Struct<int>);
|
return typeid(ValueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Int8&) const
|
void convert(Int8&) const
|
||||||
@ -405,7 +438,7 @@ public:
|
|||||||
{
|
{
|
||||||
throw BadCastException("Cannot cast Struct type to Int16");
|
throw BadCastException("Cannot cast Struct type to Int16");
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Int32&) const
|
void convert(Int32&) const
|
||||||
{
|
{
|
||||||
throw BadCastException("Cannot cast Struct type to Int32");
|
throw BadCastException("Cannot cast Struct type to Int32");
|
||||||
@ -425,7 +458,7 @@ public:
|
|||||||
{
|
{
|
||||||
throw BadCastException("Cannot cast Struct type to UInt16");
|
throw BadCastException("Cannot cast Struct type to UInt16");
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(UInt32&) const
|
void convert(UInt32&) const
|
||||||
{
|
{
|
||||||
throw BadCastException("Cannot cast Struct type to UInt32");
|
throw BadCastException("Cannot cast Struct type to UInt32");
|
||||||
@ -459,8 +492,8 @@ public:
|
|||||||
void convert(std::string& val) const
|
void convert(std::string& val) const
|
||||||
{
|
{
|
||||||
val.append("{ ");
|
val.append("{ ");
|
||||||
Struct<int>::ConstIterator it = _val.begin();
|
ValueType::ConstIterator it = _val.begin();
|
||||||
Struct<int>::ConstIterator itEnd = _val.end();
|
ValueType::ConstIterator itEnd = _val.end();
|
||||||
if (!_val.empty())
|
if (!_val.empty())
|
||||||
{
|
{
|
||||||
Var key(it->first);
|
Var key(it->first);
|
||||||
@ -477,7 +510,7 @@ public:
|
|||||||
val.append(" : ");
|
val.append(" : ");
|
||||||
Impl::appendJSONValue(val, it->second);
|
Impl::appendJSONValue(val, it->second);
|
||||||
}
|
}
|
||||||
val.append(" }");
|
val.append(" }");
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Poco::DateTime&) const
|
void convert(Poco::DateTime&) const
|
||||||
@ -499,8 +532,8 @@ public:
|
|||||||
{
|
{
|
||||||
return cloneHolder(pVarHolder, _val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Struct<int>& value() const
|
const ValueType& value() const
|
||||||
{
|
{
|
||||||
return _val;
|
return _val;
|
||||||
}
|
}
|
||||||
@ -515,6 +548,200 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isOrdered() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 KeyType& name)
|
||||||
|
{
|
||||||
|
return _val[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Var& operator [] (const KeyType& name) const
|
||||||
|
{
|
||||||
|
return _val[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ValueType _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class VarHolderImpl<Struct<std::string, Poco::OrderedMap<std::string, Var>, Poco::OrderedSet<std::string> > > : public VarHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::string KeyType;
|
||||||
|
typedef Poco::OrderedMap<KeyType, Var> MapType;
|
||||||
|
typedef Poco::OrderedSet<KeyType> SetType;
|
||||||
|
typedef Struct<KeyType, MapType, SetType> ValueType;
|
||||||
|
|
||||||
|
VarHolderImpl(const ValueType& val) : _val(val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~VarHolderImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::type_info& type() const
|
||||||
|
{
|
||||||
|
return typeid(ValueType);
|
||||||
|
}
|
||||||
|
|
||||||
|
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("{ ");
|
||||||
|
ValueType::ConstIterator it = _val.begin();
|
||||||
|
ValueType::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<VarHolder>* pVarHolder = 0) const
|
||||||
|
{
|
||||||
|
return cloneHolder(pVarHolder, _val);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ValueType& value() const
|
||||||
|
{
|
||||||
|
return _val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isArray() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isStruct() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOrdered() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool isInteger() const
|
bool isInteger() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -540,26 +767,218 @@ public:
|
|||||||
return _val.size();
|
return _val.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Var& operator [] (int name)
|
Var& operator [] (const KeyType& name)
|
||||||
{
|
{
|
||||||
return _val[name];
|
return _val[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Var& operator [] (int name) const
|
const Var& operator [] (const KeyType& name) const
|
||||||
{
|
{
|
||||||
return _val[name];
|
return _val[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Struct<int> _val;
|
ValueType _val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class VarHolderImpl<Struct<int, Poco::OrderedMap<int, Var>, Poco::OrderedSet<int> > > : public VarHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef int KeyType;
|
||||||
|
typedef Poco::OrderedMap<KeyType, Var> MapType;
|
||||||
|
typedef Poco::OrderedSet<KeyType> SetType;
|
||||||
|
typedef Struct<KeyType, MapType, SetType> ValueType;
|
||||||
|
|
||||||
|
VarHolderImpl(const ValueType& val) : _val(val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~VarHolderImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::type_info& type() const
|
||||||
|
{
|
||||||
|
return typeid(ValueType);
|
||||||
|
}
|
||||||
|
|
||||||
|
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("{ ");
|
||||||
|
ValueType::ConstIterator it = _val.begin();
|
||||||
|
ValueType::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<VarHolder>* pVarHolder = 0) const
|
||||||
|
{
|
||||||
|
return cloneHolder(pVarHolder, _val);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ValueType& value() const
|
||||||
|
{
|
||||||
|
return _val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isArray() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isStruct() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOrdered() 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 KeyType& name)
|
||||||
|
{
|
||||||
|
return _val[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Var& operator [] (const KeyType& name) const
|
||||||
|
{
|
||||||
|
return _val[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ValueType _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
|
|
||||||
} // namespace Dynamic
|
} // namespace Dynamic
|
||||||
|
|
||||||
|
|
||||||
typedef Dynamic::Struct<std::string> DynamicStruct;
|
typedef Dynamic::Struct<std::string> DynamicStruct;
|
||||||
|
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
typedef Dynamic::Struct<std::string, Poco::OrderedMap<std::string, Dynamic::Var>, Poco::OrderedSet<std::string> > OrderedDynamicStruct;
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
|
@ -21,16 +21,20 @@
|
|||||||
#include "Poco/Foundation.h"
|
#include "Poco/Foundation.h"
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
|
#include "Poco/OrderedMap.h"
|
||||||
|
#include "Poco/OrderedSet.h"
|
||||||
#include "Poco/Dynamic/VarHolder.h"
|
#include "Poco/Dynamic/VarHolder.h"
|
||||||
#include "Poco/Dynamic/VarIterator.h"
|
#include "Poco/Dynamic/VarIterator.h"
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
namespace Dynamic {
|
namespace Dynamic {
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename K, typename M, typename S>
|
||||||
class Struct;
|
class Struct;
|
||||||
|
|
||||||
|
|
||||||
@ -449,6 +453,10 @@ public:
|
|||||||
bool isStruct() const;
|
bool isStruct() const;
|
||||||
/// Returns true if Var represents a struct.
|
/// Returns true if Var represents a struct.
|
||||||
|
|
||||||
|
bool isOrdered() const;
|
||||||
|
/// Returns true if Var represents an ordered struct,
|
||||||
|
/// false if struct is sorted.
|
||||||
|
|
||||||
char& at(std::size_t n);
|
char& at(std::size_t n);
|
||||||
/// Returns character at position n. This function only works with
|
/// Returns character at position n. This function only works with
|
||||||
/// Var containing a std::string.
|
/// Var containing a std::string.
|
||||||
@ -595,7 +603,11 @@ private:
|
|||||||
throw E(errorMessage);
|
throw E(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Var& structIndexOperator(VarHolderImpl<Struct<int> >* pStr, int n) const;
|
template <typename T, typename N>
|
||||||
|
Var& structIndexOperator(T* pStr, N n) const
|
||||||
|
{
|
||||||
|
return pStr->operator[](n);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef POCO_NO_SOO
|
#ifdef POCO_NO_SOO
|
||||||
|
|
||||||
@ -822,6 +834,13 @@ inline bool Var::isStruct() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Var::isOrdered() const
|
||||||
|
{
|
||||||
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->isOrdered() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Var::isInteger() const
|
inline bool Var::isInteger() const
|
||||||
{
|
{
|
||||||
VarHolder* pHolder = content();
|
VarHolder* pHolder = content();
|
||||||
|
@ -241,6 +241,10 @@ public:
|
|||||||
/// Returns false. Must be properly overriden in a type
|
/// Returns false. Must be properly overriden in a type
|
||||||
/// specialization in order to support the diagnostic.
|
/// specialization in order to support the diagnostic.
|
||||||
|
|
||||||
|
virtual bool isOrdered() const;
|
||||||
|
/// Returns false. Must be properly overriden in a type
|
||||||
|
/// specialization in order to support the diagnostic.
|
||||||
|
|
||||||
virtual bool isInteger() const;
|
virtual bool isInteger() const;
|
||||||
/// Returns false. Must be properly overriden in a type
|
/// Returns false. Must be properly overriden in a type
|
||||||
/// specialization in order to support the diagnostic.
|
/// specialization in order to support the diagnostic.
|
||||||
@ -612,6 +616,13 @@ inline bool VarHolder::isStruct() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool VarHolder::isOrdered() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool VarHolder::isInteger() const
|
inline bool VarHolder::isInteger() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -113,6 +113,8 @@ class SharedPtr
|
|||||||
/// is required.
|
/// is required.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef C Type;
|
||||||
|
|
||||||
SharedPtr(): _pCounter(new RC), _ptr(0)
|
SharedPtr(): _pCounter(new RC), _ptr(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -362,8 +362,16 @@ Var& Var::getAt(std::size_t n)
|
|||||||
return holderImpl<std::deque<Var>,
|
return holderImpl<std::deque<Var>,
|
||||||
InvalidAccessException>("Not a deque.")->operator[](n);
|
InvalidAccessException>("Not a deque.")->operator[](n);
|
||||||
else if (isStruct())
|
else if (isStruct())
|
||||||
return structIndexOperator(holderImpl<Struct<int>,
|
{
|
||||||
InvalidAccessException>("Not a struct."), static_cast<int>(n));
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
if (isOrdered())
|
||||||
|
return structIndexOperator(holderImpl<Struct<int, OrderedMap<int, Var>, OrderedSet<int> >,
|
||||||
|
InvalidAccessException>("Not a struct."), static_cast<int>(n));
|
||||||
|
else
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
return structIndexOperator(holderImpl<Struct<int, std::map<int, Var>, std::set<int> >,
|
||||||
|
InvalidAccessException>("Not a struct."), static_cast<int>(n));
|
||||||
|
}
|
||||||
else if (!isString() && !isEmpty() && (n == 0))
|
else if (!isString() && !isEmpty() && (n == 0))
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
@ -385,8 +393,17 @@ char& Var::at(std::size_t n)
|
|||||||
|
|
||||||
Var& Var::getAt(const std::string& name)
|
Var& Var::getAt(const std::string& name)
|
||||||
{
|
{
|
||||||
return holderImpl<DynamicStruct,
|
if (isStruct())
|
||||||
InvalidAccessException>("Not a struct.")->operator[](name);
|
{
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
if (isOrdered())
|
||||||
|
return structIndexOperator(holderImpl<OrderedDynamicStruct, InvalidAccessException>("Not a struct."), name);
|
||||||
|
else
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
return structIndexOperator(holderImpl<DynamicStruct, InvalidAccessException>("Not a struct."), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw InvalidAccessException("Not a struct.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -626,11 +643,11 @@ std::string Var::toString(const Var& any)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
Var& Var::structIndexOperator(VarHolderImpl<Struct<int> >* pStr, int n) const
|
Var& Var::structIndexOperator(VarHolderImpl<Struct<int> >* pStr, int n) const
|
||||||
{
|
{
|
||||||
return pStr->operator[](n);
|
return pStr->operator[](n);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
} } // namespace Poco::Dynamic
|
} } // namespace Poco::Dynamic
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "Poco/Dynamic/VarIterator.h"
|
#include "Poco/Dynamic/VarIterator.h"
|
||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include "Poco/Dynamic/Struct.h"
|
//#include "Poco/Dynamic/Struct.h"
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
#if defined(_MSC_VER) && _MSC_VER < 1400
|
||||||
#pragma warning(disable:4800)//forcing value to bool 'true' or 'false'
|
#pragma warning(disable:4800)//forcing value to bool 'true' or 'false'
|
||||||
#endif
|
#endif
|
||||||
@ -2256,6 +2255,34 @@ void VarTest::testDynamicStructBasics()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VarTest::testOrderedDynamicStructBasics()
|
||||||
|
{
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
OrderedDynamicStruct aStruct;
|
||||||
|
assertTrue(aStruct.empty());
|
||||||
|
assertTrue(aStruct.size() == 0);
|
||||||
|
assertTrue(aStruct.members().empty());
|
||||||
|
|
||||||
|
aStruct.insert("First Name", "Little");
|
||||||
|
assertTrue(!aStruct.empty());
|
||||||
|
assertTrue(aStruct.size() == 1);
|
||||||
|
assertTrue(*(aStruct.members().begin()) == "First Name");
|
||||||
|
assertTrue(aStruct["First Name"] == "Little");
|
||||||
|
aStruct.insert("Last Name", "POCO");
|
||||||
|
assertTrue(aStruct.members().size() == 2);
|
||||||
|
aStruct.erase("First Name");
|
||||||
|
assertTrue(aStruct.size() == 1);
|
||||||
|
assertTrue(*(aStruct.members().begin()) == "Last Name");
|
||||||
|
aStruct.insert("Age", 1);
|
||||||
|
assertTrue(aStruct["Age"] == 1);
|
||||||
|
assertTrue(aStruct.members().size() == 2);
|
||||||
|
assertTrue(*(aStruct.members().begin()) == "Last Name");
|
||||||
|
aStruct.clear();
|
||||||
|
assertTrue(aStruct.size() == 0);
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VarTest::testDynamicStructString()
|
void VarTest::testDynamicStructString()
|
||||||
{
|
{
|
||||||
DynamicStruct aStruct;
|
DynamicStruct aStruct;
|
||||||
@ -2290,6 +2317,45 @@ void VarTest::testDynamicStructString()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VarTest::testOrderedDynamicStructString()
|
||||||
|
{
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
OrderedDynamicStruct aStruct;
|
||||||
|
aStruct["First Name"] = "Junior";
|
||||||
|
aStruct["Last Name"] = "POCO";
|
||||||
|
Var a1(aStruct);
|
||||||
|
assertTrue(a1["First Name"] == "Junior");
|
||||||
|
assertTrue(a1["Last Name"] == "POCO");
|
||||||
|
a1["First Name"] = "Senior";
|
||||||
|
assertTrue(a1["First Name"] == "Senior");
|
||||||
|
testGetIdxMustThrow(a1, 0);
|
||||||
|
|
||||||
|
typedef Struct<std::string, OrderedMap<std::string, Var>, OrderedSet<std::string> > OrderedStruct;
|
||||||
|
OrderedStruct s1;
|
||||||
|
s1["1"] = 1;
|
||||||
|
s1["2"] = 2;
|
||||||
|
s1["3"] = 3;
|
||||||
|
|
||||||
|
OrderedStruct s2(s1);
|
||||||
|
assertTrue(s2["1"] == 1);
|
||||||
|
assertTrue(s2["2"] == 2);
|
||||||
|
assertTrue(s2["3"] == 3);
|
||||||
|
|
||||||
|
OrderedMap<std::string, int> m1;
|
||||||
|
m1["2"] = 2;
|
||||||
|
m1["1"] = 1;
|
||||||
|
m1["3"] = 3;
|
||||||
|
assertTrue (m1.begin()->first == "2");
|
||||||
|
assertTrue(m1.begin()->second == 2);
|
||||||
|
|
||||||
|
OrderedStruct m2(m1);
|
||||||
|
assertTrue(m2["1"] == 1);
|
||||||
|
assertTrue(m2["2"] == 2);
|
||||||
|
assertTrue(m2["3"] == 3);
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VarTest::testDynamicStructInt()
|
void VarTest::testDynamicStructInt()
|
||||||
{
|
{
|
||||||
Dynamic::Struct<int> aStruct;
|
Dynamic::Struct<int> aStruct;
|
||||||
@ -2325,6 +2391,47 @@ void VarTest::testDynamicStructInt()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VarTest::testOrderedDynamicStructInt()
|
||||||
|
{
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
typedef Struct<int, OrderedMap<int, Var>, OrderedSet<int> > OrderedStruct;
|
||||||
|
OrderedStruct aStruct;
|
||||||
|
aStruct[0] = "POCO";
|
||||||
|
aStruct[1] = "Junior";
|
||||||
|
aStruct[2] = 100;
|
||||||
|
aStruct[3] = 10;
|
||||||
|
|
||||||
|
Var a1(aStruct);
|
||||||
|
assertTrue(a1[0] == "POCO");
|
||||||
|
assertTrue(a1[1] == "Junior");
|
||||||
|
assertTrue(a1[2] == 100);
|
||||||
|
assertTrue(a1[3] == 10);
|
||||||
|
a1[0] = "Senior";
|
||||||
|
assertTrue(a1[0] == "Senior");
|
||||||
|
|
||||||
|
OrderedStruct s1;
|
||||||
|
s1[1] = "1";
|
||||||
|
s1[2] = "2";
|
||||||
|
s1[3] = "3";
|
||||||
|
|
||||||
|
OrderedStruct s2(s1);
|
||||||
|
assertTrue(s2[1] == "1");
|
||||||
|
assertTrue(s2[2] == "2");
|
||||||
|
assertTrue(s2[3] == "3");
|
||||||
|
|
||||||
|
OrderedMap<int, std::string> m1;
|
||||||
|
m1[1] = "2";
|
||||||
|
m1[2] = "1";
|
||||||
|
m1[3] = "3";
|
||||||
|
|
||||||
|
OrderedStruct m2(m1);
|
||||||
|
assertTrue(m2[1] == "2");
|
||||||
|
assertTrue(m2[2] == "1");
|
||||||
|
assertTrue(m2[3] == "3");
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VarTest::testDynamicPair()
|
void VarTest::testDynamicPair()
|
||||||
{
|
{
|
||||||
Pair<int> aPair;
|
Pair<int> aPair;
|
||||||
@ -2414,6 +2521,22 @@ void VarTest::testStructToString()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VarTest::testOrderedStructToString()
|
||||||
|
{
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
OrderedDynamicStruct aStruct;
|
||||||
|
aStruct["First Name"] = "Junior";
|
||||||
|
aStruct["Last Name"] = "POCO";
|
||||||
|
aStruct["Age"] = 1;
|
||||||
|
Var a1(aStruct);
|
||||||
|
std::string res = a1.convert<std::string>();
|
||||||
|
std::string expected = "{ \"First Name\" : \"Junior\", \"Last Name\" : \"POCO\", \"Age\" : 1 }";
|
||||||
|
assertTrue(res == expected);
|
||||||
|
assertTrue(aStruct.toString() == res);
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VarTest::testStructToStringEscape()
|
void VarTest::testStructToStringEscape()
|
||||||
{
|
{
|
||||||
DynamicStruct aStruct;
|
DynamicStruct aStruct;
|
||||||
@ -2959,11 +3082,15 @@ CppUnit::Test* VarTest::suite()
|
|||||||
CppUnit_addTest(pSuite, VarTest, testArrayIdxOperator);
|
CppUnit_addTest(pSuite, VarTest, testArrayIdxOperator);
|
||||||
CppUnit_addTest(pSuite, VarTest, testDynamicPair);
|
CppUnit_addTest(pSuite, VarTest, testDynamicPair);
|
||||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructBasics);
|
CppUnit_addTest(pSuite, VarTest, testDynamicStructBasics);
|
||||||
|
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructBasics);
|
||||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructString);
|
CppUnit_addTest(pSuite, VarTest, testDynamicStructString);
|
||||||
|
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructString);
|
||||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructInt);
|
CppUnit_addTest(pSuite, VarTest, testDynamicStructInt);
|
||||||
|
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructInt);
|
||||||
CppUnit_addTest(pSuite, VarTest, testArrayToString);
|
CppUnit_addTest(pSuite, VarTest, testArrayToString);
|
||||||
CppUnit_addTest(pSuite, VarTest, testArrayToStringEscape);
|
CppUnit_addTest(pSuite, VarTest, testArrayToStringEscape);
|
||||||
CppUnit_addTest(pSuite, VarTest, testStructToString);
|
CppUnit_addTest(pSuite, VarTest, testStructToString);
|
||||||
|
CppUnit_addTest(pSuite, VarTest, testOrderedStructToString);
|
||||||
CppUnit_addTest(pSuite, VarTest, testStructToStringEscape);
|
CppUnit_addTest(pSuite, VarTest, testStructToStringEscape);
|
||||||
CppUnit_addTest(pSuite, VarTest, testArrayOfStructsToString);
|
CppUnit_addTest(pSuite, VarTest, testArrayOfStructsToString);
|
||||||
CppUnit_addTest(pSuite, VarTest, testStructWithArraysToString);
|
CppUnit_addTest(pSuite, VarTest, testStructWithArraysToString);
|
||||||
|
@ -55,11 +55,15 @@ public:
|
|||||||
void testArrayIdxOperator();
|
void testArrayIdxOperator();
|
||||||
void testDynamicPair();
|
void testDynamicPair();
|
||||||
void testDynamicStructBasics();
|
void testDynamicStructBasics();
|
||||||
|
void testOrderedDynamicStructBasics();
|
||||||
void testDynamicStructString();
|
void testDynamicStructString();
|
||||||
|
void testOrderedDynamicStructString();
|
||||||
void testDynamicStructInt();
|
void testDynamicStructInt();
|
||||||
|
void testOrderedDynamicStructInt();
|
||||||
void testArrayToString();
|
void testArrayToString();
|
||||||
void testArrayToStringEscape();
|
void testArrayToStringEscape();
|
||||||
void testStructToString();
|
void testStructToString();
|
||||||
|
void testOrderedStructToString();
|
||||||
void testStructToStringEscape();
|
void testStructToStringEscape();
|
||||||
void testArrayOfStructsToString();
|
void testArrayOfStructsToString();
|
||||||
void testStructWithArraysToString();
|
void testStructWithArraysToString();
|
||||||
|
@ -224,6 +224,16 @@ public:
|
|||||||
static Poco::DynamicStruct makeStruct(const Object::Ptr& obj);
|
static Poco::DynamicStruct makeStruct(const Object::Ptr& obj);
|
||||||
/// Utility function for creation of struct.
|
/// Utility function for creation of struct.
|
||||||
|
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
|
||||||
|
static Poco::OrderedDynamicStruct makeOrderedStruct(const Object::Ptr& obj);
|
||||||
|
/// Utility function for creation of ordered struct.
|
||||||
|
|
||||||
|
operator const Poco::OrderedDynamicStruct& () const;
|
||||||
|
/// Cast operator to Poco::OrderedDynamiStruct.
|
||||||
|
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
operator const Poco::DynamicStruct& () const;
|
operator const Poco::DynamicStruct& () const;
|
||||||
/// Cast operator to Poco::DynamiStruct.
|
/// Cast operator to Poco::DynamiStruct.
|
||||||
|
|
||||||
@ -235,10 +245,21 @@ public:
|
|||||||
private:
|
private:
|
||||||
typedef std::deque<ValueMap::const_iterator> KeyList;
|
typedef std::deque<ValueMap::const_iterator> KeyList;
|
||||||
typedef Poco::DynamicStruct::Ptr StructPtr;
|
typedef Poco::DynamicStruct::Ptr StructPtr;
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
typedef Poco::OrderedDynamicStruct::Ptr OrdStructPtr;
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
void resetDynStruct() const;
|
|
||||||
void syncKeys(const KeyList& keys);
|
void syncKeys(const KeyList& keys);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void resetDynStruct(T& pStruct) const
|
||||||
|
{
|
||||||
|
if (!pStruct)
|
||||||
|
pStruct = new typename T::Type;
|
||||||
|
else
|
||||||
|
pStruct->clear();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
void doStringify(const C& container, std::ostream& out, unsigned int indent, unsigned int step) const
|
void doStringify(const C& container, std::ostream& out, unsigned int indent, unsigned int step) const
|
||||||
{
|
{
|
||||||
@ -272,6 +293,59 @@ private:
|
|||||||
out << '}';
|
out << '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
static S makeStructImpl(const Object::Ptr& obj)
|
||||||
|
{
|
||||||
|
S ds;
|
||||||
|
|
||||||
|
if (obj->_preserveInsOrder)
|
||||||
|
{
|
||||||
|
KeyList::const_iterator it = obj->_keys.begin();
|
||||||
|
KeyList::const_iterator end = obj->_keys.end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
if (obj->isObject((*it)->first))
|
||||||
|
{
|
||||||
|
Object::Ptr pObj = obj->getObject((*it)->first);
|
||||||
|
S str = makeStructImpl<S>(pObj);
|
||||||
|
ds.insert((*it)->first, str);
|
||||||
|
}
|
||||||
|
else if (obj->isArray((*it)->first))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConstIterator it = obj->begin();
|
||||||
|
ConstIterator end = obj->end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
if (obj->isObject(it))
|
||||||
|
{
|
||||||
|
Object::Ptr pObj = obj->getObject(it->first);
|
||||||
|
S str = makeStructImpl<S>(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;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string& getKey(ValueMap::const_iterator& it) const;
|
const std::string& getKey(ValueMap::const_iterator& it) const;
|
||||||
const Dynamic::Var& getValue(ValueMap::const_iterator& it) const;
|
const Dynamic::Var& getValue(ValueMap::const_iterator& it) const;
|
||||||
const std::string& getKey(KeyList::const_iterator& it) const;
|
const std::string& getKey(KeyList::const_iterator& it) const;
|
||||||
@ -285,8 +359,11 @@ private:
|
|||||||
// because Object can be returned stringified from Dynamic::Var::toString(),
|
// because Object can be returned stringified from Dynamic::Var::toString(),
|
||||||
// so it must know whether to escape unicode or not.
|
// so it must know whether to escape unicode or not.
|
||||||
bool _escapeUnicode;
|
bool _escapeUnicode;
|
||||||
mutable StructPtr _pStruct;
|
mutable StructPtr _pStruct;
|
||||||
mutable bool _modified;
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
mutable OrdStructPtr _pOrdStruct;
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
mutable bool _modified;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,52 +220,51 @@ Object& Object::set(const std::string& key, const Dynamic::Var& value)
|
|||||||
|
|
||||||
Poco::DynamicStruct Object::makeStruct(const Object::Ptr& obj)
|
Poco::DynamicStruct Object::makeStruct(const Object::Ptr& obj)
|
||||||
{
|
{
|
||||||
Poco::DynamicStruct ds;
|
return makeStructImpl<Poco::DynamicStruct>(obj);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
|
/*
|
||||||
void Object::resetDynStruct() const
|
void Object::resetDynStruct() const
|
||||||
{
|
{
|
||||||
if (!_pStruct)
|
if (!_pStruct)
|
||||||
_pStruct = new Poco::DynamicStruct;
|
_pStruct = new Poco::DynamicStruct;
|
||||||
else
|
else
|
||||||
_pStruct->clear();
|
_pStruct->clear();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
Object::operator const Poco::DynamicStruct& () const
|
Object::operator const Poco::DynamicStruct& () const
|
||||||
{
|
{
|
||||||
if (!_values.size())
|
if (!_values.size())
|
||||||
{
|
{
|
||||||
resetDynStruct();
|
resetDynStruct(_pStruct);
|
||||||
}
|
}
|
||||||
else if (_modified)
|
else if (_modified)
|
||||||
{
|
{
|
||||||
ValueMap::const_iterator it = _values.begin();
|
ValueMap::const_iterator it = _values.begin();
|
||||||
ValueMap::const_iterator end = _values.end();
|
ValueMap::const_iterator end = _values.end();
|
||||||
resetDynStruct();
|
resetDynStruct(_pStruct);
|
||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
{
|
{
|
||||||
if (isObject(it))
|
if (isObject(it))
|
||||||
@ -287,6 +286,68 @@ Object::operator const Poco::DynamicStruct& () const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
|
|
||||||
void Object::clear()
|
void Object::clear()
|
||||||
{
|
{
|
||||||
_values.clear();
|
_values.clear();
|
||||||
|
@ -1587,7 +1587,6 @@ void JSONTest::testStringifyPreserveOrder()
|
|||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
|
|
||||||
Stringifier::condense(result, ostr);
|
Stringifier::condense(result, ostr);
|
||||||
std::cout << ostr.str() << std::endl;
|
|
||||||
assertTrue (ostr.str() == "{\"Simpsons\":{\"husband\":{\"name\":\"Homer\",\"age\":38},\"wife\":{\"name\":\"Marge\",\"age\":36},"
|
assertTrue (ostr.str() == "{\"Simpsons\":{\"husband\":{\"name\":\"Homer\",\"age\":38},\"wife\":{\"name\":\"Marge\",\"age\":36},"
|
||||||
"\"children\":[\"Bart\",\"Lisa\",\"Maggie\"],"
|
"\"children\":[\"Bart\",\"Lisa\",\"Maggie\"],"
|
||||||
"\"address\":{\"number\":742,\"street\":\"Evergreen Terrace\",\"town\":\"Springfield\"}}}");
|
"\"address\":{\"number\":742,\"street\":\"Evergreen Terrace\",\"town\":\"Springfield\"}}}");
|
||||||
@ -1674,7 +1673,12 @@ void JSONTest::testStringifyPreserveOrder()
|
|||||||
"}");
|
"}");
|
||||||
|
|
||||||
Poco::DynamicStruct ds = *result.extract<Object::Ptr>();
|
Poco::DynamicStruct ds = *result.extract<Object::Ptr>();
|
||||||
|
assertTrue(ds.toString() == "{ \"Simpsons\" : { \"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", \"town\" : \"Springfield\" }, "
|
||||||
|
"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
|
||||||
|
"\"husband\" : { \"age\" : 38, \"name\" : \"Homer\" }, "
|
||||||
|
"\"wife\" : { \"age\" : 36, \"name\" : \"Marge\" } } }");
|
||||||
assertTrue (ds["Simpsons"].isStruct());
|
assertTrue (ds["Simpsons"].isStruct());
|
||||||
|
assertFalse(ds["Simpsons"].isOrdered());
|
||||||
assertTrue (ds["Simpsons"]["husband"].isStruct());
|
assertTrue (ds["Simpsons"]["husband"].isStruct());
|
||||||
assertTrue (ds["Simpsons"]["husband"]["name"] == "Homer");
|
assertTrue (ds["Simpsons"]["husband"]["name"] == "Homer");
|
||||||
assertTrue (ds["Simpsons"]["husband"]["age"] == 38);
|
assertTrue (ds["Simpsons"]["husband"]["age"] == 38);
|
||||||
@ -1692,6 +1696,17 @@ void JSONTest::testStringifyPreserveOrder()
|
|||||||
assertTrue (ds["Simpsons"]["address"]["number"] == 742);
|
assertTrue (ds["Simpsons"]["address"]["number"] == 742);
|
||||||
assertTrue (ds["Simpsons"]["address"]["street"] == "Evergreen Terrace");
|
assertTrue (ds["Simpsons"]["address"]["street"] == "Evergreen Terrace");
|
||||||
assertTrue (ds["Simpsons"]["address"]["town"] == "Springfield");
|
assertTrue (ds["Simpsons"]["address"]["town"] == "Springfield");
|
||||||
|
|
||||||
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
Poco::OrderedDynamicStruct ods = *result.extract<Object::Ptr>();
|
||||||
|
assertTrue(ods["Simpsons"].isStruct());
|
||||||
|
assertTrue(ods["Simpsons"].isOrdered());
|
||||||
|
assertTrue(ods.toString() == "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\", \"age\" : 38 }, "
|
||||||
|
"\"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
|
||||||
|
"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
|
||||||
|
"\"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", "
|
||||||
|
"\"town\" : \"Springfield\" } } }");
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user