mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-13 10:32:57 +01:00
Var/JSON changes
- JSON support for Dynamic Struct and Array - added VarIterator - modified behavior of empty Var
This commit is contained in:
parent
1f8fcaacc0
commit
38131d452d
@ -81,7 +81,7 @@ class Data_API Statement
|
||||
/// However, calling executAsync() on a synchronous statement shall execute
|
||||
/// asynchronously but without altering the underlying statement's synchronous nature.
|
||||
///
|
||||
/// Once asyncronous, a statement can be reverted back to synchronous state in two ways:
|
||||
/// Once asynchronous, a statement can be reverted back to synchronous state in two ways:
|
||||
///
|
||||
/// 1) By calling setAsync(false)
|
||||
/// 2) By means of 'sync' or 'reset' manipulators
|
||||
|
@ -6813,6 +6813,10 @@
|
||||
RelativePath=".\include\Poco\Dynamic\VarHolder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Dynamic\VarIterator.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
@ -6825,6 +6829,10 @@
|
||||
RelativePath=".\src\VarHolder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\VarIterator.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
|
@ -389,6 +389,7 @@
|
||||
<ClCompile Include="src\UTF32Encoding.cpp" />
|
||||
<ClCompile Include="src\Var.cpp" />
|
||||
<ClCompile Include="src\VarHolder.cpp" />
|
||||
<ClCompile Include="src\VarIterator.cpp" />
|
||||
<ClCompile Include="src\Void.cpp" />
|
||||
<ClCompile Include="src\Base64Decoder.cpp" />
|
||||
<ClCompile Include="src\Base64Encoder.cpp" />
|
||||
@ -998,6 +999,7 @@
|
||||
<ClInclude Include="include\Poco\Dynamic\Struct.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\Var.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\VarHolder.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\VarIterator.h" />
|
||||
<ClInclude Include="include\Poco\Environment.h" />
|
||||
<ClInclude Include="include\Poco\Environment_UNIX.h" />
|
||||
<ClInclude Include="include\Poco\Environment_VMS.h" />
|
||||
|
@ -870,6 +870,9 @@
|
||||
<ClCompile Include="src\VarHolder.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\VarIterator.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Latin2Encoding.cpp">
|
||||
<Filter>Text\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1820,6 +1823,9 @@
|
||||
<ClInclude Include="include\Poco\Dynamic\VarHolder.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Dynamic\VarIterator.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Windows1250Encoding.h">
|
||||
<Filter>Text\Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -393,6 +393,7 @@
|
||||
<ClCompile Include="src\UTF32Encoding.cpp" />
|
||||
<ClCompile Include="src\Var.cpp" />
|
||||
<ClCompile Include="src\VarHolder.cpp" />
|
||||
<ClCompile Include="src\VarIterator.cpp" />
|
||||
<ClCompile Include="src\Void.cpp" />
|
||||
<ClCompile Include="src\Base32Decoder.cpp" />
|
||||
<ClCompile Include="src\Base32Encoder.cpp" />
|
||||
@ -1002,6 +1003,7 @@
|
||||
<ClInclude Include="include\Poco\Dynamic\Struct.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\Var.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\VarHolder.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\VarIterator.h" />
|
||||
<ClInclude Include="include\Poco\Environment.h" />
|
||||
<ClInclude Include="include\Poco\Environment_UNIX.h" />
|
||||
<ClInclude Include="include\Poco\Environment_VMS.h" />
|
||||
|
@ -888,6 +888,9 @@
|
||||
<ClCompile Include="src\VarHolder.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Variterator.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Latin2Encoding.cpp">
|
||||
<Filter>Text\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1850,6 +1853,9 @@
|
||||
<ClInclude Include="include\Poco\Dynamic\VarHolder.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Dynamic\VarIterator.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Windows1250Encoding.h">
|
||||
<Filter>Text\Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -4700,6 +4700,9 @@
|
||||
<File
|
||||
RelativePath=".\src\VarHolder.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\VarIterator.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
@ -4716,6 +4719,9 @@
|
||||
<File
|
||||
RelativePath=".\include\poco\dynamic\VarHolder.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\poco\dynamic\VarIterator.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
|
@ -6101,6 +6101,10 @@
|
||||
RelativePath=".\include\Poco\Dynamic\VarHolder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Dynamic\VarIterator.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
@ -6113,6 +6117,10 @@
|
||||
RelativePath=".\src\VarHolder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\VarIterator.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
|
@ -6094,6 +6094,10 @@
|
||||
RelativePath=".\include\Poco\Dynamic\VarHolder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Dynamic\VarIterator.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
@ -6106,6 +6110,10 @@
|
||||
RelativePath=".\src\VarHolder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\VarIterator.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
|
@ -393,6 +393,7 @@
|
||||
<ClCompile Include="src\UTF32Encoding.cpp" />
|
||||
<ClCompile Include="src\Var.cpp" />
|
||||
<ClCompile Include="src\VarHolder.cpp" />
|
||||
<ClCompile Include="src\VarIterator.cpp" />
|
||||
<ClCompile Include="src\Void.cpp" />
|
||||
<ClCompile Include="src\Base32Decoder.cpp" />
|
||||
<ClCompile Include="src\Base32Encoder.cpp" />
|
||||
@ -1001,6 +1002,7 @@
|
||||
<ClInclude Include="include\Poco\Dynamic\Struct.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\Var.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\VarHolder.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\VarIterator.h" />
|
||||
<ClInclude Include="include\Poco\Environment.h" />
|
||||
<ClInclude Include="include\Poco\Environment_UNIX.h" />
|
||||
<ClInclude Include="include\Poco\Environment_VMS.h" />
|
||||
|
@ -891,6 +891,9 @@
|
||||
<ClCompile Include="src\VarHolder.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\VarIterator.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Latin2Encoding.cpp">
|
||||
<Filter>Text\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1853,6 +1856,9 @@
|
||||
<ClInclude Include="include\Poco\Dynamic\VarHolder.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Dynamic\VarIterator.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Latin2Encoding.h">
|
||||
<Filter>Text\Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -399,6 +399,7 @@
|
||||
<ClCompile Include="src\UTF32Encoding.cpp" />
|
||||
<ClCompile Include="src\Var.cpp" />
|
||||
<ClCompile Include="src\VarHolder.cpp" />
|
||||
<ClCompile Include="src\VarIterator.cpp" />
|
||||
<ClCompile Include="src\Void.cpp" />
|
||||
<ClCompile Include="src\Base32Decoder.cpp" />
|
||||
<ClCompile Include="src\Base32Encoder.cpp" />
|
||||
@ -1007,6 +1008,7 @@
|
||||
<ClInclude Include="include\Poco\Dynamic\Struct.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\Var.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\VarHolder.h" />
|
||||
<ClInclude Include="include\Poco\Dynamic\VarIterator.h" />
|
||||
<ClInclude Include="include\Poco\Environment.h" />
|
||||
<ClInclude Include="include\Poco\Environment_UNIX.h" />
|
||||
<ClInclude Include="include\Poco\Environment_VMS.h" />
|
||||
|
@ -891,6 +891,9 @@
|
||||
<ClCompile Include="src\VarHolder.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\VarIterator.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Latin2Encoding.cpp">
|
||||
<Filter>Text\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1853,6 +1856,9 @@
|
||||
<ClInclude Include="include\Poco\Dynamic\VarHolder.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Dynamic\VarIterator.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Latin2Encoding.h">
|
||||
<Filter>Text\Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -6096,6 +6096,10 @@
|
||||
RelativePath=".\include\Poco\Dynamic\VarHolder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Dynamic\VarIterator.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
@ -6108,6 +6112,10 @@
|
||||
RelativePath=".\src\VarHolder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\VarIterator.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
|
@ -73,13 +73,13 @@ public:
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Pair(const std::pair<K, T>& val): _data(std::make_pair(val.first, Var(val.second)))
|
||||
Pair(const std::pair<K, T>& val): _data(std::make_pair(val.first, val.second))
|
||||
/// Creates Pair form standard pair.
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Pair(const K& first, const T& second): _data(std::make_pair(first, Var(second)))
|
||||
Pair(const K& first, const T& second): _data(std::make_pair(first, second))
|
||||
/// Creates pair from two values.
|
||||
{
|
||||
}
|
||||
@ -90,15 +90,10 @@ public:
|
||||
}
|
||||
|
||||
Pair& swap(Pair& other)
|
||||
|
||||
/// Swaps the content of the two Pairs.
|
||||
|
||||
{
|
||||
|
||||
std::swap(_data, other._data);
|
||||
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
Pair& operator = (const Pair& other)
|
||||
@ -215,9 +210,9 @@ public:
|
||||
// JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
|
||||
val.append("{ ");
|
||||
Var key(_val.first());
|
||||
appendJSONKey(val, key);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(" : ");
|
||||
appendJSONValue(val, _val.second());
|
||||
Impl::appendJSONValue(val, _val.second());
|
||||
val.append(" }");
|
||||
}
|
||||
|
||||
@ -364,9 +359,9 @@ public:
|
||||
// JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
|
||||
val.append("{ ");
|
||||
Var key(_val.first());
|
||||
appendJSONKey(val, key);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(" : ");
|
||||
appendJSONValue(val, _val.second());
|
||||
Impl::appendJSONValue(val, _val.second());
|
||||
val.append(" }");
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/Dynamic/VarHolder.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
@ -63,6 +64,7 @@ public:
|
||||
typedef typename Struct<K>::Data::value_type ValueType;
|
||||
typedef typename Struct<K>::Data::size_type SizeType;
|
||||
typedef typename std::pair<typename Struct<K>::Iterator, bool> InsRetVal;
|
||||
typedef typename SharedPtr<Struct<K> > Ptr;
|
||||
|
||||
Struct(): _data()
|
||||
/// Creates an empty Struct
|
||||
@ -148,7 +150,8 @@ public:
|
||||
return _data.begin();
|
||||
}
|
||||
|
||||
inline InsRetVal insert(const K& key, const Var& value)
|
||||
template <typename T>
|
||||
inline InsRetVal insert(const K& key, const T& value)
|
||||
/// Inserts a <name, Var> pair into the Struct,
|
||||
/// returns a pair containing the iterator and a boolean which
|
||||
/// indicates success or not (is true, when insert succeeded, false,
|
||||
@ -156,7 +159,7 @@ public:
|
||||
/// points to that other element)
|
||||
{
|
||||
// fix: SunPro C++ is silly ...
|
||||
ValueType valueType(key,value);
|
||||
ValueType valueType(key, value);
|
||||
return insert(valueType);
|
||||
}
|
||||
|
||||
@ -301,18 +304,18 @@ public:
|
||||
if (!_val.empty())
|
||||
{
|
||||
Var key(it->first);
|
||||
appendJSONKey(val, key);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(" : ");
|
||||
appendJSONValue(val, it->second);
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
++it;
|
||||
}
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
val.append(", ");
|
||||
Var key(it->first);
|
||||
appendJSONKey(val, key);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(" : ");
|
||||
appendJSONValue(val, it->second);
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
}
|
||||
val.append(" }");
|
||||
}
|
||||
@ -371,6 +374,11 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return _val.size();
|
||||
}
|
||||
|
||||
Var& operator [] (const std::string& name)
|
||||
{
|
||||
@ -472,18 +480,18 @@ public:
|
||||
if (!_val.empty())
|
||||
{
|
||||
Var key(it->first);
|
||||
appendJSONKey(val, key);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(" : ");
|
||||
appendJSONValue(val, it->second);
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
++it;
|
||||
}
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
val.append(", ");
|
||||
Var key(it->first);
|
||||
appendJSONKey(val, key);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(" : ");
|
||||
appendJSONValue(val, it->second);
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
}
|
||||
val.append(" }");
|
||||
}
|
||||
@ -543,6 +551,11 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return _val.size();
|
||||
}
|
||||
|
||||
Var& operator [] (int name)
|
||||
{
|
||||
return _val[name];
|
||||
@ -561,7 +574,6 @@ private:
|
||||
} // namespace Dynamic
|
||||
|
||||
|
||||
//@ deprecated
|
||||
typedef Dynamic::Struct<std::string> DynamicStruct;
|
||||
|
||||
|
||||
|
@ -42,7 +42,9 @@
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/Format.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/Dynamic/VarHolder.h"
|
||||
#include "Poco/Dynamic/VarIterator.h"
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
@ -97,6 +99,10 @@ class Foundation_API Var
|
||||
/// VarHolderImpl is available. For supported types, see VarHolder documentation.
|
||||
{
|
||||
public:
|
||||
typedef SharedPtr<Var> Ptr;
|
||||
typedef Poco::Dynamic::VarIterator Iterator;
|
||||
typedef const VarIterator ConstIterator;
|
||||
|
||||
Var();
|
||||
/// Creates an empty Var.
|
||||
|
||||
@ -104,8 +110,14 @@ public:
|
||||
Var(const T& val)
|
||||
/// Creates the Var from the given value.
|
||||
#ifdef POCO_NO_SOO
|
||||
:_pHolder(new VarHolderImpl<T>(val)) { }
|
||||
: _pHolder(new VarHolderImpl<T>(val)),
|
||||
_pBegin(new Iterator(this, false)),
|
||||
_pEnd(new Iterator(this, true))
|
||||
{
|
||||
}
|
||||
#else
|
||||
: _pBegin(new Iterator(this, false)),
|
||||
_pEnd(new Iterator(this, true))
|
||||
{
|
||||
construct(val);
|
||||
}
|
||||
@ -123,6 +135,18 @@ public:
|
||||
void swap(Var& other);
|
||||
/// Swaps the content of the this Var with the other Var.
|
||||
|
||||
ConstIterator& begin() const;
|
||||
/// Returns the const Var iterator.
|
||||
|
||||
ConstIterator& end() const;
|
||||
/// Returns the const Var iterator.
|
||||
|
||||
Iterator begin();
|
||||
/// Returns the Var iterator.
|
||||
|
||||
Iterator end();
|
||||
/// Returns the Var iterator.
|
||||
|
||||
template <typename T>
|
||||
void convert(T& val) const
|
||||
/// Invoke this method to perform a safe conversion.
|
||||
@ -427,49 +451,45 @@ public:
|
||||
|
||||
template <typename T>
|
||||
bool operator && (const T& other) const
|
||||
/// Logical AND operator
|
||||
/// Logical AND operator.
|
||||
{
|
||||
if (isEmpty()) return false;
|
||||
return convert<bool>() && other;
|
||||
}
|
||||
|
||||
bool operator && (const Var& other) const;
|
||||
/// Logical AND operator operator overload for Var
|
||||
/// Logical AND operator operator overload for Var.
|
||||
|
||||
bool isArray() const;
|
||||
/// Returns true if Var represents a vector
|
||||
/// Returns true if Var is not empty.
|
||||
|
||||
bool isVector() const;
|
||||
/// Returns true if Var represents a vector.
|
||||
|
||||
bool isList() const;
|
||||
/// Returns true if Var represents a list.
|
||||
|
||||
bool isDeque() const;
|
||||
/// Returns true if Var represents a deque.
|
||||
|
||||
bool isStruct() const;
|
||||
/// Returns true if Var represents a struct
|
||||
/// Returns true if Var represents a struct.
|
||||
|
||||
char& at(std::size_t n);
|
||||
/// Returns character at position n. This function only works with
|
||||
/// Var containing a std::string.
|
||||
|
||||
|
||||
template <typename T>
|
||||
Var& operator [] (T n)
|
||||
/// Index operator, only use on Vars where isArray() or isStruct()
|
||||
/// returns true! In all other cases InvalidAccessException is thrown.
|
||||
Var& operator [] (const T& n)
|
||||
{
|
||||
if (isArray())
|
||||
return holderImpl<std::vector<Var>,
|
||||
InvalidAccessException>("Not an array.")->operator[](n);
|
||||
else if (isStruct())
|
||||
return structIndexOperator(holderImpl<Struct<int>,
|
||||
InvalidAccessException>("Not a struct."), static_cast<int>(n));
|
||||
else
|
||||
throw InvalidAccessException("Must be struct or array.");
|
||||
return getAt(n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const Var& operator [] (T n) const
|
||||
/// const Index operator, only use on Vars where isArray() or isStruct()
|
||||
/// returns true! In all other cases InvalidAccessException is thrown.
|
||||
const Var& operator [] (const T& n) const
|
||||
{
|
||||
if (isArray())
|
||||
return holderImpl<std::vector<Var>,
|
||||
InvalidAccessException>("Not an array.")->operator[](n);
|
||||
else if (isStruct())
|
||||
return structIndexOperator(holderImpl<Struct<int>,
|
||||
InvalidAccessException>("Not a struct."), static_cast<int>(n));
|
||||
else
|
||||
throw InvalidAccessException("Must be struct or array.");
|
||||
return const_cast<Var*>(this)->getAt(n);
|
||||
}
|
||||
|
||||
Var& operator [] (const std::string& name);
|
||||
@ -480,14 +500,6 @@ public:
|
||||
/// Index operator by name, only use on Vars where isStruct
|
||||
/// returns true! In all other cases InvalidAccessException is thrown.
|
||||
|
||||
Var& operator [] (const char* name);
|
||||
/// Index operator by name, only use on Vars where isStruct
|
||||
/// returns true! In all other cases InvalidAccessException is thrown.
|
||||
|
||||
const Var& operator [] (const char* name) const;
|
||||
/// Index operator by name, only use on Vars where isStruct
|
||||
/// returns true! In all other cases InvalidAccessException is thrown.
|
||||
|
||||
const std::type_info& type() const;
|
||||
/// Returns the type information of the stored content.
|
||||
|
||||
@ -510,6 +522,11 @@ public:
|
||||
bool isString() const;
|
||||
/// Returns true if stored value is std::string.
|
||||
|
||||
std::size_t Var::size() const;
|
||||
/// Returns the size of this Var.
|
||||
/// This function returns 0 when Var is empty, 1 for POD or the size (i.e. length)
|
||||
/// for held container.
|
||||
|
||||
std::string toString() const
|
||||
/// Returns the stored value as string.
|
||||
{
|
||||
@ -536,6 +553,9 @@ public:
|
||||
/// a different result than Var::convert<std::string>() and Var::toString()!
|
||||
|
||||
private:
|
||||
Var& getAt(std::size_t n);
|
||||
Var& getAt(const std::string& n);
|
||||
|
||||
static Var parse(const std::string& val, std::string::size_type& offset);
|
||||
/// Parses the string which must be in JSON format
|
||||
|
||||
@ -656,7 +676,9 @@ private:
|
||||
Placeholder<VarHolder> _placeholder;
|
||||
|
||||
#endif // POCO_NO_SOO
|
||||
|
||||
|
||||
Iterator* _pBegin;
|
||||
Iterator* _pEnd;
|
||||
};
|
||||
|
||||
|
||||
@ -710,15 +732,42 @@ inline const std::type_info& Var::type() const
|
||||
}
|
||||
|
||||
|
||||
inline Var& Var::operator [] (const char* name)
|
||||
inline Var::ConstIterator& Var::begin() const
|
||||
{
|
||||
return operator [] (std::string(name));
|
||||
if (isEmpty()) _pBegin->setPosition(Iterator::POSITION_END);
|
||||
else if (*_pBegin == *_pEnd) _pBegin->setPosition(0);
|
||||
|
||||
return *_pBegin;
|
||||
}
|
||||
|
||||
inline Var::ConstIterator& Var::end() const
|
||||
{
|
||||
return *_pEnd;
|
||||
}
|
||||
|
||||
inline Var::Iterator Var::begin()
|
||||
{
|
||||
if (isEmpty()) _pBegin->setPosition(Iterator::POSITION_END);
|
||||
else if (*_pBegin == *_pEnd) _pBegin->setPosition(0);
|
||||
|
||||
return *_pBegin;
|
||||
}
|
||||
|
||||
inline Var::Iterator Var::end()
|
||||
{
|
||||
return *_pEnd;
|
||||
}
|
||||
|
||||
|
||||
inline const Var& Var::operator [] (const char* name) const
|
||||
inline Var& Var::operator [] (const std::string& name)
|
||||
{
|
||||
return operator [] (std::string(name));
|
||||
return getAt(name);
|
||||
}
|
||||
|
||||
|
||||
inline const Var& Var::operator [] (const std::string& name) const
|
||||
{
|
||||
return const_cast<Var*>(this)->getAt(name);
|
||||
}
|
||||
|
||||
|
||||
@ -747,9 +796,29 @@ inline bool Var::isEmpty() const
|
||||
|
||||
|
||||
inline bool Var::isArray() const
|
||||
{
|
||||
return !isEmpty() && !isString();
|
||||
}
|
||||
|
||||
|
||||
inline bool Var::isVector() const
|
||||
{
|
||||
VarHolder* pHolder = content();
|
||||
return pHolder ? pHolder->isArray() : false;
|
||||
return pHolder ? pHolder->isVector() : false;
|
||||
}
|
||||
|
||||
|
||||
inline bool Var::isList() const
|
||||
{
|
||||
VarHolder* pHolder = content();
|
||||
return pHolder ? pHolder->isList() : false;
|
||||
}
|
||||
|
||||
|
||||
inline bool Var::isDeque() const
|
||||
{
|
||||
VarHolder* pHolder = content();
|
||||
return pHolder ? pHolder->isDeque() : false;
|
||||
}
|
||||
|
||||
|
||||
@ -788,6 +857,13 @@ inline bool Var::isString() const
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t Var::size() const
|
||||
{
|
||||
VarHolder* pHolder = content();
|
||||
return pHolder ? pHolder->size() : 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Var non-member functions
|
||||
///
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include "Poco/Any.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <typeinfo>
|
||||
#undef min
|
||||
#undef max
|
||||
@ -66,6 +68,9 @@ namespace Dynamic {
|
||||
class Var;
|
||||
|
||||
|
||||
namespace Impl {
|
||||
|
||||
|
||||
bool Foundation_API isJSONString(const Var& any);
|
||||
/// Returns true for values that should be JSON-formatted as string.
|
||||
|
||||
@ -86,6 +91,35 @@ void Foundation_API appendJSONValue(std::string& val, const Var& any);
|
||||
/// and appends it to val
|
||||
|
||||
|
||||
template <typename C>
|
||||
void containerToJSON(C& cont, std::string& val)
|
||||
{
|
||||
// Serialize in JSON format. Note: although this is a vector<T>, the code only
|
||||
// supports vector<Var>. Total specialization is not possible
|
||||
// because of the cyclic dependency between Var and VarHolder
|
||||
|
||||
// JSON format definition: [ n times: elem ',' ], no ',' for last elem
|
||||
val.append("[ ");
|
||||
typename C::const_iterator it = cont.begin();
|
||||
typename C::const_iterator itEnd = cont.end();
|
||||
if (!cont.empty())
|
||||
{
|
||||
appendJSONValue(val, *it);
|
||||
++it;
|
||||
}
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
|
||||
val.append(", ");
|
||||
appendJSONValue(val, *it);
|
||||
}
|
||||
val.append(" ]");
|
||||
}
|
||||
|
||||
|
||||
} // namespace Impl
|
||||
|
||||
|
||||
class Foundation_API VarHolder
|
||||
/// Interface for a data holder used by the Var class.
|
||||
/// Provides methods to convert between data types.
|
||||
@ -103,6 +137,8 @@ class Foundation_API VarHolder
|
||||
/// throw BadCastException.
|
||||
{
|
||||
public:
|
||||
typedef Var ArrayValueType;
|
||||
|
||||
virtual ~VarHolder();
|
||||
/// Destroys the VarHolder.
|
||||
|
||||
@ -193,6 +229,17 @@ public:
|
||||
/// specialization in order to suport the conversion.
|
||||
|
||||
virtual bool isArray() const;
|
||||
/// Returns true.
|
||||
|
||||
virtual bool isVector() const;
|
||||
/// Returns false. Must be properly overriden in a type
|
||||
/// specialization in order to suport the diagnostic.
|
||||
|
||||
virtual bool isList() const;
|
||||
/// Returns false. Must be properly overriden in a type
|
||||
/// specialization in order to suport the diagnostic.
|
||||
|
||||
virtual bool isDeque() const;
|
||||
/// Returns false. Must be properly overriden in a type
|
||||
/// specialization in order to suport the diagnostic.
|
||||
|
||||
@ -216,6 +263,9 @@ public:
|
||||
/// Returns false. Must be properly overriden in a type
|
||||
/// specialization in order to suport the diagnostic.
|
||||
|
||||
virtual std::size_t size() const;
|
||||
/// Returns 1 iff Var is not empty or this function overriden.
|
||||
|
||||
protected:
|
||||
VarHolder();
|
||||
/// Creates the VarHolder.
|
||||
@ -504,6 +554,24 @@ inline void VarHolder::convert(std::string& /*val*/) const
|
||||
|
||||
|
||||
inline bool VarHolder::isArray() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool VarHolder::isVector() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline bool VarHolder::isList() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline bool VarHolder::isDeque() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -537,6 +605,11 @@ inline bool VarHolder::isString() const
|
||||
return false;
|
||||
}
|
||||
|
||||
inline std::size_t VarHolder::size() const
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
class VarHolderImpl: public VarHolder
|
||||
@ -2226,8 +2299,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
class VarHolderImpl<std::string>: public VarHolder
|
||||
template <typename T>
|
||||
class VarHolderImpl<std::basic_string<T> >: public VarHolder
|
||||
{
|
||||
public:
|
||||
VarHolderImpl(const char* pVal): _val(pVal)
|
||||
@ -2366,42 +2439,36 @@ public:
|
||||
return _val;
|
||||
}
|
||||
|
||||
bool isArray() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isStruct() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isInteger() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSigned() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isNumeric() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isString() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return _val.length();
|
||||
}
|
||||
|
||||
T& operator[](std::string::size_type n)
|
||||
{
|
||||
if (n < size()) return _val.operator[](n);
|
||||
|
||||
throw RangeException("String index out of range");
|
||||
}
|
||||
|
||||
const T& operator[](std::string::size_type n) const
|
||||
{
|
||||
if (n < size()) return _val.operator[](n);
|
||||
|
||||
throw RangeException("String index out of range");
|
||||
}
|
||||
|
||||
private:
|
||||
VarHolderImpl();
|
||||
VarHolderImpl(const VarHolderImpl&);
|
||||
VarHolderImpl& operator = (const VarHolderImpl&);
|
||||
|
||||
std::string _val;
|
||||
std::basic_string<T> _val;
|
||||
};
|
||||
|
||||
|
||||
@ -2696,26 +2763,7 @@ public:
|
||||
|
||||
void convert(std::string& val) const
|
||||
{
|
||||
// Serialize in JSON format: note: although this is a vector<T>, the code only
|
||||
// supports vector<Var>. Total specialization is not possible
|
||||
// because of the cyclic dependency between Var and VarHolder
|
||||
|
||||
// JSON format definition: [ n times: elem ',' ], no ',' for last elem
|
||||
val.append("[ ");
|
||||
typename std::vector<T>::const_iterator it = _val.begin();
|
||||
typename std::vector<T>::const_iterator itEnd = _val.end();
|
||||
if (!_val.empty())
|
||||
{
|
||||
appendJSONValue(val, *it);
|
||||
++it;
|
||||
}
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
|
||||
val.append(", ");
|
||||
appendJSONValue(val, *it);
|
||||
}
|
||||
val.append(" ]");
|
||||
Impl::containerToJSON(_val, val);
|
||||
}
|
||||
|
||||
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||
@ -2728,44 +2776,28 @@ public:
|
||||
return _val;
|
||||
}
|
||||
|
||||
bool isArray() const
|
||||
bool isVector() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isStruct() const
|
||||
std::size_t size() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isInteger() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSigned() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isNumeric() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isString() const
|
||||
{
|
||||
return false;
|
||||
return _val.size();
|
||||
}
|
||||
|
||||
T& operator[](typename std::vector<T>::size_type n)
|
||||
{
|
||||
return _val.operator[](n);
|
||||
if (n < size()) return _val.operator[](n);
|
||||
|
||||
throw RangeException("List index out of range");
|
||||
}
|
||||
|
||||
const T& operator[](typename std::vector<T>::size_type n) const
|
||||
{
|
||||
return _val.operator[](n);
|
||||
if (n < size()) return _val.operator[](n);
|
||||
|
||||
throw RangeException("List index out of range");
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2777,6 +2809,146 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class VarHolderImpl<std::list<T> >: public VarHolder
|
||||
{
|
||||
public:
|
||||
VarHolderImpl(const std::list<T>& val): _val(val)
|
||||
{
|
||||
}
|
||||
|
||||
~VarHolderImpl()
|
||||
{
|
||||
}
|
||||
|
||||
const std::type_info& type() const
|
||||
{
|
||||
return typeid(std::list<T>);
|
||||
}
|
||||
|
||||
void convert(std::string& val) const
|
||||
{
|
||||
Impl::containerToJSON(_val, val);
|
||||
}
|
||||
|
||||
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||
{
|
||||
return cloneHolder(pVarHolder, _val);
|
||||
}
|
||||
|
||||
const std::list<T>& value() const
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
bool isList() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return _val.size();
|
||||
}
|
||||
|
||||
T& operator[](typename std::list<T>::size_type n)
|
||||
{
|
||||
if (n >= size())
|
||||
throw RangeException("List index out of range");
|
||||
|
||||
std::list<T>::size_type counter = 0;
|
||||
std::list<T>::iterator it = _val.begin();
|
||||
for (; counter < n; ++counter) ++it;
|
||||
|
||||
return *it;
|
||||
}
|
||||
|
||||
const T& operator[](typename std::list<T>::size_type n) const
|
||||
{
|
||||
if (n >= size())
|
||||
throw RangeException("List index out of range");
|
||||
|
||||
std::list<T>::size_type counter = 0;
|
||||
std::list<T>::const_iterator it = _val.begin();
|
||||
for (; counter < n; ++counter) ++it;
|
||||
|
||||
return *it;
|
||||
}
|
||||
|
||||
private:
|
||||
VarHolderImpl();
|
||||
VarHolderImpl(const VarHolderImpl&);
|
||||
VarHolderImpl& operator = (const VarHolderImpl&);
|
||||
|
||||
std::list<T> _val;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class VarHolderImpl<std::deque<T> >: public VarHolder
|
||||
{
|
||||
public:
|
||||
VarHolderImpl(const std::deque<T>& val): _val(val)
|
||||
{
|
||||
}
|
||||
|
||||
~VarHolderImpl()
|
||||
{
|
||||
}
|
||||
|
||||
const std::type_info& type() const
|
||||
{
|
||||
return typeid(std::deque<T>);
|
||||
}
|
||||
|
||||
void convert(std::string& val) const
|
||||
{
|
||||
Impl::containerToJSON(_val, val);
|
||||
}
|
||||
|
||||
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||
{
|
||||
return cloneHolder(pVarHolder, _val);
|
||||
}
|
||||
|
||||
const std::deque<T>& value() const
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
bool isDeque() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return _val.size();
|
||||
}
|
||||
|
||||
T& operator[](typename std::deque<T>::size_type n)
|
||||
{
|
||||
if (n < size()) return _val.operator[](n);
|
||||
|
||||
throw RangeException("List index out of range");
|
||||
}
|
||||
|
||||
const T& operator[](typename std::deque<T>::size_type n) const
|
||||
{
|
||||
if (n < size()) return _val.operator[](n);
|
||||
|
||||
throw RangeException("List index out of range");
|
||||
}
|
||||
|
||||
private:
|
||||
VarHolderImpl();
|
||||
VarHolderImpl(const VarHolderImpl&);
|
||||
VarHolderImpl& operator = (const VarHolderImpl&);
|
||||
|
||||
std::deque<T> _val;
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
class VarHolderImpl<DateTime>: public VarHolder
|
||||
{
|
||||
@ -3080,6 +3252,12 @@ private:
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<Var> Vector;
|
||||
typedef std::deque<Var> Deque;
|
||||
typedef std::list<Var> List;
|
||||
typedef Vector Array;
|
||||
|
||||
|
||||
} } // namespace Poco::Dynamic
|
||||
|
||||
|
||||
|
173
Foundation/include/Poco/Dynamic/VarIterator.h
Normal file
173
Foundation/include/Poco/Dynamic/VarIterator.h
Normal file
@ -0,0 +1,173 @@
|
||||
//
|
||||
// VarIterator.h
|
||||
//
|
||||
// $Id: //poco/Main/Foundation/include/Poco/Dynamic/VarIterator.h#1 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Dynamic
|
||||
// Module: VarIterator
|
||||
//
|
||||
// Definition of the VarIterator class.
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#ifndef Foundation_VarIterator_INCLUDED
|
||||
#define Foundation_VarIterator_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Exception.h"
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Dynamic {
|
||||
|
||||
|
||||
class Var;
|
||||
|
||||
|
||||
class Foundation_API VarIterator
|
||||
/// VarIterator class.
|
||||
{
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef Var value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Var* pointer;
|
||||
typedef Var& reference;
|
||||
|
||||
static const int POSITION_END;
|
||||
/// End position indicator.
|
||||
|
||||
VarIterator(Var* pVar, bool positionEnd);
|
||||
/// Creates the VarIterator and positions it at the end of
|
||||
/// the recordset if positionEnd is true. Otherwise, it is
|
||||
/// positioned at the beginning.
|
||||
|
||||
VarIterator(const VarIterator& other);
|
||||
/// Creates a copy of other VarIterator.
|
||||
|
||||
~VarIterator();
|
||||
/// Destroys the VarIterator.
|
||||
|
||||
VarIterator& operator = (const VarIterator& other);
|
||||
/// Assigns the other VarIterator.
|
||||
|
||||
bool operator == (const VarIterator& other) const;
|
||||
/// Equality operator.
|
||||
|
||||
bool operator != (const VarIterator& other) const;
|
||||
/// Inequality operator.
|
||||
|
||||
Var& operator * () const;
|
||||
/// Returns value at the current position.
|
||||
|
||||
Var* operator -> () const;
|
||||
/// Returns pointer to the value at current position.
|
||||
|
||||
const VarIterator& operator ++ () const;
|
||||
/// Advances by one position and returns current position.
|
||||
|
||||
VarIterator operator ++ (int) const;
|
||||
/// Advances by one position and returns copy of the iterator with
|
||||
/// previous current position.
|
||||
|
||||
const VarIterator& operator -- () const;
|
||||
/// Goes back by one position and returns copy of the iterator with
|
||||
/// previous current position.
|
||||
|
||||
VarIterator operator -- (int) const;
|
||||
/// Goes back by one position and returns previous current position.
|
||||
|
||||
VarIterator operator + (std::size_t diff) const;
|
||||
/// Returns a copy the VarIterator advanced by diff positions.
|
||||
|
||||
VarIterator operator - (std::size_t diff) const;
|
||||
/// Returns a copy the VarIterator backed by diff positions.
|
||||
/// Throws RangeException if diff is larger than current position.
|
||||
|
||||
void swap(VarIterator& other);
|
||||
/// Swaps the VarIterator with another one.
|
||||
|
||||
private:
|
||||
VarIterator();
|
||||
|
||||
void increment() const;
|
||||
/// Increments the iterator position by one.
|
||||
/// Throws RangeException if position is out of range.
|
||||
|
||||
void decrement() const;
|
||||
/// Decrements the iterator position by one.
|
||||
/// Throws RangeException if position is out of range.
|
||||
|
||||
void setPosition(std::size_t pos) const;
|
||||
/// Sets the iterator position.
|
||||
/// Throws RangeException if position is out of range.
|
||||
|
||||
Var* _pVar;
|
||||
mutable std::size_t _position;
|
||||
|
||||
friend class Var;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// inlines
|
||||
///
|
||||
|
||||
|
||||
inline bool VarIterator::operator == (const VarIterator& other) const
|
||||
{
|
||||
return _pVar == other._pVar && _position == other._position;
|
||||
}
|
||||
|
||||
|
||||
inline bool VarIterator::operator != (const VarIterator& other) const
|
||||
{
|
||||
return _pVar != other._pVar || _position != other._position;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Dynamic
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
using std::swap;
|
||||
template<>
|
||||
inline void swap<Poco::Dynamic::VarIterator>(Poco::Dynamic::VarIterator& s1,
|
||||
Poco::Dynamic::VarIterator& s2)
|
||||
/// Full template specalization of std:::swap for VarIterator
|
||||
{
|
||||
s1.swap(s2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // Foundation_VarIterator_INCLUDED
|
@ -38,24 +38,35 @@
|
||||
#include "Poco/Dynamic/Struct.h"
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Dynamic {
|
||||
|
||||
|
||||
Var::Var()
|
||||
Var::Var() :
|
||||
#ifdef POCO_NO_SOO
|
||||
: _pHolder(0)
|
||||
_pHolder(0),
|
||||
#endif
|
||||
_pBegin(new Iterator(this, true)),
|
||||
_pEnd(new Iterator(this, true))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Var::Var(const char* pVal)
|
||||
#ifdef POCO_NO_SOO
|
||||
: _pHolder(new VarHolderImpl<std::string>(pVal)) { }
|
||||
: _pHolder(new VarHolderImpl<std::string>(pVal)),
|
||||
_pBegin(new Iterator(this, false)),
|
||||
_pEnd(new Iterator(this, true))
|
||||
{
|
||||
}
|
||||
#else
|
||||
: _pBegin(new Iterator(this, false)),
|
||||
_pEnd(new Iterator(this, true))
|
||||
{
|
||||
construct(std::string(pVal));
|
||||
}
|
||||
@ -64,12 +75,14 @@ Var::Var(const char* pVal)
|
||||
|
||||
Var::Var(const Var& other)
|
||||
#ifdef POCO_NO_SOO
|
||||
: _pHolder(0)
|
||||
: _pHolder(other._pHolder ? other._pHolder->clone() : 0),
|
||||
_pBegin(new Iterator(*other._pBegin)),
|
||||
_pEnd(new Iterator(*other._pEnd))
|
||||
{
|
||||
if (other._pHolder)
|
||||
_pHolder = other._pHolder->clone();
|
||||
}
|
||||
#else
|
||||
: _pBegin(new Iterator(*other._pBegin)),
|
||||
_pEnd(new Iterator(*other._pEnd))
|
||||
{
|
||||
if ((this != &other) && !other.isEmpty())
|
||||
construct(other);
|
||||
@ -238,6 +251,7 @@ Var& Var::operator ++ ()
|
||||
return *this = *this + 1;
|
||||
}
|
||||
|
||||
|
||||
const Var Var::operator ++ (int)
|
||||
{
|
||||
if (!isInteger())
|
||||
@ -248,6 +262,7 @@ const Var Var::operator ++ (int)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
Var& Var::operator -- ()
|
||||
{
|
||||
if (!isInteger())
|
||||
@ -256,6 +271,7 @@ Var& Var::operator -- ()
|
||||
return *this = *this - 1;
|
||||
}
|
||||
|
||||
|
||||
const Var Var::operator -- (int)
|
||||
{
|
||||
if (!isInteger())
|
||||
@ -269,7 +285,8 @@ const Var Var::operator -- (int)
|
||||
|
||||
bool Var::operator == (const Var& other) const
|
||||
{
|
||||
if (isEmpty() || other.isEmpty()) return false;
|
||||
if (isEmpty() && !other.isEmpty()) return false;
|
||||
if (isEmpty() && other.isEmpty()) return true;
|
||||
return convert<std::string>() == other.convert<std::string>();
|
||||
}
|
||||
|
||||
@ -352,16 +369,43 @@ void Var::empty()
|
||||
}
|
||||
|
||||
|
||||
Var& Var::operator [] (const std::string& name)
|
||||
Var& Var::getAt(std::size_t n)
|
||||
{
|
||||
return holderImpl<DynamicStruct, InvalidAccessException>("Not an array.")->operator[](name);
|
||||
if (isVector())
|
||||
return holderImpl<std::vector<Var>,
|
||||
InvalidAccessException>("Not a vector.")->operator[](n);
|
||||
else if (isList())
|
||||
return holderImpl<std::list<Var>,
|
||||
InvalidAccessException>("Not a list.")->operator[](n);
|
||||
else if (isDeque())
|
||||
return holderImpl<std::deque<Var>,
|
||||
InvalidAccessException>("Not a deque.")->operator[](n);
|
||||
else if (isStruct())
|
||||
return structIndexOperator(holderImpl<Struct<int>,
|
||||
InvalidAccessException>("Not a struct."), static_cast<int>(n));
|
||||
else if (!isString() && !isEmpty() && (n == 0))
|
||||
return *this;
|
||||
|
||||
throw RangeException("Index out of bounds.");
|
||||
}
|
||||
|
||||
|
||||
const Var& Var::operator [] (const std::string& name) const
|
||||
char& Var::at(std::size_t n)
|
||||
{
|
||||
return const_cast<const Var&>(holderImpl<DynamicStruct,
|
||||
InvalidAccessException>("Not an array.")->operator[](name));
|
||||
if (isString())
|
||||
{
|
||||
return holderImpl<std::string,
|
||||
InvalidAccessException>("Not a string.")->operator[](n);
|
||||
}
|
||||
|
||||
throw InvalidAccessException("Not a string.");
|
||||
}
|
||||
|
||||
|
||||
Var& Var::getAt(const std::string& name)
|
||||
{
|
||||
return holderImpl<DynamicStruct,
|
||||
InvalidAccessException>("Not a struct.")->operator[](name);
|
||||
}
|
||||
|
||||
|
||||
@ -499,7 +543,7 @@ void Var::skipWhiteSpace(const std::string& val, std::string::size_type& pos)
|
||||
std::string Var::toString(const Var& any)
|
||||
{
|
||||
std::string res;
|
||||
appendJSONValue(res, any);
|
||||
Impl::appendJSONValue(res, any);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,9 @@ VarHolder::~VarHolder()
|
||||
}
|
||||
|
||||
|
||||
namespace Impl {
|
||||
|
||||
|
||||
bool isJSONString(const Var& any)
|
||||
{
|
||||
return any.type() == typeid(std::string) ||
|
||||
@ -90,4 +93,7 @@ void appendJSONValue(std::string& val, const Var& any)
|
||||
}
|
||||
|
||||
|
||||
} // namespace Impl
|
||||
|
||||
|
||||
} } // namespace Poco::Dynamic
|
||||
|
189
Foundation/src/VarIterator.cpp
Normal file
189
Foundation/src/VarIterator.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
//
|
||||
// VarIterator.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/VarIterator.cpp#1 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Dynamic
|
||||
// Module: VarIterator
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Dynamic/VarIterator.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/Dynamic/Struct.h"
|
||||
#undef min
|
||||
#undef max
|
||||
#include <limits>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Dynamic {
|
||||
|
||||
|
||||
const int VarIterator::POSITION_END = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
|
||||
VarIterator::VarIterator(Var* pVar, bool positionEnd):
|
||||
_pVar(pVar),
|
||||
_position(positionEnd ? POSITION_END : 0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VarIterator::VarIterator(const VarIterator& other):
|
||||
_pVar(other._pVar),
|
||||
_position(other._position)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VarIterator::~VarIterator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VarIterator& VarIterator::operator = (const VarIterator& other)
|
||||
{
|
||||
VarIterator tmp(other);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void VarIterator::swap(VarIterator& other)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
swap(_pVar, other._pVar);
|
||||
swap(_position, other._position);
|
||||
}
|
||||
|
||||
|
||||
void VarIterator::increment() const
|
||||
{
|
||||
if (POSITION_END == _position)
|
||||
throw RangeException("End of iterator reached.");
|
||||
|
||||
if (_position < _pVar->size() - 1)
|
||||
++_position;
|
||||
else
|
||||
_position = POSITION_END;
|
||||
}
|
||||
|
||||
|
||||
void VarIterator::decrement() const
|
||||
{
|
||||
if (0 == _position)
|
||||
throw RangeException("Beginning of iterator reached.");
|
||||
else if (POSITION_END == _position)
|
||||
_position = _pVar->size() - 1;
|
||||
else
|
||||
--_position;
|
||||
}
|
||||
|
||||
|
||||
void VarIterator::setPosition(std::size_t pos) const
|
||||
{
|
||||
if (_position == pos) return;
|
||||
|
||||
if (pos < _pVar->size())
|
||||
_position = pos;
|
||||
else if (pos == _pVar->size())
|
||||
_position = POSITION_END;
|
||||
else
|
||||
throw RangeException("Invalid position argument.");
|
||||
}
|
||||
|
||||
|
||||
Var& VarIterator::operator * () const
|
||||
{
|
||||
if (POSITION_END == _position)
|
||||
throw InvalidAccessException("End of iterator reached.");
|
||||
|
||||
return _pVar->operator[](_position);
|
||||
}
|
||||
|
||||
|
||||
Var* VarIterator::operator -> () const
|
||||
{
|
||||
if (POSITION_END == _position)
|
||||
throw InvalidAccessException("End of iterator reached.");
|
||||
|
||||
return &_pVar->operator[](_position);
|
||||
}
|
||||
|
||||
|
||||
const VarIterator& VarIterator::operator ++ () const
|
||||
{
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
VarIterator VarIterator::operator ++ (int) const
|
||||
{
|
||||
VarIterator old(*this);
|
||||
increment();
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
const VarIterator& VarIterator::operator -- () const
|
||||
{
|
||||
decrement();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
VarIterator VarIterator::operator -- (int) const
|
||||
{
|
||||
VarIterator old(*this);
|
||||
decrement();
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
VarIterator VarIterator::operator + (std::size_t diff) const
|
||||
{
|
||||
VarIterator ri(*this);
|
||||
ri.setPosition(_position + diff);
|
||||
return ri;
|
||||
}
|
||||
|
||||
|
||||
VarIterator VarIterator::operator - (std::size_t diff) const
|
||||
{
|
||||
if (diff > _position) throw RangeException("Invalid position argument.");
|
||||
VarIterator ri(*this);
|
||||
ri.setPosition(_position - diff);
|
||||
return ri;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Dynamic
|
@ -1841,6 +1841,7 @@ void VarTest::testIsArray()
|
||||
std::vector<Var> s16;
|
||||
DynamicStruct s17;
|
||||
|
||||
Var d0;
|
||||
Var d1(s1);
|
||||
Var d2(s2);
|
||||
Var d3(s3);
|
||||
@ -1859,23 +1860,24 @@ void VarTest::testIsArray()
|
||||
Var d16(s16);
|
||||
Var d17(s17);
|
||||
|
||||
assert (!d0.isArray());
|
||||
assert (!d1.isArray());
|
||||
assert (!d2.isArray());
|
||||
assert (!d3.isArray());
|
||||
assert (!d4.isArray());
|
||||
assert (!d5.isArray());
|
||||
assert (!d6.isArray());
|
||||
assert (!d7.isArray());
|
||||
assert (!d8.isArray());
|
||||
assert (!d9.isArray());
|
||||
assert (!d10.isArray());
|
||||
assert (!d11.isArray());
|
||||
assert (!d12.isArray());
|
||||
assert (!d13.isArray());
|
||||
assert (!d14.isArray());
|
||||
assert (!d15.isArray());
|
||||
assert (d2.isArray());
|
||||
assert (d3.isArray());
|
||||
assert (d4.isArray());
|
||||
assert (d5.isArray());
|
||||
assert (d6.isArray());
|
||||
assert (d7.isArray());
|
||||
assert (d8.isArray());
|
||||
assert (d9.isArray());
|
||||
assert (d10.isArray());
|
||||
assert (d11.isArray());
|
||||
assert (d12.isArray());
|
||||
assert (d13.isArray());
|
||||
assert (d14.isArray());
|
||||
assert (d15.isArray());
|
||||
assert (d16.isArray());
|
||||
assert (!d17.isArray());
|
||||
assert (d17.isArray());
|
||||
}
|
||||
|
||||
|
||||
@ -1920,23 +1922,39 @@ void VarTest::testArrayIdxOperator()
|
||||
Var d17(s17);
|
||||
|
||||
testGetIdxMustThrow(d1, 0);
|
||||
testGetIdxMustThrow(d2, 0);
|
||||
testGetIdxMustThrow(d3, 0);
|
||||
testGetIdxMustThrow(d4, 0);
|
||||
testGetIdxMustThrow(d5, 0);
|
||||
testGetIdxMustThrow(d6, 0);
|
||||
testGetIdxMustThrow(d7, 0);
|
||||
testGetIdxMustThrow(d8, 0);
|
||||
testGetIdxMustThrow(d9, 0);
|
||||
testGetIdxMustThrow(d10, 0);
|
||||
testGetIdxMustThrow(d11, 0);
|
||||
testGetIdxMustThrow(d12, 0);
|
||||
testGetIdxMustThrow(d13, 0);
|
||||
testGetIdxMustThrow(d14, 0);
|
||||
testGetIdxMustThrow(d15, 0);
|
||||
testGetIdxNoThrow(d2, 0);
|
||||
testGetIdxNoThrow(d3, 0);
|
||||
testGetIdxNoThrow(d4, 0);
|
||||
testGetIdxNoThrow(d5, 0);
|
||||
testGetIdxNoThrow(d6, 0);
|
||||
testGetIdxNoThrow(d7, 0);
|
||||
testGetIdxNoThrow(d8, 0);
|
||||
testGetIdxNoThrow(d9, 0);
|
||||
testGetIdxNoThrow(d10, 0);
|
||||
testGetIdxNoThrow(d11, 0);
|
||||
testGetIdxNoThrow(d12, 0);
|
||||
testGetIdxNoThrow(d13, 0);
|
||||
testGetIdxNoThrow(d14, 0);
|
||||
testGetIdxNoThrow(d15, 0);
|
||||
testGetIdx(d16, 0, s1);
|
||||
testGetIdx(d16, 1, s2);
|
||||
testGetIdxMustThrow(d17, 0);
|
||||
|
||||
testGetIdxMustThrow(d1, 1);
|
||||
testGetIdxMustThrow(d2, 1);
|
||||
testGetIdxMustThrow(d3, 1);
|
||||
testGetIdxMustThrow(d4, 1);
|
||||
testGetIdxMustThrow(d5, 1);
|
||||
testGetIdxMustThrow(d6, 1);
|
||||
testGetIdxMustThrow(d7, 1);
|
||||
testGetIdxMustThrow(d8, 1);
|
||||
testGetIdxMustThrow(d9, 1);
|
||||
testGetIdxMustThrow(d10, 1);
|
||||
testGetIdxMustThrow(d11, 1);
|
||||
testGetIdxMustThrow(d12, 1);
|
||||
testGetIdxMustThrow(d13, 1);
|
||||
testGetIdxMustThrow(d14, 1);
|
||||
testGetIdxMustThrow(d15, 1);
|
||||
testGetIdxMustThrow(d17, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -2001,9 +2019,9 @@ void VarTest::testDynamicStructInt()
|
||||
aStruct[1] = "POCO";
|
||||
aStruct[2] = 10;
|
||||
Var a1(aStruct);
|
||||
assert (a1[0] == "Junior");
|
||||
assert (a1[1] == "POCO");
|
||||
assert (a1[2] == 10);
|
||||
assert (a1[0]== "Junior");
|
||||
assert (a1[1]== "POCO");
|
||||
assert (a1[2]== 10);
|
||||
a1[0] = "Senior";
|
||||
assert (a1[0] == "Senior");
|
||||
|
||||
@ -2372,17 +2390,27 @@ void VarTest::testDate()
|
||||
assert (tsNow == tsRes);
|
||||
}
|
||||
|
||||
|
||||
void VarTest::testGetIdxNoThrow(Var& a1, std::vector<Var>::size_type n)
|
||||
{
|
||||
Var val1 = a1[n];
|
||||
}
|
||||
|
||||
|
||||
void VarTest::testGetIdxMustThrow(Var& a1, std::vector<Var>::size_type n)
|
||||
{
|
||||
try
|
||||
{
|
||||
Var& val1 = a1[n];
|
||||
Var val1 = a1[n];
|
||||
fail("bad cast - must throw");
|
||||
val1 = 0; // silence the compiler
|
||||
}
|
||||
catch (Poco::InvalidAccessException&)
|
||||
{
|
||||
}
|
||||
catch (Poco::RangeException&)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@ -2394,6 +2422,9 @@ void VarTest::testGetIdxMustThrow(Var& a1, std::vector<Var>::size_type n)
|
||||
catch (Poco::InvalidAccessException&)
|
||||
{
|
||||
}
|
||||
catch (Poco::RangeException&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2407,7 +2438,7 @@ void VarTest::testEmpty()
|
||||
assert (!da.isNumeric());
|
||||
assert (!da.isSigned());
|
||||
assert (!da.isString());
|
||||
assert (!(da == da));
|
||||
assert (da == da);
|
||||
assert (!(da != da));
|
||||
|
||||
da = "123";
|
||||
@ -2424,14 +2455,13 @@ void VarTest::testEmpty()
|
||||
assert (!da.isNumeric());
|
||||
assert (!da.isSigned());
|
||||
assert (!da.isString());
|
||||
assert (!(da == da));
|
||||
assert (da == da);
|
||||
assert (!(da != da));
|
||||
|
||||
assert (da != "");
|
||||
assert ("" != da);
|
||||
assert (!(da == ""));
|
||||
assert (!("" == da));
|
||||
|
||||
|
||||
testEmptyComparisons<unsigned char>();
|
||||
testEmptyComparisons<char>();
|
||||
@ -2464,6 +2494,71 @@ void VarTest::testEmpty()
|
||||
}
|
||||
|
||||
|
||||
void VarTest::testIterator()
|
||||
{
|
||||
Var da;
|
||||
assert (da.isEmpty());
|
||||
assert (da.begin() == da.end());
|
||||
|
||||
da = 1;
|
||||
assert (!da.isEmpty());
|
||||
assert (da == 1);
|
||||
assert (da[0] == 1);
|
||||
try
|
||||
{
|
||||
da[1] = 2;
|
||||
}
|
||||
catch (RangeException&) {}
|
||||
assert (da.begin() != da.end());
|
||||
|
||||
Var::Iterator it = da.begin();
|
||||
Var::Iterator end = da.end();
|
||||
assert (it != end);
|
||||
assert (++it == end);
|
||||
assert (--it == da.begin());
|
||||
it++;
|
||||
assert (it == end);
|
||||
try
|
||||
{
|
||||
++it;
|
||||
fail ("must fail");
|
||||
}
|
||||
catch (RangeException&) {}
|
||||
assert (it == end);
|
||||
|
||||
da = "abc";
|
||||
assert (da.size() == 3);
|
||||
assert (!da.isArray());
|
||||
assert (da.isString());
|
||||
//assert (da[0] == 'a');
|
||||
assert (da.at(0) == 'a');
|
||||
//assert (da[1] = 'b');
|
||||
assert (da.at(1) == 'b');
|
||||
//assert (da[2] = 'c');
|
||||
assert (da.at(2) == 'c');
|
||||
|
||||
da.at(0) = 'b';
|
||||
assert (da.at(0) == 'b');
|
||||
// TODO: allow treatment of strings like arrays
|
||||
//da[1] = 'c';
|
||||
da.at(1) = 'c';
|
||||
assert (da.at(1) == 'c');
|
||||
//da[2] = 'a';
|
||||
da.at(2) = 'a';
|
||||
assert (da.at(2) == 'a');
|
||||
|
||||
it = da.begin();
|
||||
end = da.end();
|
||||
assert (it != end);
|
||||
assert (++it != end);
|
||||
assert (--it == da.begin());
|
||||
|
||||
testContainerIterator<std::vector<Var> >();
|
||||
testContainerIterator<std::list<Var> >();
|
||||
testContainerIterator<std::deque<Var> >();
|
||||
}
|
||||
|
||||
|
||||
void VarTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -2518,6 +2613,7 @@ CppUnit::Test* VarTest::suite()
|
||||
CppUnit_addTest(pSuite, VarTest, testJSONDeserializeComplex);
|
||||
CppUnit_addTest(pSuite, VarTest, testDate);
|
||||
CppUnit_addTest(pSuite, VarTest, testEmpty);
|
||||
CppUnit_addTest(pSuite, VarTest, testIterator);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/Dynamic/VarIterator.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "CppUnit/TestCase.h"
|
||||
|
||||
@ -87,6 +88,7 @@ public:
|
||||
void testJSONDeserializeComplex();
|
||||
void testDate();
|
||||
void testEmpty();
|
||||
void testIterator();
|
||||
|
||||
|
||||
void setUp();
|
||||
@ -95,15 +97,16 @@ public:
|
||||
|
||||
private:
|
||||
void testGetIdxMustThrow(Poco::Dynamic::Var& a1, std::vector<Poco::Dynamic::Var>::size_type n);
|
||||
void testGetIdxNoThrow(Poco::Dynamic::Var& a1, std::vector<Poco::Dynamic::Var>::size_type n);
|
||||
template<typename T>
|
||||
void testGetIdx(Poco::Dynamic::Var& a1, std::vector<Poco::Dynamic::Var>::size_type n, const T& expectedResult)
|
||||
void testGetIdx(const Poco::Dynamic::Var& a1, std::vector<Poco::Dynamic::Var>::size_type n, const T& expectedResult)
|
||||
{
|
||||
Poco::Dynamic::Var& val1 = a1[n];
|
||||
Poco::Dynamic::Var val1 = a1[n];
|
||||
assert (val1 == expectedResult);
|
||||
|
||||
const Poco::Dynamic::Var& c1 = a1;
|
||||
const Poco::Dynamic::Var c1 = a1;
|
||||
assert (a1 == c1); // silence the compiler
|
||||
const Poco::Dynamic::Var& cval1 = a1[n];
|
||||
const Poco::Dynamic::Var cval1 = a1[n];
|
||||
assert (cval1 == expectedResult);
|
||||
}
|
||||
|
||||
@ -181,6 +184,37 @@ private:
|
||||
assert (!(da >= val));
|
||||
assert (!(val >= da));
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
void testContainerIterator()
|
||||
{
|
||||
C cont;
|
||||
cont.push_back(1);
|
||||
cont.push_back("2");
|
||||
cont.push_back(3.5);
|
||||
Var arr(cont);
|
||||
assert (arr.size() == 3);
|
||||
Var::Iterator it = arr.begin();
|
||||
Var::Iterator end = arr.end();
|
||||
int counter = 0;
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
switch (++counter)
|
||||
{
|
||||
case 1:
|
||||
assert (*it == 1);
|
||||
break;
|
||||
case 2:
|
||||
assert (*it == 2);
|
||||
break;
|
||||
case 3:
|
||||
assert (*it == 3.5);
|
||||
break;
|
||||
default:
|
||||
fail ("must fail - wrong size");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,9 +12,6 @@
|
||||
<ClCompile Include="src\Array.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ParseHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Handler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -42,6 +39,9 @@
|
||||
<ClCompile Include="src\TemplateCache.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ParseHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\Poco\JSON\Array.h">
|
||||
@ -62,9 +62,6 @@
|
||||
<ClInclude Include="include\Poco\JSON\Parser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\JSON\ParseHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\JSON\PrintHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -80,5 +77,8 @@
|
||||
<ClInclude Include="include\Poco\JSON\TemplateCache.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\JSON\ParseHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -11,7 +11,7 @@ include $(POCO_BASE)/build/rules/global
|
||||
INCLUDE += -I $(POCO_BASE)/JSON/include/Poco/JSON
|
||||
|
||||
objects = Array Object Parser Handler Stringifier \
|
||||
ParseHandler PrintHandler Query JSONException \
|
||||
VarHandler PrintHandler Query JSONException \
|
||||
Template TemplateCache
|
||||
|
||||
target = PocoJSON
|
||||
|
@ -55,9 +55,34 @@ class Object;
|
||||
|
||||
|
||||
class JSON_API Array
|
||||
/// Represents a JSON array. JSON array provides a representation
|
||||
/// based on shared pointers and optimized for performance. It is possible to
|
||||
/// convert object to Poco::Dynamic::Array. Conversion requires copying and therefore
|
||||
/// has performance penalty; the benefit is in improved syntax, eg:
|
||||
///
|
||||
/// // use pointers to avoid copying
|
||||
/// using namespace Poco::JSON;
|
||||
/// std::string json = "[ {\"test\" : 0}, { \"test1\" : [1, 2, 3], \"test2\" : 4 } ]";
|
||||
/// Parser parser;
|
||||
/// Var result = parser.parse(json);
|
||||
/// Array::Ptr arr = result.extract<Array::Ptr>();
|
||||
/// Object::Ptr object = arr->getObject(0); // object == {\"test\" : 0}
|
||||
/// int i = object->getValue<int>("test"); // i == 0;
|
||||
/// Object::Ptr subObject = *arr->getObject(1); // subObject == {\"test\" : 0}
|
||||
/// Array subArr::Ptr = subObject->getArray("test1"); // subArr == [1, 2, 3]
|
||||
/// i = result = subArr->get(0); // i == 1;
|
||||
///
|
||||
/// // copy/convert to Poco::Dynamic::Array
|
||||
/// Poco::Dynamic::Array da = *arr;
|
||||
/// i = da[0]["test"]; // i == 0
|
||||
/// i = da[1]["test1"][1]; // i == 2
|
||||
/// i = da[1]["test2"]; // i == 4
|
||||
///
|
||||
{
|
||||
public:
|
||||
typedef std::vector<Dynamic::Var> ValueVec;
|
||||
typedef std::vector<Dynamic::Var> ValueVec;
|
||||
typedef std::vector<Dynamic::Var>::iterator Iterator;
|
||||
typedef std::vector<Dynamic::Var>::const_iterator ConstIterator;
|
||||
typedef SharedPtr<Array> Ptr;
|
||||
|
||||
Array();
|
||||
@ -105,6 +130,12 @@ public:
|
||||
bool isArray(unsigned int index) const;
|
||||
/// Returns true when the element is an array
|
||||
|
||||
bool isArray(const Dynamic::Var& value) const;
|
||||
/// Returns true when the element is an array
|
||||
|
||||
bool isArray(ConstIterator& value) const;
|
||||
/// Returns true when the element is an array
|
||||
|
||||
bool isNull(unsigned int index) const;
|
||||
/// Returns true when the element is null or
|
||||
/// when the element doesn't exist.
|
||||
@ -112,6 +143,12 @@ public:
|
||||
bool isObject(unsigned int index) const;
|
||||
/// Returns true when the element is an object
|
||||
|
||||
bool isObject(const Dynamic::Var& value) const;
|
||||
/// Returns true when the element is an object
|
||||
|
||||
bool isObject(ConstIterator& value) const;
|
||||
/// Returns true when the element is an object
|
||||
|
||||
template<typename T>
|
||||
T optElement(unsigned int index, const T& def) const
|
||||
/// Returns the element at the given index. When
|
||||
@ -144,8 +181,16 @@ public:
|
||||
void remove(unsigned int index);
|
||||
/// Removes the element on the given index.
|
||||
|
||||
operator const Poco::Dynamic::Array& () const;
|
||||
|
||||
static Poco::Dynamic::Array makeArray(const JSON::Array::Ptr& arr);
|
||||
/// Utility function for creation of array.
|
||||
|
||||
private:
|
||||
ValueVec _values;
|
||||
typedef SharedPtr<Poco::Dynamic::Array> ArrayPtr;
|
||||
|
||||
ValueVec _values;
|
||||
mutable ArrayPtr _pArray;
|
||||
};
|
||||
|
||||
|
||||
@ -171,10 +216,22 @@ inline std::size_t Array::size() const
|
||||
inline bool Array::isArray(unsigned int index) const
|
||||
{
|
||||
Dynamic::Var value = get(index);
|
||||
return isArray(value);
|
||||
}
|
||||
|
||||
|
||||
inline bool Array::isArray(const Dynamic::Var& value) const
|
||||
{
|
||||
return value.type() == typeid(Array::Ptr);
|
||||
}
|
||||
|
||||
|
||||
inline bool Array::isArray(ConstIterator& it) const
|
||||
{
|
||||
return it!= end() && isArray(*it);
|
||||
}
|
||||
|
||||
|
||||
inline void Array::add(const Dynamic::Var& value)
|
||||
{
|
||||
_values.push_back(value);
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "Poco/JSON/JSON.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/Dynamic/Struct.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -60,6 +61,9 @@ public:
|
||||
virtual ~Handler();
|
||||
/// Destructor
|
||||
|
||||
virtual void reset() = 0;
|
||||
/// Resets the handler state.
|
||||
|
||||
virtual void startObject() = 0;
|
||||
/// The parser has read a {, meaning a new object will be read
|
||||
|
||||
@ -103,10 +107,11 @@ public:
|
||||
virtual void value(bool b) = 0;
|
||||
/// A boolean value is read
|
||||
|
||||
virtual void comma();
|
||||
/// A comma is read
|
||||
virtual Poco::Dynamic::Var asVar() const;
|
||||
/// Returns the result of the parser (an object, array or string),
|
||||
/// empty Var if there is no result.
|
||||
|
||||
virtual Dynamic::Var result() const;
|
||||
virtual Poco::DynamicStruct asStruct() const;
|
||||
/// Returns the result of the parser (an object, array or string),
|
||||
/// empty Var if there is no result.
|
||||
};
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/Dynamic/Struct.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
@ -57,10 +58,33 @@ namespace JSON {
|
||||
|
||||
|
||||
class JSON_API Object
|
||||
/// Represents a JSON object.
|
||||
/// Represents a JSON object. JSON object provides a representation
|
||||
/// based on shared pointers and optimized for performance. It is possible to
|
||||
/// convert object to DynamicStruct. Conversion requires copying and therefore
|
||||
/// has performance penalty; the benefit is in improved syntax, eg:
|
||||
///
|
||||
/// std::string json = "{ \"test\" : { \"property\" : \"value\" } }";
|
||||
/// Parser parser;
|
||||
/// Var result = parser.parse(json);
|
||||
///
|
||||
/// // use pointers to avoid copying
|
||||
/// Object::Ptr object = result.extract<Object::Ptr>();
|
||||
/// Var test = object->get("test"); // holds { "property" : "value" }
|
||||
/// Object::Ptr subObject = test.extract<Object::Ptr>();
|
||||
/// test = subObject->get("property");
|
||||
/// std::string val = test.toString(); // val holds "value"
|
||||
///
|
||||
/// // copy/convert to Poco::DynamicStruct
|
||||
/// Poco::DynamicStruct ds = *object;
|
||||
/// val = ds["test"]["property"]; // val holds "value"
|
||||
///
|
||||
{
|
||||
public:
|
||||
typedef SharedPtr<Object> Ptr;
|
||||
typedef SharedPtr<Object> Ptr;
|
||||
typedef std::map<std::string, Dynamic::Var> ValueMap;
|
||||
typedef ValueMap::value_type ValueType;
|
||||
typedef ValueMap::iterator Iterator;
|
||||
typedef ValueMap::const_iterator ConstIterator;
|
||||
|
||||
Object(bool preserveInsertionOrder = false);
|
||||
/// Default constructor. If preserveInsertionOrder, object
|
||||
@ -68,10 +92,31 @@ public:
|
||||
/// will be sorted by keys.
|
||||
|
||||
Object(const Object& copy);
|
||||
/// Copy constructor
|
||||
/// Copy constructor. Struct is not copied to keep the operation as
|
||||
/// efficient as possible (when needed, it will be generated upon request).
|
||||
|
||||
virtual ~Object();
|
||||
/// Destructor
|
||||
/// Destroys Object.
|
||||
|
||||
Iterator begin()
|
||||
{
|
||||
return _values.begin();
|
||||
}
|
||||
|
||||
ConstIterator begin() const
|
||||
{
|
||||
return _values.begin();
|
||||
}
|
||||
|
||||
Iterator end()
|
||||
{
|
||||
return _values.end();
|
||||
}
|
||||
|
||||
ConstIterator end() const
|
||||
{
|
||||
return _values.end();
|
||||
}
|
||||
|
||||
Dynamic::Var get(const std::string& key) const;
|
||||
/// Retrieves a property. An empty value is
|
||||
@ -108,12 +153,18 @@ public:
|
||||
bool isArray(const std::string& key) const;
|
||||
/// Returns true when the given property contains an array
|
||||
|
||||
bool isArray(ConstIterator& it) const;
|
||||
/// Returns true when the given property contains an array
|
||||
|
||||
bool isNull(const std::string& key) const;
|
||||
/// Returns true when the given property contains a null value
|
||||
|
||||
bool isObject(const std::string& key) const;
|
||||
/// Returns true when the given property contains an object
|
||||
|
||||
bool isObject(ConstIterator& it) const;
|
||||
/// Returns true when the given property contains an object
|
||||
|
||||
template<typename T>
|
||||
T optValue(const std::string& key, const T& def) const
|
||||
/// Returns the value of a property when the property exists
|
||||
@ -149,8 +200,13 @@ public:
|
||||
void remove(const std::string& key);
|
||||
/// Removes the property with the given key
|
||||
|
||||
private:
|
||||
static Poco::DynamicStruct makeStruct(const Object::Ptr& obj);
|
||||
/// Utility function for creation of struct.
|
||||
|
||||
operator const Poco::DynamicStruct& () const;
|
||||
/// Cast operator to Poco::DynamiStruct.
|
||||
|
||||
private:
|
||||
template <typename C>
|
||||
void doStringify(const C& container, std::ostream& out, unsigned int indent, int step) const
|
||||
{
|
||||
@ -182,17 +238,18 @@ private:
|
||||
out << '}';
|
||||
}
|
||||
|
||||
typedef std::map<std::string, Dynamic::Var> ValueMap;
|
||||
typedef std::deque<Dynamic::Var*> KeyPtrList;
|
||||
typedef std::deque<Dynamic::Var*> KeyPtrList;
|
||||
typedef Poco::DynamicStruct::Ptr StructPtr;
|
||||
|
||||
const std::string& getKey(ValueMap::const_iterator& it) const;
|
||||
const Dynamic::Var& getValue(ValueMap::const_iterator& it) const;
|
||||
const std::string& getKey(KeyPtrList::const_iterator& it) const;
|
||||
const Dynamic::Var& getValue(KeyPtrList::const_iterator& it) const;
|
||||
|
||||
ValueMap _values;
|
||||
KeyPtrList _keys;
|
||||
bool _preserveInsOrder;
|
||||
ValueMap _values;
|
||||
KeyPtrList _keys;
|
||||
bool _preserveInsOrder;
|
||||
mutable StructPtr _pStruct;
|
||||
};
|
||||
|
||||
|
||||
@ -206,6 +263,12 @@ inline bool Object::has(const std::string& key) const
|
||||
inline bool Object::isArray(const std::string& key) const
|
||||
{
|
||||
ValueMap::const_iterator it = _values.find(key);
|
||||
return isArray(it);
|
||||
}
|
||||
|
||||
|
||||
inline bool Object::isArray(ConstIterator& it) const
|
||||
{
|
||||
return it != _values.end() && it->second.type() == typeid(Array::Ptr);
|
||||
}
|
||||
|
||||
@ -220,6 +283,12 @@ inline bool Object::isNull(const std::string& key) const
|
||||
inline bool Object::isObject(const std::string& key) const
|
||||
{
|
||||
ValueMap::const_iterator it = _values.find(key);
|
||||
return isObject(it);
|
||||
}
|
||||
|
||||
|
||||
inline bool Object::isObject(ConstIterator& it) const
|
||||
{
|
||||
return it != _values.end() && it->second.type() == typeid(Object::Ptr);
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,9 @@ public:
|
||||
virtual ~ParseHandler();
|
||||
/// Destroys the ParseHandler.
|
||||
|
||||
virtual void reset();
|
||||
/// Resets the handler state.
|
||||
|
||||
void startObject();
|
||||
/// Handles a '{'; a new object is started.
|
||||
|
||||
@ -75,7 +78,7 @@ public:
|
||||
void key(const std::string& k);
|
||||
/// A key is read
|
||||
|
||||
Dynamic::Var result() const;
|
||||
Dynamic::Var asVar() const;
|
||||
/// Returns the result of the parser (an object or an array).
|
||||
|
||||
virtual void value(int v);
|
||||
@ -117,7 +120,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
inline Dynamic::Var ParseHandler::result() const
|
||||
inline Dynamic::Var ParseHandler::asVar() const
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
@ -174,6 +177,10 @@ inline void ParseHandler::null()
|
||||
}
|
||||
|
||||
|
||||
typedef ParseHandler ParseHandler;
|
||||
//@ deprecated
|
||||
|
||||
|
||||
}} // namespace Poco::JSON
|
||||
|
||||
|
||||
|
@ -35,6 +35,29 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
/*
|
||||
Copyright (c) 2005 JSON.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
The Software shall be used for Good, not Evil.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef JSON_JSONParser_INCLUDED
|
||||
#define JSON_JSONParser_INCLUDED
|
||||
@ -46,8 +69,6 @@
|
||||
#include "Poco/JSON/ParseHandler.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/StreamTokenizer.h"
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -58,7 +79,22 @@ class Source;
|
||||
|
||||
|
||||
class JSON_API Parser
|
||||
/// A class for passing JSON strings or streams.
|
||||
/// A RFC 4627 compatible class for parsing JSON strings or streams.
|
||||
///
|
||||
/// See http://www.ietf.org/rfc/rfc4627.txt for specification.
|
||||
///
|
||||
/// Usage example:
|
||||
///
|
||||
/// std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ] }";
|
||||
/// Parser parser;
|
||||
/// Var result = parser.parse(json);
|
||||
/// // ... use result
|
||||
/// parser.reset();
|
||||
/// std::ostringstream ostr;
|
||||
/// PrintHandler::Ptr pHandler = new PrintHandler(ostr);
|
||||
/// parser.setHandler(pHandler);
|
||||
/// parser.parse(json); // ostr.str() == json
|
||||
///
|
||||
{
|
||||
public:
|
||||
|
||||
@ -170,26 +206,20 @@ public:
|
||||
enum JSONType
|
||||
{
|
||||
JSON_T_NONE = 0,
|
||||
JSON_T_ARRAY_BEGIN,
|
||||
JSON_T_ARRAY_END,
|
||||
JSON_T_OBJECT_BEGIN,
|
||||
JSON_T_OBJECT_END,
|
||||
JSON_T_INTEGER,
|
||||
JSON_T_FLOAT,
|
||||
JSON_T_NULL,
|
||||
JSON_T_TRUE,
|
||||
JSON_T_FALSE,
|
||||
JSON_T_STRING,
|
||||
JSON_T_KEY,
|
||||
JSON_T_VALUE_SEPARATOR,
|
||||
JSON_T_MAX
|
||||
};
|
||||
|
||||
static const std::size_t PARSE_BUFFER_SIZE = 3500;
|
||||
static const std::size_t PARSER_STACK_SIZE = 128;
|
||||
static const int UNLIMITED_DEPTH = -1;
|
||||
static const std::size_t JSON_PARSE_BUFFER_SIZE = 4096;
|
||||
static const std::size_t JSON_PARSER_STACK_SIZE = 128;
|
||||
static const int JSON_UNLIMITED_DEPTH = -1;
|
||||
|
||||
Parser(const Handler::Ptr& pHandler = new ParseHandler, std::size_t bufSize = PARSE_BUFFER_SIZE);
|
||||
Parser(const Handler::Ptr& pHandler = new ParseHandler, std::size_t bufSize = JSON_PARSE_BUFFER_SIZE);
|
||||
/// Constructor.
|
||||
|
||||
virtual ~Parser();
|
||||
@ -230,10 +260,16 @@ public:
|
||||
const Handler::Ptr& getHandler();
|
||||
/// Returns the handler.
|
||||
|
||||
Dynamic::Var result() const;
|
||||
Dynamic::Var asVar() const;
|
||||
/// Returns the result of parsing;
|
||||
|
||||
Dynamic::Var result() const;
|
||||
/// Returns the result of parsing as Dynamic::Var;
|
||||
|
||||
private:
|
||||
Parser(const Parser&);
|
||||
Parser& operator = (const Parser&);
|
||||
|
||||
typedef Poco::Buffer<char> BufType;
|
||||
|
||||
bool push(int mode);
|
||||
@ -265,7 +301,7 @@ private:
|
||||
|
||||
bool parseChar(int nextChar, Source& feeder);
|
||||
/// Called for each character (or partial character) in JSON string.
|
||||
/// It accepts UTF-8, UTF-16, or UTF-32. If it the character is accepted,
|
||||
/// It accepts UTF-8, UTF-16, or UTF-32. If the character is accepted,
|
||||
/// it returns true, otherwise false.
|
||||
|
||||
bool done();
|
||||
@ -298,9 +334,9 @@ private:
|
||||
};
|
||||
|
||||
|
||||
inline void Parser::setAllowComments(bool sw)
|
||||
inline void Parser::setAllowComments(bool comments)
|
||||
{
|
||||
_allowComments = sw;
|
||||
_allowComments = comments;
|
||||
}
|
||||
|
||||
|
||||
@ -310,9 +346,9 @@ inline bool Parser::getAllowComments() const
|
||||
}
|
||||
|
||||
|
||||
inline void Parser::setAllowNullByte(bool sw)
|
||||
inline void Parser::setAllowNullByte(bool nullByte)
|
||||
{
|
||||
_allowNullByte = sw;
|
||||
_allowNullByte = nullByte;
|
||||
}
|
||||
|
||||
|
||||
@ -348,7 +384,13 @@ inline const Handler::Ptr& Parser::getHandler()
|
||||
|
||||
inline Dynamic::Var Parser::result() const
|
||||
{
|
||||
return _pHandler->result();
|
||||
return _pHandler->asVar();
|
||||
}
|
||||
|
||||
|
||||
inline Dynamic::Var Parser::asVar() const
|
||||
{
|
||||
return _pHandler->asVar();
|
||||
}
|
||||
|
||||
|
||||
|
@ -68,6 +68,9 @@ public:
|
||||
~PrintHandler();
|
||||
/// Destroys the PrintHandler.
|
||||
|
||||
void reset();
|
||||
/// Resets the handler state.
|
||||
|
||||
void startObject();
|
||||
/// The parser has read a '{'; a new object is started.
|
||||
/// If indent is greater than zero, a newline will be apended.
|
||||
|
@ -116,10 +116,22 @@ bool Array::isNull(unsigned int index) const
|
||||
bool Array::isObject(unsigned int index) const
|
||||
{
|
||||
Var value = get(index);
|
||||
return isObject(value);
|
||||
}
|
||||
|
||||
|
||||
bool Array::isObject(const Dynamic::Var& value) const
|
||||
{
|
||||
return value.type() == typeid(Object::Ptr);
|
||||
}
|
||||
|
||||
|
||||
bool Array::isObject(ConstIterator& it) const
|
||||
{
|
||||
return it!= end() && isObject(*it);
|
||||
}
|
||||
|
||||
|
||||
void Array::stringify(std::ostream& out, unsigned int indent, int step) const
|
||||
{
|
||||
if (step == -1) step = indent;
|
||||
@ -152,4 +164,62 @@ void Array::stringify(std::ostream& out, unsigned int indent, int step) const
|
||||
}
|
||||
|
||||
|
||||
Array::operator const Poco::Dynamic::Array& () const
|
||||
{
|
||||
if (!_pArray)
|
||||
{
|
||||
ValueVec::const_iterator it = _values.begin();
|
||||
ValueVec::const_iterator end = _values.end();
|
||||
_pArray = new Poco::Dynamic::Array;
|
||||
int index = 0;
|
||||
for (; it != end; ++it, ++index)
|
||||
{
|
||||
if (isObject(it))
|
||||
{
|
||||
_pArray->insert(_pArray->end(), Poco::JSON::Object::makeStruct(getObject(index)));
|
||||
}
|
||||
else if (isArray(it))
|
||||
{
|
||||
_pArray->insert(_pArray->end(), makeArray(getArray(index)));
|
||||
}
|
||||
else
|
||||
{
|
||||
_pArray->insert(_pArray->end(), *it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *_pArray;
|
||||
}
|
||||
|
||||
|
||||
Poco::Dynamic::Array Array::makeArray(const JSON::Array::Ptr& arr)
|
||||
{
|
||||
Poco::Dynamic::Array vec;
|
||||
|
||||
JSON::Array::ConstIterator it = arr->begin();
|
||||
JSON::Array::ConstIterator end = arr->end();
|
||||
int index = 0;
|
||||
for (; it != end; ++it, ++index)
|
||||
{
|
||||
if (arr->isObject(it))
|
||||
{
|
||||
Object::Ptr pObj = arr->getObject(index);
|
||||
DynamicStruct str = Poco::JSON::Object::makeStruct(pObj);
|
||||
vec.insert(vec.end(), str);
|
||||
}
|
||||
else if (arr->isArray(it))
|
||||
{
|
||||
Array::Ptr pArr = arr->getArray(index);
|
||||
std::vector<Poco::Dynamic::Var> v = makeArray(pArr);
|
||||
vec.insert(vec.end(), v);
|
||||
}
|
||||
else
|
||||
vec.insert(vec.end(), *it);
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::JSON
|
||||
|
@ -52,15 +52,16 @@ Handler::~Handler()
|
||||
}
|
||||
|
||||
|
||||
void Handler::comma()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Dynamic::Var Handler::result() const
|
||||
Dynamic::Var Handler::asVar() const
|
||||
{
|
||||
return Dynamic::Var();
|
||||
}
|
||||
|
||||
|
||||
Poco::DynamicStruct Handler::asStruct() const
|
||||
{
|
||||
return Poco::DynamicStruct();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::JSON
|
||||
|
@ -53,7 +53,8 @@ Object::Object(bool preserveInsertionOrder): _preserveInsOrder(preserveInsertion
|
||||
|
||||
Object::Object(const Object& copy) : _values(copy._values),
|
||||
_keys(copy._keys),
|
||||
_preserveInsOrder(copy._preserveInsOrder)
|
||||
_preserveInsOrder(copy._preserveInsOrder),
|
||||
_pStruct(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -65,40 +66,37 @@ Object::~Object()
|
||||
|
||||
Var Object::get(const std::string& key) const
|
||||
{
|
||||
Var value;
|
||||
|
||||
ValueMap::const_iterator it = _values.find(key);
|
||||
if ( it != _values.end() )
|
||||
if (it != _values.end())
|
||||
{
|
||||
value = it->second;
|
||||
return it->second;
|
||||
}
|
||||
return value;
|
||||
|
||||
return Var();
|
||||
}
|
||||
|
||||
|
||||
Array::Ptr Object::getArray(const std::string& key) const
|
||||
{
|
||||
Array::Ptr result;
|
||||
|
||||
Var value = get(key);
|
||||
if ( value.type() == typeid(Array::Ptr) )
|
||||
ValueMap::const_iterator it = _values.find(key);
|
||||
if ((it != _values.end()) && (it->second.type() == typeid(Array::Ptr)))
|
||||
{
|
||||
result = value.extract<Array::Ptr>();
|
||||
return it->second.extract<Array::Ptr>();
|
||||
}
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Object::Ptr Object::getObject(const std::string& key) const
|
||||
{
|
||||
Object::Ptr result;
|
||||
|
||||
Var value = get(key);
|
||||
if ( value.type() == typeid(Object::Ptr) )
|
||||
ValueMap::const_iterator it = _values.find(key);
|
||||
if ((it != _values.end()) && (it->second.type() == typeid(Object::Ptr)))
|
||||
{
|
||||
result = value.extract<Object::Ptr>();
|
||||
return it->second.extract<Object::Ptr>();
|
||||
}
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -152,4 +150,60 @@ void Object::set(const std::string& key, const Dynamic::Var& value)
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Object::operator const Poco::DynamicStruct& () const
|
||||
{
|
||||
if (!_pStruct)
|
||||
{
|
||||
ValueMap::const_iterator it = _values.begin();
|
||||
ValueMap::const_iterator end = _values.end();
|
||||
_pStruct = new Poco::DynamicStruct;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::JSON
|
||||
|
@ -56,6 +56,14 @@ ParseHandler::~ParseHandler()
|
||||
}
|
||||
|
||||
|
||||
void ParseHandler::reset()
|
||||
{
|
||||
while (!_stack.empty()) _stack.pop();
|
||||
_key = "";
|
||||
_result.empty();
|
||||
}
|
||||
|
||||
|
||||
void ParseHandler::startObject()
|
||||
{
|
||||
Object::Ptr newObj = new Object(_preserveObjectOrder);
|
||||
|
@ -39,11 +39,11 @@
|
||||
#include "Poco/Ascii.h"
|
||||
#include "Poco/Token.h"
|
||||
#include "Poco/UTF8Encoding.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#include <limits>
|
||||
#include <clocale>
|
||||
#include <istream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -206,9 +206,9 @@ Parser::Parser(const Handler::Ptr& pHandler, std::size_t bufSize) :
|
||||
_escaped(0),
|
||||
_comment(0),
|
||||
_utf16HighSurrogate(0),
|
||||
_depth(UNLIMITED_DEPTH),
|
||||
_depth(JSON_UNLIMITED_DEPTH),
|
||||
_top(-1),
|
||||
_stack(PARSER_STACK_SIZE),
|
||||
_stack(JSON_PARSER_STACK_SIZE),
|
||||
_parseBuffer(bufSize),
|
||||
_parseBufferCount(0),
|
||||
_decimalPoint('.'),
|
||||
@ -230,7 +230,6 @@ void Parser::reset()
|
||||
_beforeCommentState = 0;
|
||||
_type = JSON_T_NONE;
|
||||
_escaped = 0;
|
||||
_comment = 0;
|
||||
_utf16HighSurrogate = 0;
|
||||
_top = -1;
|
||||
_parseBufferCount = 0;
|
||||
@ -239,6 +238,7 @@ void Parser::reset()
|
||||
_parseBuffer.clear();
|
||||
push(MODE_DONE);
|
||||
clearBuffer();
|
||||
if (_pHandler) _pHandler->reset();
|
||||
}
|
||||
|
||||
|
||||
@ -255,7 +255,7 @@ Dynamic::Var Parser::parse(const std::string& json)
|
||||
if (!done())
|
||||
throw JSONException("JSON syntax error");
|
||||
|
||||
return result();
|
||||
return asVar();
|
||||
}
|
||||
|
||||
|
||||
@ -272,7 +272,7 @@ Dynamic::Var Parser::parse(std::istream& in)
|
||||
if (!done())
|
||||
throw JSONException("JSON syntax error");
|
||||
|
||||
return result();
|
||||
return asVar();
|
||||
}
|
||||
|
||||
|
||||
|
@ -66,6 +66,15 @@ PrintHandler::~PrintHandler()
|
||||
}
|
||||
|
||||
|
||||
void PrintHandler::reset()
|
||||
{
|
||||
_out.flush();
|
||||
_tab = "";
|
||||
_array = false;
|
||||
_value = false;
|
||||
}
|
||||
|
||||
|
||||
const char* PrintHandler::endLine() const
|
||||
{
|
||||
if (!printFlat()) return "\n";
|
||||
@ -217,4 +226,6 @@ void PrintHandler::arrayValue()
|
||||
_out << _tab;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::JSON
|
||||
|
@ -52,10 +52,13 @@
|
||||
#include "Poco/Latin1Encoding.h"
|
||||
#include "Poco/TextConverter.h"
|
||||
|
||||
#include "Poco/Dynamic/Struct.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
using namespace Poco::JSON;
|
||||
using namespace Poco::Dynamic;
|
||||
using Poco::DynamicStruct;
|
||||
|
||||
|
||||
JSONTest::JSONTest(const std::string& name): CppUnit::TestCase("JSON")
|
||||
@ -101,6 +104,12 @@ void JSONTest::testNullProperty()
|
||||
assert(object->isNull("test"));
|
||||
Var test = object->get("test");
|
||||
assert(test.isEmpty());
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (ds["test"].isEmpty());
|
||||
|
||||
const DynamicStruct& rds = *object;
|
||||
assert (rds["test"].isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@ -127,6 +136,14 @@ void JSONTest::testTrueProperty()
|
||||
assert(test.type() == typeid(bool));
|
||||
bool value = test;
|
||||
assert(value);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (!ds["test"].isEmpty());
|
||||
assert (ds["test"]);
|
||||
|
||||
const DynamicStruct& rds = *object;
|
||||
assert (!rds["test"].isEmpty());
|
||||
assert (rds["test"]);
|
||||
}
|
||||
|
||||
|
||||
@ -153,6 +170,14 @@ void JSONTest::testFalseProperty()
|
||||
assert(test.type() == typeid(bool));
|
||||
bool value = test;
|
||||
assert(!value);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (!ds["test"].isEmpty());
|
||||
assert (!ds["test"]);
|
||||
|
||||
const DynamicStruct& rds = *object;
|
||||
assert (!rds["test"].isEmpty());
|
||||
assert (!rds["test"]);
|
||||
}
|
||||
|
||||
|
||||
@ -179,6 +204,16 @@ void JSONTest::testNumberProperty()
|
||||
assert(test.isInteger());
|
||||
int value = test;
|
||||
assert(value == 1969);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (!ds["test"].isEmpty());
|
||||
assert (ds["test"].isNumeric());
|
||||
assert (ds["test"] == 1969);
|
||||
|
||||
const DynamicStruct& rds = *object;
|
||||
assert (!rds["test"].isEmpty());
|
||||
assert (rds["test"].isNumeric());
|
||||
assert (rds["test"] == 1969);
|
||||
}
|
||||
|
||||
|
||||
@ -203,8 +238,25 @@ void JSONTest::testUnsignedNumberProperty()
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.isNumeric());
|
||||
assert(test.isInteger());
|
||||
unsigned value = test;
|
||||
Poco::UInt32 value = test;
|
||||
assert(value == -1);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (!ds["test"].isEmpty());
|
||||
assert (ds["test"].isNumeric());
|
||||
assert (ds["test"].isInteger());
|
||||
assert (ds["test"] == 4294967295);
|
||||
value = ds["test"];
|
||||
assert(value == -1);
|
||||
|
||||
const DynamicStruct& rds = *object;
|
||||
assert (!rds["test"].isEmpty());
|
||||
assert (rds["test"].isNumeric());
|
||||
assert (rds["test"].isInteger());
|
||||
assert (rds["test"] == 4294967295);
|
||||
value = rds["test"];
|
||||
assert(value == -1);
|
||||
}
|
||||
|
||||
@ -229,11 +281,27 @@ void JSONTest::testNumber64Property()
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
Object object = *result.extract<Object::Ptr>();
|
||||
Var test = object.get("test");
|
||||
assert(test.isInteger());
|
||||
Poco::Int64 value = test;
|
||||
assert(value == -5000000000000000);
|
||||
|
||||
DynamicStruct ds = object;
|
||||
assert (!ds["test"].isEmpty());
|
||||
assert (ds["test"].isNumeric());
|
||||
assert (ds["test"].isInteger());
|
||||
assert (ds["test"] == -5000000000000000);
|
||||
value = ds["test"];
|
||||
assert(value == -5000000000000000);
|
||||
|
||||
const DynamicStruct& rds = object;
|
||||
assert (!rds["test"].isEmpty());
|
||||
assert (rds["test"].isNumeric());
|
||||
assert (rds["test"].isInteger());
|
||||
assert (rds["test"] == -5000000000000000);
|
||||
value = rds["test"];
|
||||
assert(value == -5000000000000000);
|
||||
}
|
||||
|
||||
|
||||
@ -261,6 +329,22 @@ void JSONTest::testUnsignedNumber64Property()
|
||||
assert(test.isInteger());
|
||||
Poco::UInt64 value = test;
|
||||
assert(value == -1);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (!ds["test"].isEmpty());
|
||||
assert (ds["test"].isNumeric());
|
||||
assert (ds["test"].isInteger());
|
||||
assert (ds["test"] == 18446744073709551615);
|
||||
value = ds["test"];
|
||||
assert(value == -1);
|
||||
|
||||
const DynamicStruct& rds = *object;
|
||||
assert (!rds["test"].isEmpty());
|
||||
assert (rds["test"].isNumeric());
|
||||
assert (rds["test"].isInteger());
|
||||
assert (rds["test"] == 18446744073709551615);
|
||||
value = rds["test"];
|
||||
assert(value == -1);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -284,11 +368,27 @@ void JSONTest::testStringProperty()
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
Object object = *result.extract<Object::Ptr>();
|
||||
Var test = object.get("test");
|
||||
assert(test.isString());
|
||||
std::string value = test.convert<std::string>();
|
||||
assert(value.compare("value") == 0);
|
||||
|
||||
DynamicStruct ds = object;
|
||||
assert (!ds["test"].isEmpty());
|
||||
assert (ds["test"].isString());
|
||||
assert (!ds["test"].isInteger());
|
||||
assert (ds["test"] == "value");
|
||||
value = ds["test"].toString();
|
||||
assert(value == "value");
|
||||
|
||||
const DynamicStruct& rds = object;
|
||||
assert (!rds["test"].isEmpty());
|
||||
assert (rds["test"].isString());
|
||||
assert (!rds["test"].isInteger());
|
||||
assert (rds["test"] == "value");
|
||||
value = rds["test"].toString();
|
||||
assert(value == "value");
|
||||
}
|
||||
|
||||
|
||||
@ -312,6 +412,12 @@ void JSONTest::testEmptyObject()
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
assert(object->size() == 0);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (ds.size() == 0);
|
||||
|
||||
const DynamicStruct& rds = *object;
|
||||
assert (rds.size() == 0);
|
||||
}
|
||||
|
||||
|
||||
@ -386,12 +492,65 @@ void JSONTest::testComplexObject()
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
assert(object->size() > 0);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (ds.size() > 0);
|
||||
assert (ds["id"] == 1);
|
||||
assert (ds["jsonrpc"] == 2.0);
|
||||
|
||||
assert (ds["result"].isArray());
|
||||
assert (ds["result"].size() == 1);
|
||||
assert (ds["result"][0].isStruct());
|
||||
assert (ds["result"][0]["id"] == 1);
|
||||
assert (ds["result"][0]["guid"] == "67acfb26-17eb-4a75-bdbd-f0669b7d8f73");
|
||||
assert (ds["result"][0]["age"] == 40);
|
||||
assert (ds["result"][0]["name"] == "Angelina Crossman");
|
||||
assert (ds["result"][0]["gender"] == "female");
|
||||
assert (ds["result"][0]["company"] == "Raylog");
|
||||
assert (ds["result"][0]["phone"] == "892-470-2803");
|
||||
assert (ds["result"][0]["email"] == "angelina@raylog.com");
|
||||
assert (ds["result"][0]["address"] == "20726, CostaMesa, Horatio Streets");
|
||||
assert (ds["result"][0]["about"] == "Consectetuer suscipit volutpat eros dolor euismod, "
|
||||
"et dignissim in feugiat sed, ea tation exerci quis. Consectetuer, "
|
||||
"dolor dolore ad vero ullamcorper, tincidunt facilisis at in facilisi, "
|
||||
"iusto illum illum. Autem nibh, sed elit consequat volutpat tation, "
|
||||
"nisl lorem lorem sed tation, facilisis dolore. Augue odio molestie, "
|
||||
"dolor zzril nostrud aliquam sed, wisi dolor et ut iusto, ea. Magna "
|
||||
"ex qui facilisi, hendrerit quis in eros ut, zzril nibh dolore nisl "
|
||||
"suscipit, vulputate elit ut lobortis exerci, nulla dolore eros at "
|
||||
"aliquam, ullamcorper vero ad iusto. Adipiscing, nisl eros exerci "
|
||||
"nisl vel, erat in luptatum in duis, iusto.");
|
||||
assert (ds["result"][0]["registered"] == "2008-04-09T11:13:17 +05:00");
|
||||
|
||||
assert (ds["result"][0]["tags"].isArray());
|
||||
assert (ds["result"][0]["tags"].size() == 7);
|
||||
assert (ds["result"][0]["tags"][0] == "ut");
|
||||
assert (ds["result"][0]["tags"][1] == "accumsan");
|
||||
assert (ds["result"][0]["tags"][2] == "feugait");
|
||||
assert (ds["result"][0]["tags"][3] == "ex");
|
||||
assert (ds["result"][0]["tags"][4] == "odio");
|
||||
assert (ds["result"][0]["tags"][5] == "consequat");
|
||||
assert (ds["result"][0]["tags"][6] == "delenit");
|
||||
|
||||
assert (ds["result"][0]["friends"][0].isStruct());
|
||||
assert (ds["result"][0]["friends"][0]["id"] == 1);
|
||||
assert (ds["result"][0]["friends"][0]["name"] == "Hailey Hardman");
|
||||
assert (ds["result"][0]["friends"][1]["id"] == 2);
|
||||
assert (ds["result"][0]["friends"][1]["name"] == "Bailey Oldridge");
|
||||
assert (ds["result"][0]["friends"][2]["id"] == 3);
|
||||
assert (ds["result"][0]["friends"][2]["name"] == "Makayla Campbell");
|
||||
|
||||
const DynamicStruct& rds = *object;
|
||||
assert (rds.size() > 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testDoubleProperty()
|
||||
{
|
||||
std::string json = "{ \"test\" : 123.45 }";
|
||||
std::string json = "{ \"test\" : 1234.5 }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
@ -411,7 +570,10 @@ void JSONTest::testDoubleProperty()
|
||||
Var test = object->get("test");
|
||||
assert(test.isNumeric());
|
||||
double value = test;
|
||||
assert(value == 123.45);
|
||||
assert(value == 1234.5);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (ds["test"] == 1234.5);
|
||||
}
|
||||
|
||||
|
||||
@ -491,12 +653,16 @@ void JSONTest::testObjectProperty()
|
||||
|
||||
Var test = object->get("test");
|
||||
assert(test.type() == typeid(Object::Ptr));
|
||||
object = test.extract<Object::Ptr>();
|
||||
Object::Ptr subObject = test.extract<Object::Ptr>();
|
||||
|
||||
test = object->get("property");
|
||||
test = subObject->get("property");
|
||||
assert(test.isString());
|
||||
std::string value = test.convert<std::string>();
|
||||
assert(value.compare("value") == 0);
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (ds["test"].isStruct());
|
||||
assert (ds["test"]["property"] == "value");
|
||||
}
|
||||
|
||||
|
||||
@ -519,11 +685,23 @@ void JSONTest::testObjectArray()
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
assert(object->isObject("test"));
|
||||
object = object->getObject("test");
|
||||
assert(!object->isObject("test1"));
|
||||
assert(object->isArray("test1"));
|
||||
assert(!object->isObject("test2"));
|
||||
assert(!object->isArray("test2"));
|
||||
Object::Ptr subObject = object->getObject("test");
|
||||
assert(!subObject->isObject("test1"));
|
||||
assert(subObject->isArray("test1"));
|
||||
assert(!subObject->isObject("test2"));
|
||||
assert(!subObject->isArray("test2"));
|
||||
|
||||
DynamicStruct ds = *object;
|
||||
assert (ds.size() > 0);
|
||||
assert (ds.size() == 1);
|
||||
|
||||
assert (ds["test"].isStruct());
|
||||
assert (ds["test"]["test1"].isArray());
|
||||
assert (ds["test"]["test1"].size() == 3);
|
||||
assert (ds["test"]["test1"][0] == 1);
|
||||
assert (ds["test"]["test1"][1] == 2);
|
||||
assert (ds["test"]["test1"][2] == 3);
|
||||
assert (ds["test"]["test2"] == 4);
|
||||
}
|
||||
|
||||
|
||||
@ -543,15 +721,25 @@ void JSONTest::testArrayOfObjects()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
Array::Ptr arr = result.extract<Array::Ptr>();
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
Poco::JSON::Array::Ptr arr = result.extract<Poco::JSON::Array::Ptr>();
|
||||
Object::Ptr object = arr->getObject(0);
|
||||
assert (object->getValue<int>("test") == 0);
|
||||
object = arr->getObject(1);
|
||||
arr = object->getArray("test1");
|
||||
result = arr->get(0);
|
||||
Object::Ptr subObject = arr->getObject(1);
|
||||
Poco::JSON::Array::Ptr subArr = subObject->getArray("test1");
|
||||
result = subArr->get(0);
|
||||
assert (result == 1);
|
||||
|
||||
Poco::Dynamic::Array da = *arr;
|
||||
assert (da.size() == 2);
|
||||
assert (da[0].isStruct());
|
||||
assert (da[0]["test"] == 0);
|
||||
assert (da[1].isStruct());
|
||||
assert (da[1]["test1"].isArray());
|
||||
assert (da[1]["test1"][0] == 1);
|
||||
assert (da[1]["test1"][1] == 2);
|
||||
assert (da[1]["test1"][2] == 3);
|
||||
assert (da[1]["test2"] == 4);
|
||||
}
|
||||
|
||||
|
||||
@ -571,10 +759,13 @@ void JSONTest::testEmptyArray()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
assert(array->size() == 0);
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 0);
|
||||
}
|
||||
|
||||
|
||||
@ -594,10 +785,16 @@ void JSONTest::testNestedArray()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
assert(array->size() == 1);
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (da[0].size() == 1);
|
||||
assert (da[0][0].size() == 1);
|
||||
assert (da[0][0][0].size() == 0);
|
||||
}
|
||||
|
||||
|
||||
@ -617,12 +814,16 @@ void JSONTest::testNullElement()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
assert(array->isNull(0));
|
||||
Var test = array->get(0);
|
||||
assert(test.isEmpty());
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (da[0].isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@ -642,13 +843,17 @@ void JSONTest::testTrueElement()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.type() == typeid(bool));
|
||||
bool value = test;
|
||||
assert(value);
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (da[0]);
|
||||
}
|
||||
|
||||
|
||||
@ -668,13 +873,17 @@ void JSONTest::testFalseElement()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.type() == typeid(bool));
|
||||
bool value = test;
|
||||
assert(!value);
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (!da[0]);
|
||||
}
|
||||
|
||||
|
||||
@ -694,13 +903,17 @@ void JSONTest::testNumberElement()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.isInteger());
|
||||
int value = test;
|
||||
assert(value == 1969);
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (da[0] == 1969);
|
||||
}
|
||||
|
||||
|
||||
@ -720,13 +933,17 @@ void JSONTest::testStringElement()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.isString());
|
||||
std::string value = test.convert<std::string>();
|
||||
assert(value.compare("value") == 0);
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (da[0] == "value");
|
||||
}
|
||||
|
||||
|
||||
@ -746,17 +963,22 @@ void JSONTest::testEmptyObjectElement()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
Object::Ptr object = array->getObject(0);
|
||||
assert(object->size() == 0);
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (da[0].isStruct());
|
||||
assert (da[0].size() == 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testDoubleElement()
|
||||
{
|
||||
std::string json = "[ 123.45 ]";
|
||||
std::string json = "[ 1234.5 ]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
@ -770,13 +992,17 @@ void JSONTest::testDoubleElement()
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.isNumeric());
|
||||
double value = test;
|
||||
assert(value == 123.45);
|
||||
assert(value == 1234.5);
|
||||
|
||||
Poco::Dynamic::Array da = *array;
|
||||
assert (da.size() == 1);
|
||||
assert (da[0] == 1234.5);
|
||||
}
|
||||
|
||||
|
||||
@ -826,6 +1052,48 @@ void JSONTest::testQuery()
|
||||
|
||||
std::string firstChild = query.findValue("children[0]", "");
|
||||
assert(firstChild.compare("Jonas") == 0);
|
||||
|
||||
Poco::DynamicStruct ds = *result.extract<Object::Ptr>();
|
||||
assert (ds["name"] == "Franky");
|
||||
assert (ds["children"].size() == 2);
|
||||
assert (ds["children"][0] == "Jonas");
|
||||
assert (ds["children"][1] == "Ellen");
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testComment()
|
||||
{
|
||||
std::string json = "{ \"name\" : \"Franky\" /* father */, \"children\" : [ \"Jonas\" /* son */ , \"Ellen\" /* daughter */ ] }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
parser.parse(json);
|
||||
fail ("must fail");
|
||||
}
|
||||
catch(Poco::SyntaxException&)
|
||||
{
|
||||
}
|
||||
|
||||
parser.reset();
|
||||
parser.setAllowComments(true);
|
||||
try
|
||||
{
|
||||
result = parser.parse(json);
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Query query(result);
|
||||
|
||||
std::string firstChild = query.findValue("children[0]", "");
|
||||
assert(firstChild.compare("Jonas") == 0);
|
||||
}
|
||||
|
||||
|
||||
@ -1127,6 +1395,26 @@ void JSONTest::testStringifyPreserveOrder()
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}");
|
||||
|
||||
Poco::DynamicStruct ds = *result.extract<Object::Ptr>();
|
||||
assert (ds["Simpsons"].isStruct());
|
||||
assert (ds["Simpsons"]["husband"].isStruct());
|
||||
assert (ds["Simpsons"]["husband"]["name"] == "Homer");
|
||||
assert (ds["Simpsons"]["husband"]["age"] == 38);
|
||||
|
||||
assert (ds["Simpsons"]["wife"].isStruct());
|
||||
assert (ds["Simpsons"]["wife"]["name"] == "Marge");
|
||||
assert (ds["Simpsons"]["wife"]["age"] == 36);
|
||||
|
||||
assert (ds["Simpsons"]["children"].isArray());
|
||||
assert (ds["Simpsons"]["children"][0] == "Bart");
|
||||
assert (ds["Simpsons"]["children"][1] == "Lisa");
|
||||
assert (ds["Simpsons"]["children"][2] == "Maggie");
|
||||
|
||||
assert (ds["Simpsons"]["address"].isStruct());
|
||||
assert (ds["Simpsons"]["address"]["number"] == 742);
|
||||
assert (ds["Simpsons"]["address"]["street"] == "Evergreen Terrace");
|
||||
assert (ds["Simpsons"]["address"]["town"] == "Springfield");
|
||||
}
|
||||
|
||||
|
||||
@ -1155,7 +1443,7 @@ void JSONTest::testValidJanssonFiles()
|
||||
try
|
||||
{
|
||||
parser.parse(fis);
|
||||
result = parser.result();
|
||||
result = parser.asVar();
|
||||
std::cout << "Ok!" << std::endl;
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
@ -1202,7 +1490,7 @@ void JSONTest::testInvalidJanssonFiles()
|
||||
try
|
||||
{
|
||||
parser.parse(fis);
|
||||
result = parser.result();
|
||||
result = parser.asVar();
|
||||
// We shouldn't get here.
|
||||
std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
|
||||
fail(result.convert<std::string>());
|
||||
@ -1245,7 +1533,7 @@ void JSONTest::testInvalidUnicodeJanssonFiles()
|
||||
try
|
||||
{
|
||||
parser.parse(fis);
|
||||
result = parser.result();
|
||||
result = parser.asVar();
|
||||
// We shouldn't get here.
|
||||
std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
|
||||
fail(result.convert<std::string>());
|
||||
@ -1291,7 +1579,7 @@ void JSONTest::testUnicode()
|
||||
try
|
||||
{
|
||||
parser.parse(json);
|
||||
result = parser.result();
|
||||
result = parser.asVar();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
@ -1374,6 +1662,7 @@ CppUnit::Test* JSONTest::suite()
|
||||
CppUnit_addTest(pSuite, JSONTest, testDoubleElement);
|
||||
CppUnit_addTest(pSuite, JSONTest, testOptValue);
|
||||
CppUnit_addTest(pSuite, JSONTest, testQuery);
|
||||
CppUnit_addTest(pSuite, JSONTest, testComment);
|
||||
CppUnit_addTest(pSuite, JSONTest, testPrintHandler);
|
||||
CppUnit_addTest(pSuite, JSONTest, testStringify);
|
||||
CppUnit_addTest(pSuite, JSONTest, testStringifyPreserveOrder);
|
||||
|
@ -75,6 +75,7 @@ public:
|
||||
void testDoubleElement();
|
||||
void testOptValue();
|
||||
void testQuery();
|
||||
void testComment();
|
||||
void testPrintHandler();
|
||||
void testStringify();
|
||||
void testStringifyPreserveOrder();
|
||||
|
@ -189,3 +189,60 @@ public domain (http://www.sqlite.org/copyright.html).
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute the
|
||||
original SQLite code, either in source code form or as a compiled binary,
|
||||
for any purpose, commercial or non-commercial, and by any means.
|
||||
----
|
||||
|
||||
|
||||
!!!double-conversion
|
||||
|
||||
Copyright 2010 the V8 project authors. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----
|
||||
|
||||
|
||||
!!!JSON_parser
|
||||
|
||||
Copyright (c) 2005 JSON.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
The Software shall be used for Good, not Evil.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
@ -227,6 +227,29 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
</pre></p>
|
||||
|
||||
<h3>JSON_parser</h3>
|
||||
<p><pre>Copyright (c) 2005 JSON.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
The Software shall be used for Good, not Evil.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
</pre></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user