diff --git a/Foundation/Foundation_vs71.vcproj b/Foundation/Foundation_vs71.vcproj
index d9a60f2be..074183f8e 100644
--- a/Foundation/Foundation_vs71.vcproj
+++ b/Foundation/Foundation_vs71.vcproj
@@ -3653,6 +3653,11 @@
RelativePath=".\include\Poco\DynamicStruct.h"
>
+
+
+
diff --git a/Foundation/Foundation_vs80.vcproj b/Foundation/Foundation_vs80.vcproj
index 9d23d90f2..414e179aa 100644
--- a/Foundation/Foundation_vs80.vcproj
+++ b/Foundation/Foundation_vs80.vcproj
@@ -4741,6 +4741,10 @@
RelativePath=".\include\Poco\DynamicStruct.h"
>
+
+
diff --git a/Foundation/Foundation_vs90.vcproj b/Foundation/Foundation_vs90.vcproj
index db8336d78..6e440da21 100644
--- a/Foundation/Foundation_vs90.vcproj
+++ b/Foundation/Foundation_vs90.vcproj
@@ -4732,6 +4732,10 @@
RelativePath=".\include\Poco\DynamicStruct.h"
>
+
+
diff --git a/Foundation/include/Poco/Dynamic/Pair.h b/Foundation/include/Poco/Dynamic/Pair.h
new file mode 100644
index 000000000..b3fa54688
--- /dev/null
+++ b/Foundation/include/Poco/Dynamic/Pair.h
@@ -0,0 +1,427 @@
+//
+// Pair.h
+//
+// $Id: //poco/Main/Foundation/include/Poco/Dynamic/Pair.h#9 $
+//
+// Library: Foundation
+// Package: Dynamic
+// Module: Pair
+//
+// Definition of the Pair class.
+//
+// Copyright (c) 2007, 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_Pair_INCLUDED
+#define Foundation_Pair_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Dynamic/Var.h"
+#include "Poco/Dynamic/VarHolder.h"
+#include
+
+
+namespace Poco {
+namespace Dynamic {
+
+
+template
+class Pair
+ /// Pair allows to define a pair of values.
+{
+public:
+ typedef typename std::pair Data;
+
+ Pair(): _data()
+ /// Creates an empty Pair
+ {
+ }
+
+ Pair(const Pair& other): _data(other._data)
+ /// Creates the Pair from another pair.
+ {
+ }
+
+ Pair(const Data& val): _data(val)
+ /// Creates the Pair from the given value.
+ {
+ }
+
+ template
+ Pair(const std::pair& val): _data(std::make_pair(val.first, Var(val.second)))
+ /// Creates Pair form standard pair.
+ {
+ }
+
+ template
+ Pair(const K& first, const T& second): _data(std::make_pair(first, Var(second)))
+ /// Creates pair from two values.
+ {
+ }
+
+ virtual ~Pair()
+ /// Destroys the Pair.
+ {
+ }
+
+ Pair& swap(Pair& other)
+ /// Swaps the content of the two Pairs.
+ {
+ std::swap(_data, other._data);
+ return *this;
+ }
+
+ Pair& operator = (const Pair& other)
+ /// Copy constructs Pair from another pair.
+ {
+ Pair(other).swap(*this);
+ return *this;
+ }
+
+ inline const K& first() const
+ /// Returns the first member of the pair.
+ {
+ return _data.first;
+ }
+
+ inline const Var& second() const
+ /// Returns the second member of the pair.
+ {
+ return _data.second;
+ }
+
+private:
+ Data _data;
+};
+
+
+template <>
+class VarHolderImpl >: public VarHolder
+{
+public:
+ VarHolderImpl(const Pair& val): _val(val)
+ {
+ }
+
+ ~VarHolderImpl()
+ {
+ }
+
+ const std::type_info& type() const
+ {
+ return typeid(Pair);
+ }
+
+ void convert(Int8& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to Int8");
+ }
+
+ void convert(Int16& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to Int16");
+ }
+
+ void convert(Int32& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to Int32");
+ }
+
+ void convert(Int64& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to Int64");
+ }
+
+ void convert(UInt8& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to UInt8");
+ }
+
+ void convert(UInt16& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to UInt16");
+ }
+
+ void convert(UInt32& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to UInt32");
+ }
+
+ void convert(UInt64& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to UInt64");
+ }
+
+ void convert(bool& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to bool");
+ }
+
+ void convert(float& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to float");
+ }
+
+ void convert(double& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to double");
+ }
+
+ void convert(char& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to char");
+ }
+
+ void convert(std::string& val) const
+ {
+ // Serialize in JSON format: equals an object
+ // JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
+ val.append("{ ");
+ Var key(_val.first());
+ appendJSONString(val, key);
+ val.append(" : ");
+ appendJSONString(val, _val.second());
+ val.append(" }");
+ }
+
+ void convert(Poco::DateTime&) const
+ {
+ throw BadCastException("Pair -> Poco::DateTime");
+ }
+
+ void convert(Poco::LocalDateTime&) const
+ {
+ throw BadCastException("Pair -> Poco::LocalDateTime");
+ }
+
+ void convert(Poco::Timestamp&) const
+ {
+ throw BadCastException("Pair -> Poco::Timestamp");
+ }
+
+ VarHolder* clone() const
+ {
+ return new VarHolderImpl(_val);
+ }
+
+ const Pair& value() const
+ {
+ 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 false;
+ }
+
+private:
+ Pair _val;
+};
+
+
+template <>
+class VarHolderImpl >: public VarHolder
+{
+public:
+ VarHolderImpl(const Pair& val): _val(val)
+ {
+ }
+
+ ~VarHolderImpl()
+ {
+ }
+
+ const std::type_info& type() const
+ {
+ return typeid(Pair);
+ }
+
+ void convert(Int8& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to Int8");
+ }
+
+ void convert(Int16& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to Int16");
+ }
+
+ void convert(Int32& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to Int32");
+ }
+
+ void convert(Int64& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to Int64");
+ }
+
+ void convert(UInt8& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to UInt8");
+ }
+
+ void convert(UInt16& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to UInt16");
+ }
+
+ void convert(UInt32& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to UInt32");
+ }
+
+ void convert(UInt64& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to UInt64");
+ }
+
+ void convert(bool& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to bool");
+ }
+
+ void convert(float& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to float");
+ }
+
+ void convert(double& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to double");
+ }
+
+ void convert(char& val) const
+ {
+ throw BadCastException("Cannot cast Pair type to char");
+ }
+
+ void convert(std::string& val) const
+ {
+ // Serialize in JSON format: equals an object
+ // JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
+ val.append("{ ");
+ Var key(_val.first());
+ appendJSONString(val, key);
+ val.append(" : ");
+ appendJSONString(val, _val.second());
+ val.append(" }");
+ }
+
+ void convert(Poco::DateTime&) const
+ {
+ throw BadCastException("Pair -> Poco::DateTime");
+ }
+
+ void convert(Poco::LocalDateTime&) const
+ {
+ throw BadCastException("Pair -> Poco::LocalDateTime");
+ }
+
+ void convert(Poco::Timestamp&) const
+ {
+ throw BadCastException("Pair -> Poco::Timestamp");
+ }
+
+ VarHolder* clone() const
+ {
+ return new VarHolderImpl(_val);
+ }
+
+ const Pair& value() const
+ {
+ 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 false;
+ }
+
+private:
+ Pair _val;
+};
+
+
+} // namespace Dynamic
+
+
+} // namespace Poco
+
+
+#endif // Foundation_Pair_INCLUDED
diff --git a/Foundation/include/Poco/Dynamic/Struct.h b/Foundation/include/Poco/Dynamic/Struct.h
index 27a828b43..5a315c6e7 100644
--- a/Foundation/include/Poco/Dynamic/Struct.h
+++ b/Foundation/include/Poco/Dynamic/Struct.h
@@ -1,7 +1,7 @@
//
// Struct.h
//
-// $Id: //poco/Main/Foundation/include/Poco/Struct.h#9 $
+// $Id: //poco/Main/Foundation/include/Poco/Dynamic/Struct.h#9 $
//
// Library: Foundation
// Package: Dynamic
@@ -69,7 +69,7 @@ public:
{
}
- Struct(const Data &val): _data(val)
+ Struct(const Data& val): _data(val)
/// Creates the Struct from the given value.
{
}
@@ -286,9 +286,6 @@ public:
void convert(std::string& val) const
{
- // Serialize in JSON format: equals an object
-
- // JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
val.append("{ ");
Struct::ConstIterator it = _val.begin();
Struct::ConstIterator itEnd = _val.end();
@@ -460,9 +457,6 @@ public:
void convert(std::string& val) const
{
- // Serialize in JSON format: equals an object
-
- // JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
val.append("{ ");
Struct::ConstIterator it = _val.begin();
Struct::ConstIterator itEnd = _val.end();
diff --git a/Foundation/include/Poco/Dynamic/Var.h b/Foundation/include/Poco/Dynamic/Var.h
index 078cb74e7..56b32e2c6 100644
--- a/Foundation/include/Poco/Dynamic/Var.h
+++ b/Foundation/include/Poco/Dynamic/Var.h
@@ -53,7 +53,6 @@ namespace Dynamic {
template
class Struct;
-
class Foundation_API Var
/// Var allows to store data of different types and to convert between these types transparently.
/// Var puts forth the best effort to provide intuitive and reasonable conversion semantics and prevent
diff --git a/Foundation/include/Poco/Dynamic/VarHolder.h b/Foundation/include/Poco/Dynamic/VarHolder.h
index a0dfa74f7..12465f9f4 100644
--- a/Foundation/include/Poco/Dynamic/VarHolder.h
+++ b/Foundation/include/Poco/Dynamic/VarHolder.h
@@ -65,6 +65,9 @@ namespace Dynamic {
class Var;
+bool Foundation_API isJSONString(const Var& any);
+ /// Returns true for values that should be JSON-formatted as string.
+
void Foundation_API appendJSONString(std::string& val, const Var& any);
/// Converts the any to a JSON value and adds it to val
diff --git a/Foundation/src/Var.cpp b/Foundation/src/Var.cpp
index 84e19076d..e9457946d 100644
--- a/Foundation/src/Var.cpp
+++ b/Foundation/src/Var.cpp
@@ -423,12 +423,12 @@ Var Var::parseArray(const std::string& val, std::string::size_type& pos)
std::string Var::parseString(const std::string& val, std::string::size_type& pos)
{
- static const std::string STR_STOP("'\"");
+ static const std::string STR_STOP("\"");
static const std::string OTHER_STOP(" ,]}"); // we stop at space, ',', ']' or '}'
bool inString = false;
//skip optional ' "
- if (val[pos] == '\'' || val[pos] == '"')
+ if (val[pos] == '"')
{
inString = true;
++pos;
diff --git a/Foundation/src/VarHolder.cpp b/Foundation/src/VarHolder.cpp
index 6473b37d6..702082417 100644
--- a/Foundation/src/VarHolder.cpp
+++ b/Foundation/src/VarHolder.cpp
@@ -52,17 +52,24 @@ VarHolder::~VarHolder()
}
+bool isJSONString(const Var& any)
+{
+ return any.type() == typeid(std::string) ||
+ any.type() == typeid(char) ||
+ any.type() == typeid(Poco::DateTime) ||
+ any.type() == typeid(Poco::LocalDateTime);
+}
+
+
void appendJSONString(std::string& val, const Var& any)
{
- bool isJsonString = (any.type() == typeid(std::string) || any.type() == typeid(char) || any.type() == typeid(Poco::DateTime) || any.type() == typeid(Poco::LocalDateTime));
- if (isJsonString)
+ if (any.isEmpty()) val.append("null");
+ else
{
- val.append(1, '\'');
- }
- val.append(any.convert());
- if (isJsonString)
- {
- val.append(1, '\'');
+ bool isStr = isJSONString(any);
+ if (isStr) val.append(1, '"');
+ val.append(any.convert());
+ if (isStr) val.append(1, '"');
}
}
diff --git a/Foundation/testsuite/src/VarTest.cpp b/Foundation/testsuite/src/VarTest.cpp
index 7d36a2fdc..75a99a2d7 100644
--- a/Foundation/testsuite/src/VarTest.cpp
+++ b/Foundation/testsuite/src/VarTest.cpp
@@ -36,11 +36,13 @@
#include "Poco/Exception.h"
#include "Poco/Dynamic/Var.h"
#include "Poco/Bugcheck.h"
-#include "Poco/DynamicStruct.h"
+#include "Poco/Dynamic/Struct.h"
+#include "Poco/Dynamic/Pair.h"
+#include