GH #119: JSON::Object holds values in ordered map

- fixed GH #119: JSON::Object holds values in ordered map
- added PrintHandler
- renamed DefaultHandler to ParseHandler
- redefined DefaultHandler as typedef to ParseHandler
This commit is contained in:
aleks-f
2013-03-16 11:33:27 -05:00
parent fe6715890c
commit 42ff341cb9
34 changed files with 1249 additions and 328 deletions

View File

@@ -23,6 +23,10 @@ Release 1.5.2 (2013-03-??)
- added ListMap (map-like container with preserving insertion order) - added ListMap (map-like container with preserving insertion order)
- MailMessage: attachments saving support and consistent read/write - MailMessage: attachments saving support and consistent read/write
- fixed GH #124: Possibile buffer overrun in Foundation/EventLogChannel - fixed GH #124: Possibile buffer overrun in Foundation/EventLogChannel
- fixed GH #119: JSON::Object holds values in ordered map
- added PrintHandler
- renamed DefaultHandler to ParseHandler
- redefined DefaultHandler as typedef to ParseHandler
Release 1.5.1 (2013-01-11) Release 1.5.1 (2013-01-11)
========================== ==========================

View File

@@ -247,4 +247,11 @@
#endif #endif
#if defined(POCO_OS_FAMILY_WINDOWS)
#define POCO_DEFAULT_NEWLINE_CHARS "\r\n"
#else
#define POCO_DEFAULT_NEWLINE_CHARS "\n"
#endif
#endif // Foundation_Platform_INCLUDED #endif // Foundation_Platform_INCLUDED

View File

