mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-25 18:22:59 +02:00
add JSONFormatter
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="debug_shared|x64">
|
||||
@@ -303,6 +303,7 @@
|
||||
<ClInclude Include="include\Poco\Data\DynamicDateTime.h" />
|
||||
<ClInclude Include="include\Poco\Data\DynamicLOB.h" />
|
||||
<ClInclude Include="include\Poco\Data\Extraction.h" />
|
||||
<ClInclude Include="include\Poco\Data\JSONFormatter.h" />
|
||||
<ClInclude Include="include\Poco\Data\Limit.h" />
|
||||
<ClInclude Include="include\Poco\Data\LOB.h" />
|
||||
<ClInclude Include="include\Poco\Data\LOBStream.h" />
|
||||
@@ -344,6 +345,7 @@
|
||||
<ClCompile Include="src\DataException.cpp" />
|
||||
<ClCompile Include="src\Date.cpp" />
|
||||
<ClCompile Include="src\DynamicLOB.cpp" />
|
||||
<ClCompile Include="src\JSONFormatter.cpp" />
|
||||
<ClCompile Include="src\Limit.cpp" />
|
||||
<ClCompile Include="src\MetaColumn.cpp" />
|
||||
<ClCompile Include="src\PooledSessionHolder.cpp" />
|
||||
|
||||
@@ -177,6 +177,9 @@
|
||||
<ClInclude Include="include\Poco\Data\SQLChannel.h">
|
||||
<Filter>Logging\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Data\JSONFormatter.h">
|
||||
<Filter>DataCore\Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\AbstractBinder.cpp">
|
||||
@@ -284,5 +287,8 @@
|
||||
<ClCompile Include="src\SQLChannel.cpp">
|
||||
<Filter>Logging\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\JSONFormatter.cpp">
|
||||
<Filter>DataCore\Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
62
Data/include/Poco/Data/JSONFormatter.h
Normal file
62
Data/include/Poco/Data/JSONFormatter.h
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// JSONFormatter.h
|
||||
//
|
||||
// $Id: //poco/Main/Data/include/Poco/Data/JSONFormatter.h#9 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: JSONFormatter
|
||||
//
|
||||
// Definition of the JSONFormatter class.
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef Data_JSONFormatter_INCLUDED
|
||||
#define Data_JSONFormatter_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
class Data_API JSONFormatter: public Poco::Data::RowFormatter
|
||||
/// Class for JSON formatting of data rows.
|
||||
{
|
||||
public:
|
||||
JSONFormatter();
|
||||
/// Creates a new JSONFormatter.
|
||||
|
||||
~JSONFormatter();
|
||||
/// Destroy the JSONFormatter.
|
||||
|
||||
std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames);
|
||||
std::string& formatValues(const ValueVec& vals, std::string& formattedValues);
|
||||
|
||||
private:
|
||||
NameVecPtr _pNames;
|
||||
int _rowCounter;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline std::string& JSONFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames)
|
||||
{
|
||||
// names are used in formatValues
|
||||
if (pNames && !_pNames) _pNames = pNames;
|
||||
return formattedNames = "";
|
||||
}
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
#endif // Data_JSONFormatter_INCLUDED
|
||||
84
Data/src/JSONFormatter.cpp
Normal file
84
Data/src/JSONFormatter.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// JSONFormatter.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/JSONFormatter.cpp#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: JSONFormatter
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/JSONFormatter.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/JSONString.h"
|
||||
#include "Poco/Format.h"
|
||||
|
||||
|
||||
using Poco::trimInPlace;
|
||||
using Poco::format;
|
||||
using Poco::toJSON;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
JSONFormatter::JSONFormatter() : _rowCounter(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
JSONFormatter::~JSONFormatter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::string& JSONFormatter::formatValues(const ValueVec& vals, std::string& formattedValues)
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
str << "{\"count\":" << getTotalRowCount() << ",\"rows\":[{";
|
||||
|
||||
std::string pref = str.str();
|
||||
if (prefix() != pref) setPrefix(pref);
|
||||
else
|
||||
{
|
||||
str.str("");
|
||||
str << ",{";
|
||||
}
|
||||
|
||||
if (postfix().empty()) setPostfix("]}");
|
||||
|
||||
ValueVec::const_iterator it = vals.begin();
|
||||
ValueVec::const_iterator end = vals.end();
|
||||
NameVec::iterator nIt = _pNames->begin();
|
||||
NameVec::iterator nEnd = _pNames->end();
|
||||
for (; it != end && nIt != nEnd; ++nIt)
|
||||
{
|
||||
if (!it->isEmpty())
|
||||
{
|
||||
if (it->isString())
|
||||
str << '"' << *nIt << "\":" <<
|
||||
toJSON(trimInPlace(it->convert<std::string>()));
|
||||
else
|
||||
str << '"' << *nIt << "\":" << it->convert<std::string>();
|
||||
}
|
||||
else
|
||||
str << '"' << *nIt << "\":null";
|
||||
|
||||
if (++it != end) str << ',';
|
||||
}
|
||||
|
||||
str << '}';
|
||||
++_rowCounter;
|
||||
return formattedValues = str.str();
|
||||
}
|
||||
|
||||
|
||||
} }// namespace Poco::Data
|
||||
@@ -392,6 +392,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release_static_mt|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\JSONString.cpp" />
|
||||
<ClCompile Include="src\Latin2Encoding.cpp" />
|
||||
<ClCompile Include="src\MemoryPool.cpp" />
|
||||
<ClCompile Include="src\NestedDiagnosticContext.cpp" />
|
||||
@@ -1055,6 +1056,7 @@
|
||||
<ClInclude Include="include\Poco\FPEnvironment_SUN.h" />
|
||||
<ClInclude Include="include\Poco\FPEnvironment_WIN32.h" />
|
||||
<ClInclude Include="include\Poco\Instantiator.h" />
|
||||
<ClInclude Include="include\Poco\JSONString.h" />
|
||||
<ClInclude Include="include\Poco\Latin2Encoding.h" />
|
||||
<ClInclude Include="include\Poco\ListMap.h" />
|
||||
<ClInclude Include="include\Poco\MemoryPool.h" />
|
||||
|
||||
@@ -930,6 +930,9 @@
|
||||
<ClCompile Include="src\UTF32Encoding.cpp">
|
||||
<Filter>Text\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\JSONString.cpp">
|
||||
<Filter>Core\Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\Poco\Any.h">
|
||||
@@ -1907,6 +1910,9 @@
|
||||
<ClInclude Include="include\Poco\PBKDF2Engine.h">
|
||||
<Filter>Crypt\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\JSONString.h">
|
||||
<Filter>Core\Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="src\pocomsg.rc">
|
||||
|
||||
48
Foundation/include/Poco/JSONString.h
Normal file
48
Foundation/include/Poco/JSONString.h
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// JSONString.h
|
||||
//
|
||||
// $Id: //poco/1.4/Foundation/include/Poco/JSONString.h#1 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: String
|
||||
//
|
||||
// JSONString utility functions.
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef Foundation_JSONString_INCLUDED
|
||||
#define Foundation_JSONString_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
std::string Foundation_API toJSON(char c);
|
||||
/// Utility function for escaping JSON characters.
|
||||
|
||||
|
||||
void Foundation_API toJSON(const std::string& value, std::ostream& out, bool wrap = true);
|
||||
/// Formats string value into the suplied output stream by
|
||||
/// escaping control characters.
|
||||
/// If wrap is true, the resulting string is enclosed in double quotes
|
||||
|
||||
|
||||
std::string Foundation_API toJSON(const std::string& value, bool wrap = true);
|
||||
/// Formats string value by escaping control characters.
|
||||
/// If wrap is true, the resulting string is enclosed in double quotes
|
||||
/// Returns formatted string.
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif // Foundation_JSONString_INCLUDED
|
||||
66
Foundation/src/JSONString.cpp
Normal file
66
Foundation/src/JSONString.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// String.h
|
||||
//
|
||||
// $Id: //poco/1.4/Foundation/src/String.cpp#1 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: String
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/JSONString.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
std::string toJSON(char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\\': return "\\\\";
|
||||
case '"': return "\\\"";
|
||||
case '/': return "\\/";
|
||||
case '\b': return "\\b";
|
||||
case '\f': return "\\f";
|
||||
case '\n': return "\\n";
|
||||
case '\r': return "\\r";
|
||||
case '\t': return "\\t";
|
||||
default: return std::string(1, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void toJSON(const std::string& value, std::ostream& out, bool wrap)
|
||||
{
|
||||
if (wrap) out << '"';
|
||||
for (std::string::const_iterator it = value.begin(),
|
||||
end = value.end(); it != end; ++it)
|
||||
{
|
||||
out << toJSON(*it);
|
||||
}
|
||||
if (wrap) out << '"';
|
||||
}
|
||||
|
||||
|
||||
std::string toJSON(const std::string& value, bool wrap)
|
||||
{
|
||||
std::string ret;
|
||||
if (wrap) ret.append(1, '"');
|
||||
for (std::string::const_iterator it = value.begin(),
|
||||
end = value.end(); it != end; ++it)
|
||||
{
|
||||
ret.append(toJSON(*it));
|
||||
}
|
||||
if (wrap) ret.append(1, '"');
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "Poco/Dynamic/VarHolder.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/JSONString.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -41,33 +42,7 @@ void escape(std::string& target, const std::string& source)
|
||||
std::string::const_iterator end(source.end());
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case '"':
|
||||
target += "\\\"";
|
||||
break;
|
||||
case '\\':
|
||||
target += "\\\\";
|
||||
break;
|
||||
case '\b':
|
||||
target += "\\b";
|
||||
break;
|
||||
case '\f':
|
||||
target += "\\f";
|
||||
break;
|
||||
case '\n':
|
||||
target += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
target += "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
target += "\\t";
|
||||
break;
|
||||
default:
|
||||
target += *it;
|
||||
break;
|
||||
}
|
||||
target.append(Poco::toJSON(*it));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ void HMACEngineTest::testHMAC()
|
||||
digest = DigestEngine::digestToHex(hmac2.digest());
|
||||
assert (digest == "750c783e6ab0b503eaa86e310a5db738");
|
||||
|
||||
key = std::string(16, 0xaa);
|
||||
data = std::string(50, 0xdd);
|
||||
key = std::string(16, char(0xaa));
|
||||
data = std::string(50, char(0xdd));
|
||||
HMACEngine<MD5Engine> hmac3(key);
|
||||
hmac3.update(data);
|
||||
digest = DigestEngine::digestToHex(hmac3.digest());
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
#include "CppUnit/TestCaller.h"
|
||||
#include "CppUnit/TestSuite.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/JSONString.h"
|
||||
#include "Poco/Format.h"
|
||||
#include "Poco/MemoryStream.h"
|
||||
#include "Poco/Stopwatch.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
@@ -55,6 +57,7 @@ using Poco::doubleToStr;
|
||||
using Poco::thousandSeparator;
|
||||
using Poco::decimalSeparator;
|
||||
using Poco::format;
|
||||
using Poco::toJSON;
|
||||
using Poco::CILess;
|
||||
using Poco::MemoryInputStream;
|
||||
using Poco::Stopwatch;
|
||||
@@ -1081,6 +1084,56 @@ void StringTest::benchmarkFloatToStr()
|
||||
}
|
||||
|
||||
|
||||
void StringTest::testJSONString()
|
||||
{
|
||||
assert (toJSON('\\') == "\\\\");
|
||||
assert (toJSON('"') == "\\\"");
|
||||
assert (toJSON('/') == "\\/");
|
||||
assert (toJSON('\b') == "\\b");
|
||||
assert (toJSON('\f') == "\\f");
|
||||
assert (toJSON('\n') == "\\n");
|
||||
assert (toJSON('\r') == "\\r");
|
||||
assert (toJSON('\t') == "\\t");
|
||||
assert (toJSON('a') == "a");
|
||||
|
||||
// ??? on MSVC, the assert macro expansion
|
||||
// fails to compile when this string is inline ???
|
||||
std::string str = "\"foo\\\\\"";
|
||||
assert (toJSON("foo\\") == str);
|
||||
|
||||
assert (toJSON("bar/") == "\"bar\\/\"");
|
||||
assert (toJSON("baz") == "\"baz\"");
|
||||
assert (toJSON("q\"uote\"d") == "\"q\\\"uote\\\"d\"");
|
||||
assert (toJSON("bs\b") == "\"bs\\b\"");
|
||||
assert (toJSON("nl\n") == "\"nl\\n\"");
|
||||
assert (toJSON("tb\t") == "\"tb\\t\"");
|
||||
|
||||
std::ostringstream ostr;
|
||||
toJSON("foo\\", ostr);
|
||||
assert(ostr.str() == str);
|
||||
ostr.str("");
|
||||
|
||||
toJSON("foo\\", ostr);
|
||||
assert(toJSON("bar/") == "\"bar\\/\"");
|
||||
ostr.str("");
|
||||
toJSON("baz", ostr);
|
||||
assert(ostr.str() == "\"baz\"");
|
||||
ostr.str("");
|
||||
toJSON("q\"uote\"d", ostr);
|
||||
assert(ostr.str() == "\"q\\\"uote\\\"d\"");
|
||||
ostr.str("");
|
||||
toJSON("bs\b", ostr);
|
||||
assert(ostr.str() == "\"bs\\b\"");
|
||||
ostr.str("");
|
||||
toJSON("nl\n", ostr);
|
||||
assert(ostr.str() == "\"nl\\n\"");
|
||||
ostr.str("");
|
||||
toJSON("tb\t", ostr);
|
||||
assert(ostr.str() == "\"tb\\t\"");
|
||||
ostr.str("");
|
||||
}
|
||||
|
||||
|
||||
void StringTest::setUp()
|
||||
{
|
||||
}
|
||||
@@ -1121,6 +1174,7 @@ CppUnit::Test* StringTest::suite()
|
||||
CppUnit_addTest(pSuite, StringTest, testIntToString);
|
||||
CppUnit_addTest(pSuite, StringTest, testFloatToString);
|
||||
//CppUnit_addTest(pSuite, StringTest, benchmarkFloatToStr);
|
||||
CppUnit_addTest(pSuite, StringTest, testJSONString);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
void testFloatToString();
|
||||
void benchmarkFloatToStr();
|
||||
|
||||
void testJSONString();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include "Poco/JSON/Array.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSONString.h"
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
@@ -69,24 +70,7 @@ void Stringifier::stringify(const Var& any, std::ostream& out, unsigned int inde
|
||||
|
||||
void Stringifier::formatString(const std::string& value, std::ostream& out)
|
||||
{
|
||||
out << '"';
|
||||
for (std::string::const_iterator it = value.begin(),
|
||||
end = value.end(); it != end; ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case '\\': out << "\\\\"; break;
|
||||
case '"': out << "\\\""; break;
|
||||
case '/': out << "\\/"; break;
|
||||
case '\b': out << "\\b"; break;
|
||||
case '\f': out << "\\f"; break;
|
||||
case '\n': out << "\\n"; break;
|
||||
case '\r': out << "\\r"; break;
|
||||
case '\t': out << "\\t"; break;
|
||||
default: out << *it; break;
|
||||
}
|
||||
}
|
||||
out << '"';
|
||||
Poco::toJSON(value, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user