mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-27 02:53:10 +01:00
feat(DynamicStruct): toString() escaping #3833
This commit is contained in:
@@ -32,6 +32,37 @@ namespace Poco {
|
|||||||
namespace Dynamic {
|
namespace Dynamic {
|
||||||
|
|
||||||
|
|
||||||
|
template <typename S, typename I = typename S::ConstIterator>
|
||||||
|
std::string structToString(const S& data, bool wrap = true)
|
||||||
|
/// Utility function for converting DynamicStruct to std::string.
|
||||||
|
/// Set wrap to false in order to prevent string values wrapping
|
||||||
|
/// (useful to prevent JSON fragments from being treated as strings).
|
||||||
|
{
|
||||||
|
std::string val;
|
||||||
|
val.append("{ ");
|
||||||
|
I it = data.begin();
|
||||||
|
I itEnd = data.end();
|
||||||
|
if (!data.empty())
|
||||||
|
{
|
||||||
|
Var key(it->first);
|
||||||
|
Impl::appendJSONKey(val, key);
|
||||||
|
val.append(": ");
|
||||||
|
Impl::appendJSONValue(val, it->second, wrap);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
for (; it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
val.append(", ");
|
||||||
|
Var key(it->first);
|
||||||
|
Impl::appendJSONKey(val, key);
|
||||||
|
val.append(": ");
|
||||||
|
Impl::appendJSONValue(val, it->second, wrap);
|
||||||
|
}
|
||||||
|
val.append(" }");
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename K, typename M = std::map<K, Var>, typename S = std::set<K>>
|
template <typename K, typename M = std::map<K, Var>, typename S = std::set<K>>
|
||||||
class Struct
|
class Struct
|
||||||
/// Struct allows to define a named collection of Var objects.
|
/// Struct allows to define a named collection of Var objects.
|
||||||
@@ -226,11 +257,20 @@ public:
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString() const
|
std::string toString(bool wrap = true) const
|
||||||
|
/// Returns the DynamicStruct as string.
|
||||||
|
///
|
||||||
|
/// To prevent unwanted string wrapping
|
||||||
|
/// (eg. when a value is JSON string),
|
||||||
|
/// `wrap` should be false. Note, however,
|
||||||
|
/// that wrap argument is of a limited utility
|
||||||
|
/// because it applies to the entire Struct,
|
||||||
|
/// so it should not be relied on when mixed content
|
||||||
|
/// (ie. plain string, which should be wrapped,
|
||||||
|
/// and JSON-as-string entries, which shouldn't)
|
||||||
|
/// is held.
|
||||||
{
|
{
|
||||||
std::string str;
|
return structToString<Data, ConstIterator>(_data, wrap);
|
||||||
Var(*this).template convert<std::string>(str);
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -332,26 +372,7 @@ public:
|
|||||||
|
|
||||||
void convert(std::string& val) const
|
void convert(std::string& val) const
|
||||||
{
|
{
|
||||||
val.append("{ ");
|
val = structToString(_val);
|
||||||
ValueType::ConstIterator it = _val.begin();
|
|
||||||
ValueType::ConstIterator itEnd = _val.end();
|
|
||||||
if (!_val.empty())
|
|
||||||
{
|
|
||||||
Var key(it->first);
|
|
||||||
Impl::appendJSONKey(val, key);
|
|
||||||
val.append(": ");
|
|
||||||
Impl::appendJSONValue(val, it->second);
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
for (; it != itEnd; ++it)
|
|
||||||
{
|
|
||||||
val.append(", ");
|
|
||||||
Var key(it->first);
|
|
||||||
Impl::appendJSONKey(val, key);
|
|
||||||
val.append(": ");
|
|
||||||
Impl::appendJSONValue(val, it->second);
|
|
||||||
}
|
|
||||||
val.append(" }");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Poco::DateTime&) const
|
void convert(Poco::DateTime&) const
|
||||||
@@ -518,26 +539,7 @@ public:
|
|||||||
|
|
||||||
void convert(std::string& val) const
|
void convert(std::string& val) const
|
||||||
{
|
{
|
||||||
val.append("{ ");
|
val = structToString(_val);
|
||||||
ValueType::ConstIterator it = _val.begin();
|
|
||||||
ValueType::ConstIterator itEnd = _val.end();
|
|
||||||
if (!_val.empty())
|
|
||||||
{
|
|
||||||
Var key(it->first);
|
|
||||||
Impl::appendJSONKey(val, key);
|
|
||||||
val.append(": ");
|
|
||||||
Impl::appendJSONValue(val, it->second);
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
for (; it != itEnd; ++it)
|
|
||||||
{
|
|
||||||
val.append(", ");
|
|
||||||
Var key(it->first);
|
|
||||||
Impl::appendJSONKey(val, key);
|
|
||||||
val.append(": ");
|
|
||||||
Impl::appendJSONValue(val, it->second);
|
|
||||||
}
|
|
||||||
val.append(" }");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Poco::DateTime&) const
|
void convert(Poco::DateTime&) const
|
||||||
@@ -704,26 +706,7 @@ public:
|
|||||||
|
|
||||||
void convert(std::string& val) const
|
void convert(std::string& val) const
|
||||||
{
|
{
|
||||||
val.append("{ ");
|
val = structToString(_val);
|
||||||
ValueType::ConstIterator it = _val.begin();
|
|
||||||
ValueType::ConstIterator itEnd = _val.end();
|
|
||||||
if (!_val.empty())
|
|
||||||
{
|
|
||||||
Var key(it->first);
|
|
||||||
Impl::appendJSONKey(val, key);
|
|
||||||
val.append(": ");
|
|
||||||
Impl::appendJSONValue(val, it->second);
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
for (; it != itEnd; ++it)
|
|
||||||
{
|
|
||||||
val.append(", ");
|
|
||||||
Var key(it->first);
|
|
||||||
Impl::appendJSONKey(val, key);
|
|
||||||
val.append(": ");
|
|
||||||
Impl::appendJSONValue(val, it->second);
|
|
||||||
}
|
|
||||||
val.append(" }");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Poco::DateTime&) const
|
void convert(Poco::DateTime&) const
|
||||||
@@ -890,26 +873,7 @@ public:
|
|||||||
|
|
||||||
void convert(std::string& val) const
|
void convert(std::string& val) const
|
||||||
{
|
{
|
||||||
val.append("{ ");
|
val = structToString(_val);
|
||||||
ValueType::ConstIterator it = _val.begin();
|
|
||||||
ValueType::ConstIterator itEnd = _val.end();
|
|
||||||
if (!_val.empty())
|
|
||||||
{
|
|
||||||
Var key(it->first);
|
|
||||||
Impl::appendJSONKey(val, key);
|
|
||||||
val.append(": ");
|
|
||||||
Impl::appendJSONValue(val, it->second);
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
for (; it != itEnd; ++it)
|
|
||||||
{
|
|
||||||
val.append(", ");
|
|
||||||
Var key(it->first);
|
|
||||||
Impl::appendJSONKey(val, key);
|
|
||||||
val.append(": ");
|
|
||||||
Impl::appendJSONValue(val, it->second);
|
|
||||||
}
|
|
||||||
val.append(" }");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Poco::DateTime&) const
|
void convert(Poco::DateTime&) const
|
||||||
|
|||||||
@@ -67,10 +67,12 @@ void Foundation_API appendJSONString(std::string& val, const Var& any);
|
|||||||
/// regardless of the underlying type) and appends it to val.
|
/// regardless of the underlying type) and appends it to val.
|
||||||
|
|
||||||
|
|
||||||
void Foundation_API appendJSONValue(std::string& val, const Var& any);
|
void Foundation_API appendJSONValue(std::string& val, const Var& any, bool wrap = true);
|
||||||
/// Converts the any to a JSON value (if underlying type qualifies
|
/// Converts the any to a JSON value (if underlying type qualifies
|
||||||
/// as string - see isJSONString() - , it is wrapped into double quotes)
|
/// as string - see isJSONString() - it is wrapped into double quotes)
|
||||||
/// and appends it to val
|
/// and appends it to val.
|
||||||
|
/// Wrapping can be prevented (useful for appending JSON fragments) by setting
|
||||||
|
/// the wrap argument to false.
|
||||||
|
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ void appendJSONKey(std::string& val, const Var& any)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void appendJSONValue(std::string& val, const Var& any)
|
void appendJSONValue(std::string& val, const Var& any, bool wrap)
|
||||||
{
|
{
|
||||||
if (any.isEmpty())
|
if (any.isEmpty())
|
||||||
{
|
{
|
||||||
@@ -74,7 +74,7 @@ void appendJSONValue(std::string& val, const Var& any)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool isStr = isJSONString(any);
|
bool isStr = wrap && isJSONString(any);
|
||||||
if (isStr)
|
if (isStr)
|
||||||
{
|
{
|
||||||
appendJSONString(val, any.convert<std::string>());
|
appendJSONString(val, any.convert<std::string>());
|
||||||
|
|||||||
@@ -2286,6 +2286,14 @@ void VarTest::testOrderedDynamicStructBasics()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VarTest::testDynamicStructNoEscapeString()
|
||||||
|
{
|
||||||
|
DynamicStruct aStruct;
|
||||||
|
aStruct["Birthday"] = "{ \"Day\": 12, \"Month\": \"May\", \"Year\": 2005 }";
|
||||||
|
assertEqual(aStruct.toString(false), "{ \"Birthday\": { \"Day\": 12, \"Month\": \"May\", \"Year\": 2005 } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VarTest::testDynamicStructString()
|
void VarTest::testDynamicStructString()
|
||||||
{
|
{
|
||||||
DynamicStruct aStruct;
|
DynamicStruct aStruct;
|
||||||
@@ -3131,6 +3139,7 @@ CppUnit::Test* VarTest::suite()
|
|||||||
CppUnit_addTest(pSuite, VarTest, testDynamicPair);
|
CppUnit_addTest(pSuite, VarTest, testDynamicPair);
|
||||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructBasics);
|
CppUnit_addTest(pSuite, VarTest, testDynamicStructBasics);
|
||||||
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructBasics);
|
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructBasics);
|
||||||
|
CppUnit_addTest(pSuite, VarTest, testDynamicStructNoEscapeString);
|
||||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructString);
|
CppUnit_addTest(pSuite, VarTest, testDynamicStructString);
|
||||||
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructString);
|
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructString);
|
||||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructInt);
|
CppUnit_addTest(pSuite, VarTest, testDynamicStructInt);
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public:
|
|||||||
void testDynamicStructBasics();
|
void testDynamicStructBasics();
|
||||||
void testOrderedDynamicStructBasics();
|
void testOrderedDynamicStructBasics();
|
||||||
void testDynamicStructString();
|
void testDynamicStructString();
|
||||||
|
void testDynamicStructNoEscapeString();
|
||||||
void testOrderedDynamicStructString();
|
void testOrderedDynamicStructString();
|
||||||
void testDynamicStructInt();
|
void testDynamicStructInt();
|
||||||
void testOrderedDynamicStructInt();
|
void testOrderedDynamicStructInt();
|
||||||
|
|||||||
Reference in New Issue
Block a user