@@ -40,13 +40,6 @@
namespace Poco { namespace Poco {
#if defined(_WIN32)
#define POCO_DEFAULT_NEWLINE_CHARS "\r\n"
#else
#define POCO_DEFAULT_NEWLINE_CHARS "\n"
#endif
const std::string LineEnding::NEWLINE_DEFAULT(POCO_DEFAULT_NEWLINE_CHARS); const std::string LineEnding::NEWLINE_DEFAULT(POCO_DEFAULT_NEWLINE_CHARS);
const std::string LineEnding::NEWLINE_CR("\r"); const std::string LineEnding::NEWLINE_CR("\r");
const std::string LineEnding::NEWLINE_CRLF("\r\n"); const std::string LineEnding::NEWLINE_CRLF("\r\n");

View File

@@ -433,7 +433,7 @@
<File <File
RelativePath=".\src\Array.cpp"/> RelativePath=".\src\Array.cpp"/>
<File <File
RelativePath=".\src\DefaultHandler.cpp"/> RelativePath=".\src\ParseHandler.cpp"/>
<File <File
RelativePath=".\src\Handler.cpp"/> RelativePath=".\src\Handler.cpp"/>
<File <File
@@ -442,6 +442,8 @@
RelativePath=".\src\Object.cpp"/> RelativePath=".\src\Object.cpp"/>
<File <File
RelativePath=".\src\Parser.cpp"/> RelativePath=".\src\Parser.cpp"/>
<File
RelativePath=".\src\PrintHandler.cpp"/>
<File <File
RelativePath=".\src\Query.cpp"/> RelativePath=".\src\Query.cpp"/>
<File <File
@@ -467,6 +469,10 @@
RelativePath=".\include\Poco\JSON\Object.h"/> RelativePath=".\include\Poco\JSON\Object.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Parser.h"/> RelativePath=".\include\Poco\JSON\Parser.h"/>
<File
RelativePath=".\include\Poco\JSON\ParseHandler.h"/>
<File
RelativePath=".\include\Poco\JSON\PrintHandler.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Query.h"/> RelativePath=".\include\Poco\JSON\Query.h"/>
<File <File

View File

@@ -273,7 +273,9 @@
<ClInclude Include="include\Poco\JSON\JSON.h" /> <ClInclude Include="include\Poco\JSON\JSON.h" />
<ClInclude Include="include\Poco\JSON\JSONException.h" /> <ClInclude Include="include\Poco\JSON\JSONException.h" />
<ClInclude Include="include\Poco\JSON\Object.h" /> <ClInclude Include="include\Poco\JSON\Object.h" />
<ClInclude Include="include\Poco\JSON\ParseHandler.h" />
<ClInclude Include="include\Poco\JSON\Parser.h" /> <ClInclude Include="include\Poco\JSON\Parser.h" />
<ClInclude Include="include\Poco\JSON\PrintHandler.h" />
<ClInclude Include="include\Poco\JSON\Query.h" /> <ClInclude Include="include\Poco\JSON\Query.h" />
<ClInclude Include="include\Poco\JSON\Stringifier.h" /> <ClInclude Include="include\Poco\JSON\Stringifier.h" />
<ClInclude Include="include\Poco\JSON\Template.h" /> <ClInclude Include="include\Poco\JSON\Template.h" />
@@ -281,11 +283,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Array.cpp" /> <ClCompile Include="src\Array.cpp" />
<ClCompile Include="src\DefaultHandler.cpp" /> <ClCompile Include="src\ParseHandler.cpp" />
<ClCompile Include="src\Handler.cpp" /> <ClCompile Include="src\Handler.cpp" />
<ClCompile Include="src\JSONException.cpp" /> <ClCompile Include="src\JSONException.cpp" />
<ClCompile Include="src\Object.cpp" /> <ClCompile Include="src\Object.cpp" />
<ClCompile Include="src\Parser.cpp" /> <ClCompile Include="src\Parser.cpp" />
<ClCompile Include="src\PrintHandler.cpp" />
<ClCompile Include="src\Query.cpp" /> <ClCompile Include="src\Query.cpp" />
<ClCompile Include="src\Stringifier.cpp" /> <ClCompile Include="src\Stringifier.cpp" />
<ClCompile Include="src\Template.cpp" /> <ClCompile Include="src\Template.cpp" />

View File

@@ -42,14 +42,17 @@
<ClInclude Include="include\Poco\JSON\TemplateCache.h"> <ClInclude Include="include\Poco\JSON\TemplateCache.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="include\Poco\JSON\PrintHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\Poco\JSON\ParseHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Array.cpp"> <ClCompile Include="src\Array.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\DefaultHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Handler.cpp"> <ClCompile Include="src\Handler.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -74,5 +77,11 @@
<ClCompile Include="src\TemplateCache.cpp"> <ClCompile Include="src\TemplateCache.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\PrintHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ParseHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -274,11 +274,12 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Array.cpp"/> <ClCompile Include="src\Array.cpp"/>
<ClCompile Include="src\DefaultHandler.cpp"/> <ClCompile Include="src\ParseHandler.cpp"/>
<ClCompile Include="src\Handler.cpp"/> <ClCompile Include="src\Handler.cpp"/>
<ClCompile Include="src\JSONException.cpp"/> <ClCompile Include="src\JSONException.cpp"/>
<ClCompile Include="src\Object.cpp"/> <ClCompile Include="src\Object.cpp"/>
<ClCompile Include="src\Parser.cpp"/> <ClCompile Include="src\Parser.cpp"/>
<ClCompile Include="src\PrintHandler.cpp"/>
<ClCompile Include="src\Query.cpp"/> <ClCompile Include="src\Query.cpp"/>
<ClCompile Include="src\Stringifier.cpp"/> <ClCompile Include="src\Stringifier.cpp"/>
<ClCompile Include="src\Template.cpp"/> <ClCompile Include="src\Template.cpp"/>
@@ -292,6 +293,8 @@
<ClInclude Include="include\Poco\JSON\JSONException.h"/> <ClInclude Include="include\Poco\JSON\JSONException.h"/>
<ClInclude Include="include\Poco\JSON\Object.h"/> <ClInclude Include="include\Poco\JSON\Object.h"/>
<ClInclude Include="include\Poco\JSON\Parser.h"/> <ClInclude Include="include\Poco\JSON\Parser.h"/>
<ClInclude Include="include\Poco\JSON\ParseHandler.h"/>
<ClInclude Include="include\Poco\JSON\PrintHandler.h"/>
<ClInclude Include="include\Poco\JSON\Query.h"/> <ClInclude Include="include\Poco\JSON\Query.h"/>
<ClInclude Include="include\Poco\JSON\Stringifier.h"/> <ClInclude Include="include\Poco\JSON\Stringifier.h"/>
<ClInclude Include="include\Poco\JSON\Template.h"/> <ClInclude Include="include\Poco\JSON\Template.h"/>

View File

@@ -12,7 +12,7 @@
<ClCompile Include="src\Array.cpp"> <ClCompile Include="src\Array.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\DefaultHandler.cpp"> <ClCompile Include="src\ParseHandler.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Handler.cpp"> <ClCompile Include="src\Handler.cpp">
@@ -27,6 +27,9 @@
<ClCompile Include="src\Parser.cpp"> <ClCompile Include="src\Parser.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\PrintHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Query.cpp"> <ClCompile Include="src\Query.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -62,6 +65,12 @@
<ClInclude Include="include\Poco\JSON\Parser.h"> <ClInclude Include="include\Poco\JSON\Parser.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </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>
<ClInclude Include="include\Poco\JSON\Query.h"> <ClInclude Include="include\Poco\JSON\Query.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@@ -365,7 +365,7 @@
<File <File
RelativePath=".\src\Array.cpp"/> RelativePath=".\src\Array.cpp"/>
<File <File
RelativePath=".\src\DefaultHandler.cpp"/> RelativePath=".\src\ParseHandler.cpp"/>
<File <File
RelativePath=".\src\Handler.cpp"/> RelativePath=".\src\Handler.cpp"/>
<File <File
@@ -374,6 +374,8 @@
RelativePath=".\src\Object.cpp"/> RelativePath=".\src\Object.cpp"/>
<File <File
RelativePath=".\src\Parser.cpp"/> RelativePath=".\src\Parser.cpp"/>
<File
RelativePath=".\src\PrintHandler.cpp"/>
<File <File
RelativePath=".\src\Query.cpp"/> RelativePath=".\src\Query.cpp"/>
<File <File
@@ -399,6 +401,10 @@
RelativePath=".\include\Poco\JSON\Object.h"/> RelativePath=".\include\Poco\JSON\Object.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Parser.h"/> RelativePath=".\include\Poco\JSON\Parser.h"/>
<File
RelativePath=".\include\Poco\JSON\ParseHandler.h"/>
<File
RelativePath=".\include\Poco\JSON\PrintHandler.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Query.h"/> RelativePath=".\include\Poco\JSON\Query.h"/>
<File <File

View File

@@ -386,7 +386,7 @@
<File <File
RelativePath=".\src\Array.cpp"/> RelativePath=".\src\Array.cpp"/>
<File <File
RelativePath=".\src\DefaultHandler.cpp"/> RelativePath=".\src\ParseHandler.cpp"/>
<File <File
RelativePath=".\src\Handler.cpp"/> RelativePath=".\src\Handler.cpp"/>
<File <File
@@ -395,6 +395,8 @@
RelativePath=".\src\Object.cpp"/> RelativePath=".\src\Object.cpp"/>
<File <File
RelativePath=".\src\Parser.cpp"/> RelativePath=".\src\Parser.cpp"/>
<File
RelativePath=".\src\PrintHandler.cpp"/>
<File <File
RelativePath=".\src\Query.cpp"/> RelativePath=".\src\Query.cpp"/>
<File <File
@@ -420,6 +422,10 @@
RelativePath=".\include\Poco\JSON\Object.h"/> RelativePath=".\include\Poco\JSON\Object.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Parser.h"/> RelativePath=".\include\Poco\JSON\Parser.h"/>
<File
RelativePath=".\include\Poco\JSON\ParseHandler.h"/>
<File
RelativePath=".\include\Poco\JSON\PrintHandler.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Query.h"/> RelativePath=".\include\Poco\JSON\Query.h"/>
<File <File

View File

@@ -385,7 +385,7 @@
<File <File
RelativePath=".\src\Array.cpp"/> RelativePath=".\src\Array.cpp"/>
<File <File
RelativePath=".\src\DefaultHandler.cpp"/> RelativePath=".\src\ParseHandler.cpp"/>
<File <File
RelativePath=".\src\Handler.cpp"/> RelativePath=".\src\Handler.cpp"/>
<File <File
@@ -394,6 +394,8 @@
RelativePath=".\src\Object.cpp"/> RelativePath=".\src\Object.cpp"/>
<File <File
RelativePath=".\src\Parser.cpp"/> RelativePath=".\src\Parser.cpp"/>
<File
RelativePath=".\src\PrintHandler.cpp"/>
<File <File
RelativePath=".\src\Query.cpp"/> RelativePath=".\src\Query.cpp"/>
<File <File
@@ -419,6 +421,10 @@
RelativePath=".\include\Poco\JSON\Object.h"/> RelativePath=".\include\Poco\JSON\Object.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Parser.h"/> RelativePath=".\include\Poco\JSON\Parser.h"/>
<File
RelativePath=".\include\Poco\JSON\ParseHandler.h"/>
<File
RelativePath=".\include\Poco\JSON\PrintHandler.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Query.h"/> RelativePath=".\include\Poco\JSON\Query.h"/>
<File <File

View File

@@ -272,11 +272,12 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Array.cpp"/> <ClCompile Include="src\Array.cpp"/>
<ClCompile Include="src\DefaultHandler.cpp"/> <ClCompile Include="src\ParseHandler.cpp"/>
<ClCompile Include="src\Handler.cpp"/> <ClCompile Include="src\Handler.cpp"/>
<ClCompile Include="src\JSONException.cpp"/> <ClCompile Include="src\JSONException.cpp"/>
<ClCompile Include="src\Object.cpp"/> <ClCompile Include="src\Object.cpp"/>
<ClCompile Include="src\Parser.cpp"/> <ClCompile Include="src\Parser.cpp"/>
<ClCompile Include="src\PrintHandler.cpp"/>
<ClCompile Include="src\Query.cpp"/> <ClCompile Include="src\Query.cpp"/>
<ClCompile Include="src\Stringifier.cpp"/> <ClCompile Include="src\Stringifier.cpp"/>
<ClCompile Include="src\Template.cpp"/> <ClCompile Include="src\Template.cpp"/>
@@ -290,6 +291,8 @@
<ClInclude Include="include\Poco\JSON\JSONException.h"/> <ClInclude Include="include\Poco\JSON\JSONException.h"/>
<ClInclude Include="include\Poco\JSON\Object.h"/> <ClInclude Include="include\Poco\JSON\Object.h"/>
<ClInclude Include="include\Poco\JSON\Parser.h"/> <ClInclude Include="include\Poco\JSON\Parser.h"/>
<ClInclude Include="include\Poco\JSON\ParseHandler.h"/>
<ClInclude Include="include\Poco\JSON\PrintHandler.h"/>
<ClInclude Include="include\Poco\JSON\Query.h"/> <ClInclude Include="include\Poco\JSON\Query.h"/>
<ClInclude Include="include\Poco\JSON\Stringifier.h"/> <ClInclude Include="include\Poco\JSON\Stringifier.h"/>
<ClInclude Include="include\Poco\JSON\Template.h"/> <ClInclude Include="include\Poco\JSON\Template.h"/>

View File

@@ -12,7 +12,7 @@
<ClCompile Include="src\Array.cpp"> <ClCompile Include="src\Array.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\DefaultHandler.cpp"> <ClCompile Include="src\ParseHandler.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Handler.cpp"> <ClCompile Include="src\Handler.cpp">
@@ -27,6 +27,9 @@
<ClCompile Include="src\Parser.cpp"> <ClCompile Include="src\Parser.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\PrintHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Query.cpp"> <ClCompile Include="src\Query.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -62,6 +65,12 @@
<ClInclude Include="include\Poco\JSON\Parser.h"> <ClInclude Include="include\Poco\JSON\Parser.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </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>
<ClInclude Include="include\Poco\JSON\Query.h"> <ClInclude Include="include\Poco\JSON\Query.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@@ -272,11 +272,12 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Array.cpp"/> <ClCompile Include="src\Array.cpp"/>
<ClCompile Include="src\DefaultHandler.cpp"/> <ClCompile Include="src\ParseHandler.cpp"/>
<ClCompile Include="src\Handler.cpp"/> <ClCompile Include="src\Handler.cpp"/>
<ClCompile Include="src\JSONException.cpp"/> <ClCompile Include="src\JSONException.cpp"/>
<ClCompile Include="src\Object.cpp"/> <ClCompile Include="src\Object.cpp"/>
<ClCompile Include="src\Parser.cpp"/> <ClCompile Include="src\Parser.cpp"/>
<ClCompile Include="src\PrintHandler.cpp"/>
<ClCompile Include="src\Query.cpp"/> <ClCompile Include="src\Query.cpp"/>
<ClCompile Include="src\Stringifier.cpp"/> <ClCompile Include="src\Stringifier.cpp"/>
<ClCompile Include="src\Template.cpp"/> <ClCompile Include="src\Template.cpp"/>
@@ -290,6 +291,8 @@
<ClInclude Include="include\Poco\JSON\JSONException.h"/> <ClInclude Include="include\Poco\JSON\JSONException.h"/>
<ClInclude Include="include\Poco\JSON\Object.h"/> <ClInclude Include="include\Poco\JSON\Object.h"/>
<ClInclude Include="include\Poco\JSON\Parser.h"/> <ClInclude Include="include\Poco\JSON\Parser.h"/>
<ClInclude Include="include\Poco\JSON\ParseHandler.h"/>
<ClInclude Include="include\Poco\JSON\PrintHandler.h"/>
<ClInclude Include="include\Poco\JSON\Query.h"/> <ClInclude Include="include\Poco\JSON\Query.h"/>
<ClInclude Include="include\Poco\JSON\Stringifier.h"/> <ClInclude Include="include\Poco\JSON\Stringifier.h"/>
<ClInclude Include="include\Poco\JSON\Template.h"/> <ClInclude Include="include\Poco\JSON\Template.h"/>

View File

@@ -12,7 +12,7 @@
<ClCompile Include="src\Array.cpp"> <ClCompile Include="src\Array.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\DefaultHandler.cpp"> <ClCompile Include="src\ParseHandler.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Handler.cpp"> <ClCompile Include="src\Handler.cpp">
@@ -27,6 +27,9 @@
<ClCompile Include="src\Parser.cpp"> <ClCompile Include="src\Parser.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\PrintHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Query.cpp"> <ClCompile Include="src\Query.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -62,6 +65,12 @@
<ClInclude Include="include\Poco\JSON\Parser.h"> <ClInclude Include="include\Poco\JSON\Parser.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </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>
<ClInclude Include="include\Poco\JSON\Query.h"> <ClInclude Include="include\Poco\JSON\Query.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@@ -390,7 +390,7 @@
<File <File
RelativePath=".\src\Array.cpp"/> RelativePath=".\src\Array.cpp"/>
<File <File
RelativePath=".\src\DefaultHandler.cpp"/> RelativePath=".\src\ParseHandler.cpp"/>
<File <File
RelativePath=".\src\Handler.cpp"/> RelativePath=".\src\Handler.cpp"/>
<File <File
@@ -399,6 +399,8 @@
RelativePath=".\src\Object.cpp"/> RelativePath=".\src\Object.cpp"/>
<File <File
RelativePath=".\src\Parser.cpp"/> RelativePath=".\src\Parser.cpp"/>
<File
RelativePath=".\src\PrintHandler.cpp"/>
<File <File
RelativePath=".\src\Query.cpp"/> RelativePath=".\src\Query.cpp"/>
<File <File
@@ -424,6 +426,10 @@
RelativePath=".\include\Poco\JSON\Object.h"/> RelativePath=".\include\Poco\JSON\Object.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Parser.h"/> RelativePath=".\include\Poco\JSON\Parser.h"/>
<File
RelativePath=".\include\Poco\JSON\ParseHandler.h"/>
<File
RelativePath=".\include\Poco\JSON\PrintHandler.h"/>
<File <File
RelativePath=".\include\Poco\JSON\Query.h"/> RelativePath=".\include\Poco\JSON\Query.h"/>
<File <File

View File

@@ -11,7 +11,7 @@ include $(POCO_BASE)/build/rules/global
INCLUDE += -I $(POCO_BASE)/JSON/include/Poco/JSON INCLUDE += -I $(POCO_BASE)/JSON/include/Poco/JSON
objects = Array Object Parser Handler \ objects = Array Object Parser Handler \
Stringifier DefaultHandler Query JSONException \ Stringifier ParseHandler Query JSONException \
Template TemplateCache Template TemplateCache
target = PocoJSON target = PocoJSON

View File

@@ -137,9 +137,9 @@ public:
void add(const Dynamic::Var& value); void add(const Dynamic::Var& value);
/// Add the given value to the array /// Add the given value to the array
void stringify(std::ostream& out, unsigned int indent) const; void stringify(std::ostream& out, unsigned int indent = 0, int step = -1) const;
/// Prints the array to out. When indent is 0, the array /// Prints the array to out. When indent has zero value,
/// will be printed on one line without indentation. /// the array will be printed without newline breaks and spaces between elements.
void remove(unsigned int index); void remove(unsigned int index);
/// Removes the element on the given index. /// Removes the element on the given index.

View File

@@ -40,137 +40,15 @@
#define JSON_DefaultHandler_INCLUDED #define JSON_DefaultHandler_INCLUDED
#include "Poco/JSON/Handler.h" #include "Poco/JSON/ParseHandler.h"
#include <stack>
namespace Poco { namespace Poco {
namespace JSON { namespace JSON {
class JSON_API DefaultHandler : public Handler //@deprecated
/// Provides a default handler for the JSON parser. typedef ParseHandler DefaultHandler;
/// This handler will build up an object or array based
/// on the handlers called by the parser.
{
public:
DefaultHandler();
/// Default Constructor
virtual ~DefaultHandler();
/// Destructor
void startObject();
/// Handles a {, meaning a new object will be read
void endObject();
/// Handles a }, meaning the object is read
void startArray();
/// Handles a [, meaning a new array will be read
void endArray();
/// Handles a ], meaning the array is read
void key(const std::string& k);
/// A key is read
Dynamic::Var result() const;
/// Returns the result of the parser. Which is an object or an array.
virtual void value(int v);
/// An integer value is read
virtual void value(unsigned v);
/// An unsigned value is read. This will only be triggered if the
/// value cannot fit into a signed int.
#if defined(POCO_HAVE_INT64)
virtual void value(Int64 v);
/// A 64-bit integer value is read
virtual void value(UInt64 v);
/// An unsigned 64-bit integer value is read. This will only be
/// triggered if the value cannot fit into a signed 64-bit integer.
#endif
virtual void value(const std::string& s);
/// A string value is read.
virtual void value(double d);
/// A double value is read
virtual void value(bool b);
/// A boolean value is read
virtual void null();
/// A null value is read
private:
void setValue(const Poco::Dynamic::Var& value);
std::stack<Dynamic::Var> _stack;
std::string _key;
Dynamic::Var _result;
};
inline Dynamic::Var DefaultHandler::result() const
{
return _result;
}
inline void DefaultHandler::value(int v)
{
setValue(v);
}
inline void DefaultHandler::value(unsigned v)
{
setValue(v);
}
#if defined(POCO_HAVE_INT64)
inline void DefaultHandler::value(Int64 v)
{
setValue(v);
}
inline void DefaultHandler::value(UInt64 v)
{
setValue(v);
}
#endif
inline void DefaultHandler::value(const std::string& s)
{
setValue(s);
}
inline void DefaultHandler::value(double d)
{
setValue(d);
}
inline void DefaultHandler::value(bool b)
{
setValue(b);
}
inline void DefaultHandler::null()
{
Poco::Dynamic::Var empty;
setValue(empty);
}
}} // namespace Poco::JSON }} // namespace Poco::JSON

View File

@@ -51,6 +51,9 @@ namespace JSON {
class JSON_API Handler class JSON_API Handler
{ {
public: public:
Handler();
/// Constructor;
virtual void startObject() = 0; virtual void startObject() = 0;
/// The parser has read a {, meaning a new object will be read /// The parser has read a {, meaning a new object will be read
@@ -74,7 +77,7 @@ public:
virtual void value(unsigned v) = 0; virtual void value(unsigned v) = 0;
/// An unsigned value is read. This will only be triggered if the /// An unsigned value is read. This will only be triggered if the
/// value cannot fit into a signed int. /// value cannot fit into a signed int.
#if defined(POCO_HAVE_INT64) #if defined(POCO_HAVE_INT64)
virtual void value(Int64 v) = 0; virtual void value(Int64 v) = 0;
@@ -82,7 +85,7 @@ public:
virtual void value(UInt64 v) = 0; virtual void value(UInt64 v) = 0;
/// An unsigned 64-bit integer value is read. This will only be /// An unsigned 64-bit integer value is read. This will only be
/// triggered if the value cannot fit into a signed 64-bit integer. /// triggered if the value cannot fit into a signed 64-bit integer.
#endif #endif
virtual void value(const std::string& value) = 0; virtual void value(const std::string& value) = 0;
@@ -94,6 +97,9 @@ public:
virtual void value(bool b) = 0; virtual void value(bool b) = 0;
/// A boolean value is read /// A boolean value is read
virtual void comma();
/// A comma is read
protected: protected:
virtual ~Handler(); virtual ~Handler();

View File

@@ -46,6 +46,7 @@
#include "Poco/Dynamic/Var.h" #include "Poco/Dynamic/Var.h"
#include <map> #include <map>
#include <vector> #include <vector>
#include <deque>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@@ -60,8 +61,10 @@ class JSON_API Object
public: public:
typedef SharedPtr<Object> Ptr; typedef SharedPtr<Object> Ptr;
Object(); Object(bool preserveInsertionOrder = false);
/// Default constructor /// Default constructor. If preserveInsertionOrder, object
/// will preserve the items insertion order. Otherwise, items
/// will be sorted by keys.
Object(const Object& copy); Object(const Object& copy);
/// Copy constructor /// Copy constructor
@@ -138,17 +141,55 @@ public:
void set(const std::string& key, const Dynamic::Var& value); void set(const std::string& key, const Dynamic::Var& value);
/// Sets a new value /// Sets a new value
void stringify(std::ostream& out, unsigned int indent = 0) const; void stringify(std::ostream& out, unsigned int indent = 0, int step = -1) const;
/// Prints the object to out. When indent is 0, the object /// Prints the object to out. When indent is 0, the object
/// will be printed on one line without indentation. /// will be printed on a single line without indentation.
void remove(const std::string& key); void remove(const std::string& key);
/// Removes the property with the given key /// Removes the property with the given key
private: private:
//TODO: unordered map
template <typename C>
void doStringify(const C& container, std::ostream& out, unsigned int indent, int step) const
{
out << '{';
if (indent > 0) out << std::endl;
for (C::const_iterator it = container.begin(); it != container.end();)
{
for(int i = 0; i < indent; i++) out << ' ';
out << '"' << getKey(it) << '"';
out << ((indent > 0) ? " : " : ":");
Stringifier::stringify(getValue(it), out, indent + step, step);
if ( ++it != container.end() ) out << ',';
if (step > 0) out << '\n';
}
if (indent >= step) indent -= step;
for (int i = 0; i < indent; i++)
out << ' ';
out << '}';
}
typedef std::map<std::string, Dynamic::Var> ValueMap; typedef std::map<std::string, Dynamic::Var> ValueMap;
ValueMap _values; typedef std::deque<Dynamic::Var*> KeyPtrList;
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;
}; };
@@ -180,12 +221,6 @@ inline bool Object::isObject(const std::string& key) const
} }
inline void Object::set(const std::string& key, const Dynamic::Var& value)
{
_values[key] = value;
}
inline std::size_t Object::size() const inline std::size_t Object::size() const
{ {
return static_cast<std::size_t>(_values.size()); return static_cast<std::size_t>(_values.size());
@@ -198,6 +233,24 @@ inline void Object::remove(const std::string& key)
} }
inline const std::string& Object::getKey(ValueMap::const_iterator& it) const
{
return it->first;
}
inline const Dynamic::Var& Object::getValue(ValueMap::const_iterator& it) const
{
return it->second;
}
inline const Dynamic::Var& Object::getValue(KeyPtrList::const_iterator& it) const
{
return **it;
}
}} // Namespace Poco::JSON }} // Namespace Poco::JSON

View File

@@ -0,0 +1,181 @@
//
// ParseHandler.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: ParseHandler
//
// Definition of the ParseHandler class.
//
// Copyright (c) 2012, 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 JSON_ParseHandler_INCLUDED
#define JSON_ParseHandler_INCLUDED
#include "Poco/JSON/Handler.h"
#include <stack>
namespace Poco {
namespace JSON {
class JSON_API ParseHandler : public Handler
/// Provides a default handler for the JSON parser.
/// This handler will build up an object or array based
/// on the handlers called by the parser.
{
public:
ParseHandler(bool preserveObjectOrder = false);
/// Creates the ParseHandler.
virtual ~ParseHandler();
/// Destroys the ParseHandler.
void startObject();
/// Handles a '{'; a new object is started.
void endObject();
/// Handles a '}'; the object is closed.
void startArray();
/// Handles a '['; a new array is started.
void endArray();
/// Handles a ']'; the array is closed.
void key(const std::string& k);
/// A key is read
Dynamic::Var result() const;
/// Returns the result of the parser (an object or an array).
virtual void value(int v);
/// An integer value is read
virtual void value(unsigned v);
/// An unsigned value is read. This will only be triggered if the
/// value cannot fit into a signed int.
#if defined(POCO_HAVE_INT64)
virtual void value(Int64 v);
/// A 64-bit integer value is read
virtual void value(UInt64 v);
/// An unsigned 64-bit integer value is read. This will only be
/// triggered if the value cannot fit into a signed 64-bit integer.
#endif
virtual void value(const std::string& s);
/// A string value is read.
virtual void value(double d);
/// A double value is read.
virtual void value(bool b);
/// A boolean value is read.
virtual void null();
/// A null value is read.
private:
void setValue(const Poco::Dynamic::Var& value);
typedef std::stack<Dynamic::Var> Stack;
Stack _stack;
std::string _key;
Dynamic::Var _result;
bool _preserveObjectOrder;
};
inline Dynamic::Var ParseHandler::result() const
{
return _result;
}
inline void ParseHandler::value(int v)
{
setValue(v);
}
inline void ParseHandler::value(unsigned v)
{
setValue(v);
}
#if defined(POCO_HAVE_INT64)
inline void ParseHandler::value(Int64 v)
{
setValue(v);
}
inline void ParseHandler::value(UInt64 v)
{
setValue(v);
}
#endif
inline void ParseHandler::value(const std::string& s)
{
setValue(s);
}
inline void ParseHandler::value(double d)
{
setValue(d);
}
inline void ParseHandler::value(bool b)
{
setValue(b);
}
inline void ParseHandler::null()
{
Poco::Dynamic::Var empty;
setValue(empty);
}
}} // namespace Poco::JSON
#endif // JSON_ParseHandler_INCLUDED

View File

@@ -0,0 +1,139 @@
//
// PrintHandler.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: PrintHandler
//
// Definition of the PrintHandler class.
//
// Copyright (c) 2012, 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 JSON_PrintHandler_INCLUDED
#define JSON_PrintHandler_INCLUDED
#include "Poco/JSON/JSON.h"
#include "Poco/JSON/Handler.h"
namespace Poco {
namespace JSON {
class JSON_API PrintHandler : public Handler
/// PrintHandler formats and prints the JSON object
/// to either user-provided std::ostream or standard out.
/// If indent i zero, the output is condensed JSON string,
/// otherwise, the proper indentation is applied to elements.
{
public:
static const unsigned JSON_PRINT_FLAT = 0;
PrintHandler(unsigned indent = 0);
/// Creates the PrintHandler.
PrintHandler(std::ostream& out, unsigned indent = 0);
/// Creates the PrintHandler.
~PrintHandler();
/// Destroys the PrintHandler.
void startObject();
/// The parser has read a '{'; a new object is started.
/// If indent is greater than zero, a newline will be apended.
void endObject();
/// The parser has read a '}'; the object is closed.
void startArray();
/// The parser has read a [; a new array will be started.
/// If indent is greater than zero, a newline will be apended.
void endArray();
/// The parser has read a ]; the array is closed.
void key(const std::string& k);
/// A key of an object is read; it will be written to the output,
/// followed by a ':'. If indent is greater than zero, the colon
/// is padded by a space before and after.
void null();
/// A null value is read; "null" will be written to the output.
void value(int v);
/// An integer value is read.
void value(unsigned v);
/// An unsigned value is read. This will only be triggered if the
/// value cannot fit into a signed int.
#if defined(POCO_HAVE_INT64)
void value(Int64 v);
/// A 64-bit integer value is read; it will be written to the output.
void value(UInt64 v);
/// An unsigned 64-bit integer value is read; it will be written to the output.
#endif
void value(const std::string& value);
/// A string value is read; it will be fromatted and written to the output.
void value(double d);
/// A double value is read; it will be written to the output.
void value(bool b);
/// A boolean value is read; it will be written to the output.
void comma();
/// A comma is read; it will be written to the output as "true" or "false".
void setIndent(unsigned indent)
{
_indent = indent;
}
private:
const char* endLine() const;
unsigned indent();
bool printFlat() const;
std::ostream& _out;
unsigned _indent;
std::string _tab;
bool _array;
};
}} // namespace Poco::JSON
#endif // JSON_PrintHandler_INCLUDED

View File

@@ -53,12 +53,39 @@ class JSON_API Stringifier
/// Helper class for creating a String from a JSON object or array /// Helper class for creating a String from a JSON object or array
{ {
public: public:
static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0); static void condense(const Dynamic::Var& any, std::ostream& out);
/// Writes a condensed string representation of the value to the output stream while preserving the insertion order.
/// This is just a "shortcut" to stringify(any, out) with name indicating the function effect.
static void stringify(const Dynamic::Var& any, bool preserveInsertionOrder, std::ostream& out, unsigned int indent = 0);
/// Writes a String representation of the value to the output stream while preserving the insertion order.
/// When indent is 0, the generated string will be created as small as possible (condensed).
/// When preserveInsertionOrder is true, the original string object members order will be preserved.
/// This is a "shortcut" to stringify(any, out, indent, -1, preserveInsertionOrder).
static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0, int step = -1, bool preserveInsertionOrder = false);
/// Writes a String representation of the value to the output stream. /// Writes a String representation of the value to the output stream.
/// When indent is 0, the String will be created as small as possible. /// When indent is 0, the String will be created as small as possible.
/// When preserveInsertionOrder is true, the original string object members order will be preserved;
/// otherwise, object members are sorted by their names.
static void formatString(const std::string& value, std::ostream& out);
/// Formats the JSON string and streams it into ostream.
}; };
inline void Stringifier::condense(const Dynamic::Var& any, std::ostream& out)
{
stringify(any, out, 0, -1, true);
}
inline void Stringifier::stringify(const Dynamic::Var& any, bool preserveInsertionOrder, std::ostream& out, unsigned int indent)
{
stringify(any, out, indent, -1, preserveInsertionOrder);
}
}} // namespace Poco::JSON }} // namespace Poco::JSON

