mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-13 10:32:57 +01:00
feat(DynamicStruct): toString() escaping #3833
This commit is contained in:
parent
d11e48f851
commit
a2c09c29d8
@ -32,6 +32,37 @@ namespace Poco {
|
||||
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>>
|
||||
class Struct
|
||||
/// Struct allows to define a named collection of Var objects.
|
||||
@ -226,11 +257,20 @@ public:
|
||||
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;
|
||||
Var(*this).template convert<std::string>(str);
|
||||
return str;
|
||||
return structToString<Data, ConstIterator>(_data, wrap);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -332,26 +372,7 @@ public:
|
||||
|
||||
void convert(std::string& val) const
|
||||
{
|
||||
val.append("{ ");
|
||||
ValueType::ConstIterator it = _val.begin();
|
||||
ValueType::ConstIterator itEnd = _val.end();
|
||||
if (!_val.empty())
|
||||
{
|
||||
Var key(it->first);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(": ");
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
++it;
|
||||
}
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
val.append(", ");
|
||||
Var key(it->first);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(": ");
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
}
|
||||
val.append(" }");
|
||||
val = structToString(_val);
|
||||
}
|
||||
|
||||
void convert(Poco::DateTime&) const
|
||||
@ -518,26 +539,7 @@ public:
|
||||
|
||||
void convert(std::string& val) const
|
||||
{
|
||||
val.append("{ ");
|
||||
ValueType::ConstIterator it = _val.begin();
|
||||
ValueType::ConstIterator itEnd = _val.end();
|
||||
if (!_val.empty())
|
||||
{
|
||||
Var key(it->first);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(": ");
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
++it;
|
||||
}
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
val.append(", ");
|
||||
Var key(it->first);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(": ");
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
}
|
||||
val.append(" }");
|
||||
val = structToString(_val);
|
||||
}
|
||||
|
||||
void convert(Poco::DateTime&) const
|
||||
@ -704,26 +706,7 @@ public:
|
||||
|
||||
void convert(std::string& val) const
|
||||
{
|
||||
val.append("{ ");
|
||||
ValueType::ConstIterator it = _val.begin();
|
||||
ValueType::ConstIterator itEnd = _val.end();
|
||||
if (!_val.empty())
|
||||
{
|
||||
Var key(it->first);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(": ");
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
++it;
|
||||
}
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
val.append(", ");
|
||||
Var key(it->first);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(": ");
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
}
|
||||
val.append(" }");
|
||||
val = structToString(_val);
|
||||
}
|
||||
|
||||
void convert(Poco::DateTime&) const
|
||||
@ -890,26 +873,7 @@ public:
|
||||
|
||||
void convert(std::string& val) const
|
||||
{
|
||||
val.append("{ ");
|
||||
ValueType::ConstIterator it = _val.begin();
|
||||
ValueType::ConstIterator itEnd = _val.end();
|
||||
if (!_val.empty())
|
||||
{
|
||||
Var key(it->first);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(": ");
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
++it;
|
||||
}
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
val.append(", ");
|
||||
Var key(it->first);
|
||||
Impl::appendJSONKey(val, key);
|
||||
val.append(": ");
|
||||
Impl::appendJSONValue(val, it->second);
|
||||
}
|
||||
val.append(" }");
|
||||
val = structToString(_val);
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
/// as string - see isJSONString() - , it is wrapped into double quotes)
|
||||
/// and appends it to val
|
||||
/// as string - see isJSONString() - it is wrapped into double quotes)
|
||||
/// and appends it to val.
|
||||
/// Wrapping can be prevented (useful for appending JSON fragments) by setting
|
||||
/// the wrap argument to false.
|
||||
|
||||
|
||||
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())
|
||||
{
|
||||
@ -74,7 +74,7 @@ void appendJSONValue(std::string& val, const Var& any)
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isStr = isJSONString(any);
|
||||
bool isStr = wrap && isJSONString(any);
|
||||
if (isStr)
|
||||
{
|
||||
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()
|
||||
{
|
||||
DynamicStruct aStruct;
|
||||
@ -3131,6 +3139,7 @@ CppUnit::Test* VarTest::suite()
|
||||
CppUnit_addTest(pSuite, VarTest, testDynamicPair);
|
||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructBasics);
|
||||
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructBasics);
|
||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructNoEscapeString);
|
||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructString);
|
||||
CppUnit_addTest(pSuite, VarTest, testOrderedDynamicStructString);
|
||||
CppUnit_addTest(pSuite, VarTest, testDynamicStructInt);
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
void testDynamicStructBasics();
|
||||
void testOrderedDynamicStructBasics();
|
||||
void testDynamicStructString();
|
||||
void testDynamicStructNoEscapeString();
|
||||
void testOrderedDynamicStructString();
|
||||
void testDynamicStructInt();
|
||||
void testOrderedDynamicStructInt();
|
||||
|
Loading…
Reference in New Issue
Block a user