View File

@@ -34,7 +34,7 @@
#include "Poco/Timestamp.h" #include "Poco/Timestamp.h"
#include "Poco/JSON/Parser.h" #include "Poco/JSON/Parser.h"
#include "Poco/JSON/DefaultHandler.h" #include "Poco/JSON/ParseHandler.h"
#include "Poco/JSON/JSONException.h" #include "Poco/JSON/JSONException.h"
#include "Poco/Environment.h" #include "Poco/Environment.h"
#include "Poco/Path.h" #include "Poco/Path.h"
@@ -82,7 +82,7 @@ int main(int argc, char** argv)
try try
{ {
Poco::JSON::DefaultHandler handler; Poco::JSON::ParseHandler handler;
Poco::JSON::Parser parser; Poco::JSON::Parser parser;
parser.setHandler(&handler); parser.setHandler(&handler);
Poco::Timestamp time1; Poco::Timestamp time1;

View File

@@ -120,8 +120,10 @@ bool Array::isObject(unsigned int index) const
} }
void Array::stringify(std::ostream& out, unsigned int indent) const void Array::stringify(std::ostream& out, unsigned int indent, int step) const
{ {
if (step == -1) step = indent;
out << "["; out << "[";
if (indent > 0) out << std::endl; if (indent > 0) out << std::endl;
@@ -130,15 +132,22 @@ void Array::stringify(std::ostream& out, unsigned int indent) const
{ {
for(int i = 0; i < indent; i++) out << ' '; for(int i = 0; i < indent; i++) out << ' ';
Stringifier::stringify(*it, out, indent); Stringifier::stringify(*it, out, indent + step, step);
if ( ++it != _values.end() ) if ( ++it != _values.end() )
{ {
out << ","; out << ",";
if ( indent > 0 ) out << std::endl; if (step > 0) out << '\n';
} }
} }
if (step > 0) out << '\n';
if (indent >= step) indent -= step;
for (int i = 0; i < indent; i++)
out << ' ';
out << "]"; out << "]";
} }

View File

@@ -42,9 +42,19 @@ namespace Poco {
namespace JSON { namespace JSON {
Handler::Handler()
{
}
Handler::~Handler() Handler::~Handler()
{ {
} }
void Handler::comma()
{
}
} } // namespace Poco::JSON } } // namespace Poco::JSON

View File

@@ -48,20 +48,20 @@ namespace Poco {
namespace JSON { namespace JSON {
Object::Object() Object::Object(bool preserveInsertionOrder): _preserveInsOrder(preserveInsertionOrder)
{ {
} }
Object::Object(const Object& copy) : _values(copy._values) Object::Object(const Object& copy) : _values(copy._values),
_keys(copy._keys),
_preserveInsOrder(copy._preserveInsOrder)
{ {
} }
Object::~Object() Object::~Object()
{ {
} }
@@ -114,27 +114,43 @@ void Object::getNames(std::vector<std::string>& names) const
} }
void Object::stringify(std::ostream& out, unsigned int indent) const void Object::stringify(std::ostream& out, unsigned int indent, int step) const
{ {
out << '{'; if (step == -1) step = indent;
if (indent > 0) out << std::endl; if(!_preserveInsOrder)
doStringify(_values, out, indent, step);
else
doStringify(_keys, out, indent, step);
}
for (ValueMap::const_iterator it = _values.begin(); it != _values.end();)
const std::string& Object::getKey(KeyPtrList::const_iterator& iter) const
{
ValueMap::const_iterator it = _values.begin();
ValueMap::const_iterator end = _values.end();
for (; it != end; ++it)
{ {
for(int i = 0; i < indent; i++) out << ' '; if (it->second == **iter) return it->first;
}
out << '"' << it->first << '"';
out << (( indent > 0 ) ? " : " : ":"); throw NotFoundException((*iter)->convert<std::string>());
}
Stringifier::stringify(it->second, out, indent);
if ( ++it != _values.end() ) out << ','; void Object::set(const std::string& key, const Dynamic::Var& value)
{
if ( indent > 0 ) out << std::endl; _values[key] = value;
if (_preserveInsOrder)
{
KeyPtrList::iterator it = _keys.begin();
KeyPtrList::iterator end = _keys.end();
for (; it != end; ++it)
{
if (key == **it) return;
}
_keys.push_back(&_values[key]);
} }
out << '}';
} }

View File

@@ -1,11 +1,11 @@
// //
// DefaultHandler.cpp // ParseHandler.cpp
// //
// $Id$ // $Id$
// //
// Library: JSON // Library: JSON
// Package: JSON // Package: JSON
// Module: DefaultHandler // Module: ParseHandler
// //
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH. // Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
@@ -34,7 +34,7 @@
// //
#include "Poco/JSON/DefaultHandler.h" #include "Poco/JSON/ParseHandler.h"
#include "Poco/JSON/Object.h" #include "Poco/JSON/Object.h"
@@ -45,19 +45,20 @@ namespace Poco {
namespace JSON { namespace JSON {
DefaultHandler::DefaultHandler() : Handler() ParseHandler::ParseHandler(bool preserveObjectOrder) : Handler(),
_preserveObjectOrder(preserveObjectOrder)
{ {
} }
DefaultHandler::~DefaultHandler() ParseHandler::~ParseHandler()
{ {
} }
void DefaultHandler::startObject() void ParseHandler::startObject()
{ {
Object::Ptr newObj = new Object(); Object::Ptr newObj = new Object(_preserveObjectOrder);
if ( _stack.empty() ) // The first object if ( _stack.empty() ) // The first object
{ {
@@ -85,13 +86,13 @@ void DefaultHandler::startObject()
} }
void DefaultHandler::endObject() void ParseHandler::endObject()
{ {
_stack.pop(); _stack.pop();
} }
void DefaultHandler::startArray() void ParseHandler::startArray()
{ {
Array::Ptr newArr = new Array(); Array::Ptr newArr = new Array();
@@ -121,19 +122,19 @@ void DefaultHandler::startArray()
} }
void DefaultHandler::endArray() void ParseHandler::endArray()
{ {
_stack.pop(); _stack.pop();
} }
void DefaultHandler::key(const std::string& k) void ParseHandler::key(const std::string& k)
{ {
_key = k; _key = k;
} }
void DefaultHandler::setValue(const Var& value) void ParseHandler::setValue(const Var& value)
{ {
Var parent = _stack.top(); Var parent = _stack.top();

View File

@@ -67,11 +67,11 @@ public:
bool start(char c, std::istream& istr) bool start(char c, std::istream& istr)
{ {
if (c == '{' if (c == '{'
|| c == '}' || c == '}'
|| c == ']' || c == ']'
|| c == '[' || c == '['
|| c == ',' || c == ','
|| c == ':') || c == ':')
{ {
_value = c; _value = c;
return true; return true;
@@ -594,6 +594,7 @@ bool Parser::readRow(bool firstCall)
{ {
if (token->asChar() == ',') if (token->asChar() == ',')
{ {
_handler->comma();
return true; // Read next row return true; // Read next row
} }
else if (token->asChar() == '}') else if (token->asChar() == '}')
@@ -636,46 +637,46 @@ void Parser::readValue(const Token* token)
if (_handler != NULL) if (_handler != NULL)
{ {
#if defined(POCO_HAVE_INT64) #if defined(POCO_HAVE_INT64)
try try
{ {
Int64 value = token->asInteger64(); Int64 value = token->asInteger64();
// if number is 32-bit, then handle as such // if number is 32-bit, then handle as such
if ( value > std::numeric_limits<int>::max() if ( value > std::numeric_limits<int>::max()
|| value < std::numeric_limits<int>::min() ) || value < std::numeric_limits<int>::min() )
{ {
_handler->value(value); _handler->value(value);
} }
else else
{ {
_handler->value(static_cast<int>(value)); _handler->value(static_cast<int>(value));
} }
} }
// try to handle error as unsigned in case of overflow // try to handle error as unsigned in case of overflow
catch ( const SyntaxException& ) catch ( const SyntaxException& )
{ {
UInt64 value = token->asUnsignedInteger64(); UInt64 value = token->asUnsignedInteger64();
// if number is 32-bit, then handle as such // if number is 32-bit, then handle as such
if ( value > std::numeric_limits<unsigned>::max() ) if ( value > std::numeric_limits<unsigned>::max() )
{ {
_handler->value(value); _handler->value(value);
} }
else else
{ {
_handler->value(static_cast<unsigned>(value)); _handler->value(static_cast<unsigned>(value));
} }
} }
#else #else
try try
{ {
int value = token->asInteger(); int value = token->asInteger();
_handle->value(value); _handle->value(value);
} }
// try to handle error as unsigned in case of overflow // try to handle error as unsigned in case of overflow
catch ( const SyntaxException& ) catch ( const SyntaxException& )
{ {
unsigned value = token->asUnsignedInteger(); unsigned value = token->asUnsignedInteger();
_handle->value(value); _handle->value(value);
} }
#endif #endif
} }
break; break;
@@ -773,13 +774,16 @@ bool Parser::readElements(bool firstCall)
token = nextToken(); token = nextToken();
if ( token->is(Token::SEPARATOR_TOKEN) ) if (token->is(Token::SEPARATOR_TOKEN))
{ {
if (token->asChar() == ']') if (token->asChar() == ']')
return false; // End of array return false; // End of array
if (token->asChar() == ',') if (token->asChar() == ',')
{
_handler->comma();
return true; return true;
}
throw JSONException(format("Invalid separator '%c' found. Expecting , or ]", token->asChar())); throw JSONException(format("Invalid separator '%c' found. Expecting , or ]", token->asChar()));
} }

194
JSON/src/PrintHandler.cpp Normal file
View File

@@ -0,0 +1,194 @@
//
// PrintHandler.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: PrintHandler
//
// Copyright (c) 2012, 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/JSON/PrintHandler.h"
#include "Poco/JSON/Stringifier.h"
namespace Poco {
namespace JSON {
PrintHandler::PrintHandler(unsigned indent):
_out(std::cout),
_indent(indent),
_array(false)
{
}
PrintHandler::PrintHandler(std::ostream& out, unsigned indent):
_out(out),
_indent(indent),
_array(false)
{
}
PrintHandler::~PrintHandler()
{
}
const char* PrintHandler::endLine() const
{
if (!printFlat()) return "\n";
else return "";
}
bool PrintHandler::printFlat() const
{
return _indent == JSON_PRINT_FLAT;
}
unsigned PrintHandler::indent()
{
if (!printFlat()) return _indent;
return 0;
}
void PrintHandler::startObject()
{
_out << '{';
_out << endLine();
_tab.append(indent(), ' ');
}
void PrintHandler::endObject()
{
if( _tab.length() >= indent())
_tab.erase(_tab.length() - indent());
_out << endLine() << _tab << '}';
}
void PrintHandler::startArray()
{
_out << '[' << endLine();
_tab.append(indent(), ' ');
_array = true;
}
void PrintHandler::endArray()
{
_tab.erase(_tab.length() - indent());
_out << endLine() << _tab << ']';
_array = false;
}
void PrintHandler::key(const std::string& k)
{
_out << _tab << '"' << k << '"';
if (!printFlat()) _out << ' ';
_out << ':';
if (!printFlat()) _out << ' ';
}
void PrintHandler::null()
{
if (_array) _out << _tab;
_out << "null";
}
void PrintHandler::value(int v)
{
if (_array) _out << _tab;
_out << v;
}
void PrintHandler::value(unsigned v)
{
if (_array) _out << _tab;
_out << v;
}
#if defined(POCO_HAVE_INT64)
void PrintHandler::value(Int64 v)
{
if (_array) _out << _tab;
_out << v;
}
void PrintHandler::value(UInt64 v)
{
if (_array) _out << _tab;
_out << v;
}
#endif
void PrintHandler::value(const std::string& value)
{
if (_array) _out << _tab;
Stringifier::formatString(value, _out);
}
void PrintHandler::value(double d)
{
if (_array) _out << _tab;
_out << d;
}
void PrintHandler::value(bool b)
{
if (_array) _out << _tab;
_out << b;
}
void PrintHandler::comma()
{
_out << ',' << endLine();
}
} } // namespace Poco::JSON

View File

@@ -47,27 +47,29 @@ namespace Poco {
namespace JSON { namespace JSON {
void Stringifier::stringify(const Var& any, std::ostream& out, unsigned int indent) void Stringifier::stringify(const Var& any, std::ostream& out, unsigned int indent, int step, bool preserveInsertionOrder)
{ {
if (step == -1) step = indent;
if ( any.type() == typeid(Object) ) if ( any.type() == typeid(Object) )
{ {
const Object& o = any.extract<Object>(); const Object& o = any.extract<Object>();
o.stringify(out, indent == 0 ? 0 : indent + 2); o.stringify(out, indent == 0 ? 0 : indent, step);
} }
else if ( any.type() == typeid(Array) ) else if ( any.type() == typeid(Array) )
{ {
const Array& a = any.extract<Array>(); const Array& a = any.extract<Array>();
a.stringify(out, indent == 0 ? 0 : indent + 2); a.stringify(out, indent == 0 ? 0 : indent, step);
} }
else if ( any.type() == typeid(Object::Ptr) ) else if ( any.type() == typeid(Object::Ptr) )
{ {
const Object::Ptr& o = any.extract<Object::Ptr>(); const Object::Ptr& o = any.extract<Object::Ptr>();
o->stringify(out, indent == 0 ? 0 : indent + 2); o->stringify(out, indent == 0 ? 0 : indent, step);
} }
else if ( any.type() == typeid(Array::Ptr) ) else if ( any.type() == typeid(Array::Ptr) )
{ {
const Array::Ptr& a = any.extract<Array::Ptr>(); const Array::Ptr& a = any.extract<Array::Ptr>();
a->stringify(out, indent == 0 ? 0 : indent + 2); a->stringify(out, indent == 0 ? 0 : indent, step);
} }
else if ( any.isEmpty() ) else if ( any.isEmpty() )
{ {
@@ -75,48 +77,8 @@ void Stringifier::stringify(const Var& any, std::ostream& out, unsigned int inde
} }
else if ( any.isString() ) else if ( any.isString() )
{ {
out << '"';
std::string value = any.convert<std::string>(); std::string value = any.convert<std::string>();
for(std::string::const_iterator it = value.begin(); it != value.end(); ++it) formatString(value, out);
{
switch (*it)
{
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:
{
if ( *it > 0 && *it <= 0x1F )
{
out << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*it);
}
else
{
out << *it;
}
break;
}
}
}
out << '"';
} }
else else
{ {
@@ -125,4 +87,49 @@ 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(); it != value.end(); ++it)
{
switch (*it)
{
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:
{
if ( *it > 0 && *it <= 0x1F )
{
out << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*it);
}
else
{
out << *it;
}
break;
}
}
}
out << '"';
}
} } // Namespace Poco::JSON } } // Namespace Poco::JSON

View File

@@ -39,7 +39,8 @@
#include "Poco/JSON/Query.h" #include "Poco/JSON/Query.h"
#include "Poco/JSON/JSONException.h" #include "Poco/JSON/JSONException.h"
#include "Poco/JSON/Stringifier.h" #include "Poco/JSON/Stringifier.h"
#include "Poco/JSON/DefaultHandler.h" #include "Poco/JSON/ParseHandler.h"
#include "Poco/JSON/PrintHandler.h"
#include "Poco/JSON/Template.h" #include "Poco/JSON/Template.h"
#include "Poco/Path.h" #include "Poco/Path.h"
@@ -87,7 +88,7 @@ void JSONTest::testNullProperty()
Var result; Var result;
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -114,7 +115,7 @@ void JSONTest::testTrueProperty()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -143,7 +144,7 @@ void JSONTest::testFalseProperty()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -172,7 +173,7 @@ void JSONTest::testNumberProperty()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -202,7 +203,7 @@ void JSONTest::testUnsignedNumberProperty()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -233,7 +234,7 @@ void JSONTest::testNumber64Property()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -263,7 +264,7 @@ void JSONTest::testUnsignedNumber64Property()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -294,7 +295,7 @@ void JSONTest::testStringProperty()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -323,7 +324,7 @@ void JSONTest::testEmptyObject()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -349,7 +350,7 @@ void JSONTest::testDoubleProperty()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -378,7 +379,7 @@ void JSONTest::testDouble2Property()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -407,7 +408,7 @@ void JSONTest::testDouble3Property()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -436,7 +437,7 @@ void JSONTest::testObjectProperty()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -472,7 +473,7 @@ void JSONTest::testObjectArray()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -494,6 +495,37 @@ void JSONTest::testObjectArray()
} }
void JSONTest::testArrayOfObjects()
{
std::string json = "[ {\"test\" : 0}, { \"test1\" : [1, 2, 3], \"test2\" : 4 } ]";
Parser parser;
Var result;
try
{
ParseHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(JSONException& jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Array::Ptr));
Array::Ptr arr = result.extract<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);
assert (result == 1);
}
void JSONTest::testEmptyArray() void JSONTest::testEmptyArray()
{ {
std::string json = "[]"; std::string json = "[]";
@@ -502,7 +534,7 @@ void JSONTest::testEmptyArray()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -528,7 +560,7 @@ void JSONTest::testNestedArray()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -554,7 +586,7 @@ void JSONTest::testNullElement()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -582,7 +614,7 @@ void JSONTest::testTrueElement()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -611,7 +643,7 @@ void JSONTest::testFalseElement()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -640,7 +672,7 @@ void JSONTest::testNumberElement()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -669,7 +701,7 @@ void JSONTest::testStringElement()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -698,7 +730,7 @@ void JSONTest::testEmptyObjectElement()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -725,7 +757,7 @@ void JSONTest::testDoubleElement()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -754,7 +786,7 @@ void JSONTest::testOptValue()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -781,7 +813,7 @@ void JSONTest::testQuery()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -801,15 +833,77 @@ void JSONTest::testQuery()
} }
void JSONTest::testPrintHandler()
{
std::string json = "{ \"name\" : \"Homer\", \"age\" : 38, \"wife\" : \"Marge\", \"age\" : 36, \"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ] }";
Parser parser;
std::ostringstream ostr;
PrintHandler handler(ostr);
parser.setHandler(&handler);
parser.parse(json);
assert (ostr.str() == "{\"name\":\"Homer\",\"age\":38,\"wife\":\"Marge\",\"age\":36,\"children\":[\"Bart\",\"Lisa\",\"Maggie\"]}");
handler.setIndent(1);
ostr.str("");
parser.parse(json);
assert (ostr.str() == "{\n"
" \"name\" : \"Homer\",\n"
" \"age\" : 38,\n"
" \"wife\" : \"Marge\",\n"
" \"age\" : 36,\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ]\n"
"}"
);
handler.setIndent(2);
ostr.str("");
parser.parse(json);
assert (ostr.str() == "{\n"
" \"name\" : \"Homer\",\n"
" \"age\" : 38,\n"
" \"wife\" : \"Marge\",\n"
" \"age\" : 36,\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ]\n"
"}"
);
handler.setIndent(4);
ostr.str("");
parser.parse(json);
assert (ostr.str() == "{\n"
" \"name\" : \"Homer\",\n"
" \"age\" : 38,\n"
" \"wife\" : \"Marge\",\n"
" \"age\" : 36,\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ]\n"
"}"
);
}
void JSONTest::testStringify() void JSONTest::testStringify()
{ {
std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ] }"; std::string json = "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\" , \"age\" : 38 }, \"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
"\"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", \"town\" : \"Springfield\" } } }";
Parser parser; Parser parser;
Var result; Var result;
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -822,9 +916,221 @@ void JSONTest::testStringify()
assert(result.type() == typeid(Object::Ptr)); assert(result.type() == typeid(Object::Ptr));
std::ostringstream ostr; std::ostringstream ostr;
Stringifier::condense(result, ostr);
std::string str = "{"
"\"Simpsons\":{"
"\"address\":{"
"\"number\":742,"
"\"street\":\"Evergreen Terrace\","
"\"town\":\"Springfield\""
"},"
"\"children\":["
"\"Bart\","
"\"Lisa\","
"\"Maggie\"],"
"\"husband\":{"
"\"age\":38,"
"\"name\":\"Homer\""
"},"
"\"wife\":{"
"\"age\":36,\"name\":\"Marge\""
"}}}";
assert (ostr.str() == str);
ostr.str("");
Stringifier::stringify(result, ostr); Stringifier::stringify(result, ostr);
//TODO: need map that does not order for internal container assert (ostr.str() == str);
assert (ostr.str() == "{\"name\":\"Franky\",\"children\":[\"Jonas\",\"Ellen\"]}");
ostr.str("");
Stringifier::stringify(result, ostr, 1);
str = "{\n"
" \"Simpsons\" : {\n"
" \"address\" : {\n"
" \"number\" : 742,\n"
" \"street\" : \"Evergreen Terrace\",\n"
" \"town\" : \"Springfield\"\n"
" },\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ],\n"
" \"husband\" : {\n"
" \"age\" : 38,\n"
" \"name\" : \"Homer\"\n"
" },\n"
" \"wife\" : {\n"
" \"age\" : 36,\n"
" \"name\" : \"Marge\"\n"
" }\n"
" }\n"
"}";
assert (ostr.str() == str);
ostr.str("");
Stringifier::stringify(result, ostr, 2);
str = "{\n"
" \"Simpsons\" : {\n"
" \"address\" : {\n"
" \"number\" : 742,\n"
" \"street\" : \"Evergreen Terrace\",\n"
" \"town\" : \"Springfield\"\n"
" },\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ],\n"
" \"husband\" : {\n"
" \"age\" : 38,\n"
" \"name\" : \"Homer\"\n"
" },\n"
" \"wife\" : {\n"
" \"age\" : 36,\n"
" \"name\" : \"Marge\"\n"
" }\n"
" }\n"
"}";
assert (ostr.str() == str);
ostr.str("");
Stringifier::stringify(result, ostr, 4);
str = "{\n"
" \"Simpsons\" : {\n"
" \"address\" : {\n"
" \"number\" : 742,\n"
" \"street\" : \"Evergreen Terrace\",\n"
" \"town\" : \"Springfield\"\n"
" },\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ],\n"
" \"husband\" : {\n"
" \"age\" : 38,\n"
" \"name\" : \"Homer\"\n"
" },\n"
" \"wife\" : {\n"
" \"age\" : 36,\n"
" \"name\" : \"Marge\"\n"
" }\n"
" }\n"
"}";
assert (ostr.str() == str);
}
void JSONTest::testStringifyPreserveOrder()
{
std::string json = "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\" , \"age\" : 38 }, \"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
"\"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", \"town\" : \"Springfield\" } } }";
Parser parser;
Var result;
try
{
ParseHandler handler(true);
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(JSONException& jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Object::Ptr));
std::ostringstream ostr;
Stringifier::condense(result, ostr);
assert (ostr.str() == "{\"Simpsons\":{\"husband\":{\"name\":\"Homer\",\"age\":38},\"wife\":{\"name\":\"Marge\",\"age\":36},"
"\"children\":[\"Bart\",\"Lisa\",\"Maggie\"],"
"\"address\":{\"number\":742,\"street\":\"Evergreen Terrace\",\"town\":\"Springfield\"}}}");
ostr.str("");
Stringifier::stringify(result, ostr);
assert (ostr.str() == "{\"Simpsons\":{\"husband\":{\"name\":\"Homer\",\"age\":38},\"wife\":{\"name\":\"Marge\",\"age\":36},"
"\"children\":[\"Bart\",\"Lisa\",\"Maggie\"],"
"\"address\":{\"number\":742,\"street\":\"Evergreen Terrace\",\"town\":\"Springfield\"}}}");
ostr.str("");
Stringifier::stringify(result, ostr, 1);
assert (ostr.str() == "{\n"
" \"Simpsons\" : {\n"
" \"husband\" : {\n"
" \"name\" : \"Homer\",\n"
" \"age\" : 38\n"
" },\n"
" \"wife\" : {\n"
" \"name\" : \"Marge\",\n"
" \"age\" : 36\n"
" },\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ],\n"
" \"address\" : {\n"
" \"number\" : 742,\n"
" \"street\" : \"Evergreen Terrace\",\n"
" \"town\" : \"Springfield\"\n"
" }\n"
" }\n"
"}");
ostr.str("");
Stringifier::stringify(result, ostr, 2);
assert (ostr.str() == "{\n"
" \"Simpsons\" : {\n"
" \"husband\" : {\n"
" \"name\" : \"Homer\",\n"
" \"age\" : 38\n"
" },\n"
" \"wife\" : {\n"
" \"name\" : \"Marge\",\n"
" \"age\" : 36\n"
" },\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ],\n"
" \"address\" : {\n"
" \"number\" : 742,\n"
" \"street\" : \"Evergreen Terrace\",\n"
" \"town\" : \"Springfield\"\n"
" }\n"
" }\n"
"}");
ostr.str("");
Stringifier::stringify(result, ostr, 4);
assert (ostr.str() == "{\n"
" \"Simpsons\" : {\n"
" \"husband\" : {\n"
" \"name\" : \"Homer\",\n"
" \"age\" : 38\n"
" },\n"
" \"wife\" : {\n"
" \"name\" : \"Marge\",\n"
" \"age\" : 36\n"
" },\n"
" \"children\" : [\n"
" \"Bart\",\n"
" \"Lisa\",\n"
" \"Maggie\"\n"
" ],\n"
" \"address\" : {\n"
" \"number\" : 742,\n"
" \"street\" : \"Evergreen Terrace\",\n"
" \"town\" : \"Springfield\"\n"
" }\n"
" }\n"
"}");
} }
@@ -852,7 +1158,7 @@ void JSONTest::testValidJanssonFiles()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(fis); parser.parse(fis);
result = handler.result(); result = handler.result();
@@ -900,7 +1206,7 @@ void JSONTest::testInvalidJanssonFiles()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(fis); parser.parse(fis);
result = handler.result(); result = handler.result();
@@ -944,7 +1250,7 @@ void JSONTest::testInvalidUnicodeJanssonFiles()
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(fis); parser.parse(fis);
result = handler.result(); result = handler.result();
@@ -977,6 +1283,7 @@ void JSONTest::testTemplate()
tpl.render(data, std::cout); tpl.render(data, std::cout);
} }
void JSONTest::testUnicode() void JSONTest::testUnicode()
{ {
const unsigned char supp[] = {0x61, 0xE1, 0xE9, 0x78, 0xED, 0xF3, 0xFA, 0x0}; const unsigned char supp[] = {0x61, 0xE1, 0xE9, 0x78, 0xED, 0xF3, 0xFA, 0x0};
@@ -988,7 +1295,7 @@ void JSONTest::testUnicode()
Var result; Var result;
try try
{ {
DefaultHandler handler; ParseHandler handler;
parser.setHandler(&handler); parser.setHandler(&handler);
parser.parse(json); parser.parse(json);
result = handler.result(); result = handler.result();
@@ -1012,6 +1319,7 @@ void JSONTest::testUnicode()
assert(test.convert<std::string>() == original); assert(test.convert<std::string>() == original);
} }
std::string JSONTest::getTestFilesPath(const std::string& type) std::string JSONTest::getTestFilesPath(const std::string& type)
{ {
std::ostringstream ostr; std::ostringstream ostr;
@@ -1060,6 +1368,7 @@ CppUnit::Test* JSONTest::suite()
CppUnit_addTest(pSuite, JSONTest, testDouble3Property); CppUnit_addTest(pSuite, JSONTest, testDouble3Property);
CppUnit_addTest(pSuite, JSONTest, testObjectProperty); CppUnit_addTest(pSuite, JSONTest, testObjectProperty);
CppUnit_addTest(pSuite, JSONTest, testObjectArray); CppUnit_addTest(pSuite, JSONTest, testObjectArray);
CppUnit_addTest(pSuite, JSONTest, testArrayOfObjects);
CppUnit_addTest(pSuite, JSONTest, testEmptyArray); CppUnit_addTest(pSuite, JSONTest, testEmptyArray);
CppUnit_addTest(pSuite, JSONTest, testNestedArray); CppUnit_addTest(pSuite, JSONTest, testNestedArray);
CppUnit_addTest(pSuite, JSONTest, testNullElement); CppUnit_addTest(pSuite, JSONTest, testNullElement);
@@ -1071,7 +1380,9 @@ CppUnit::Test* JSONTest::suite()
CppUnit_addTest(pSuite, JSONTest, testDoubleElement); CppUnit_addTest(pSuite, JSONTest, testDoubleElement);
CppUnit_addTest(pSuite, JSONTest, testOptValue); CppUnit_addTest(pSuite, JSONTest, testOptValue);
CppUnit_addTest(pSuite, JSONTest, testQuery); CppUnit_addTest(pSuite, JSONTest, testQuery);
CppUnit_addTest(pSuite, JSONTest, testPrintHandler);
CppUnit_addTest(pSuite, JSONTest, testStringify); CppUnit_addTest(pSuite, JSONTest, testStringify);
CppUnit_addTest(pSuite, JSONTest, testStringifyPreserveOrder);
CppUnit_addTest(pSuite, JSONTest, testValidJanssonFiles); CppUnit_addTest(pSuite, JSONTest, testValidJanssonFiles);
CppUnit_addTest(pSuite, JSONTest, testInvalidJanssonFiles); CppUnit_addTest(pSuite, JSONTest, testInvalidJanssonFiles);
CppUnit_addTest(pSuite, JSONTest, testInvalidUnicodeJanssonFiles); CppUnit_addTest(pSuite, JSONTest, testInvalidUnicodeJanssonFiles);

View File

@@ -62,6 +62,7 @@ public:
void testDouble3Property(); void testDouble3Property();
void testObjectProperty(); void testObjectProperty();
void testObjectArray(); void testObjectArray();
void testArrayOfObjects();
void testEmptyArray(); void testEmptyArray();
void testNestedArray(); void testNestedArray();
void testNullElement(); void testNullElement();
@@ -73,7 +74,9 @@ public:
void testDoubleElement(); void testDoubleElement();
void testOptValue(); void testOptValue();
void testQuery(); void testQuery();
void testPrintHandler();
void testStringify(); void testStringify();
void testStringifyPreserveOrder();
void testValidJanssonFiles(); void testValidJanssonFiles();
void testInvalidJanssonFiles(); void testInvalidJanssonFiles();