Copy JSON from SandBox to trunk

This commit is contained in:
Franky Braem 2012-04-29 20:09:55 +00:00
parent 5a639074d9
commit 95c62c00df
121 changed files with 5085 additions and 0 deletions

21
JSON/Makefile Normal file
View File

@ -0,0 +1,21 @@
#
# Makefile
#
# $Id$
#
# Makefile for Poco JSON
#
include $(POCO_BASE)/build/rules/global
INCLUDE += -I $(POCO_BASE)/JSON/include/Poco/JSON
objects = Array Object Parser Handler \
Stringifier DefaultHandler Query JSONException \
Template TemplateCache
target = PocoJSON
target_version = $(LIBVERSION)
target_libs = PocoFoundation
include $(POCO_BASE)/build/rules/lib

View File

@ -0,0 +1,358 @@
//
// Array.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Array
//
// Definition of the Array 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_Array_INCLUDED
#define JSON_Array_INCLUDED
#include <vector>
#include <sstream>
#include "Poco/JSON/JSON.h"
#include "Poco/SharedPtr.h"
#include "Poco/DynamicAny.h"
namespace Poco
{
namespace JSON
{
class Object;
class JSON_API Array
{
public:
typedef std::vector<DynamicAny> ValueVector;
typedef SharedPtr<Array> Ptr;
Array();
/// Default constructor
Array(const Array& copy);
/// Copy Constructor
virtual ~Array();
/// Destructor
ValueVector::const_iterator begin() const;
/// Returns iterator
ValueVector::const_iterator end() const;
/// Returns iterator
DynamicAny get(unsigned int index) const;
/// Retrieves an element. Will return an empty value
/// when the element doesn't exist.
Array::Ptr getArray(unsigned int index) const;
/// Retrieves an array. When the element is not
/// an array or doesn't exist, an empty SharedPtr is returned.
template<typename T>
T getElement(unsigned int index) const
/// Retrieves an element and tries to convert it to the
/// template type. The convert<T> method of
/// Dynamic is called which can also throw
/// exceptions for invalid values.
/// Note: This will not work for an array or an object.
{
DynamicAny value = get(index);
return value.convert<T>();
}
SharedPtr<Object> getObject(unsigned int index) const;
/// Retrieves an object. When the element is not
/// an object or doesn't exist, an empty SharedPtr is returned.
unsigned int size() const;
/// Returns the size of the array
bool isArray(unsigned int index) const;
/// Returns true when the element is an array
bool isNull(unsigned int index) const;
/// Returns true when the element is null or
/// when the element doesn't exist.
bool isObject(unsigned int index) const;
/// Returns true when the element is an object
template<typename T>
T optElement(unsigned int index, const T& def) const
/// Returns the element at the given index. When
/// the element is null, doesn't exist or can't
/// be converted to the given type, the default
/// value will be returned
{
T value = def;
if ( index < _values.size() )
{
try
{
value = _values[index].convert<T>();
}
catch(...)
{
// Default value is returned.
}
}
return value;
}
void add(const DynamicAny& value)
/// Add the given value to the array
{
_values.push_back(value);
}
void stringify(std::ostream& out, unsigned int indent) const;
/// Prints the array to out. When indent is 0, the array
/// will be printed on one line without indentation.
void remove(unsigned int index);
/// Removes the element on the given index.
private:
ValueVector _values;
};
inline Array::ValueVector::const_iterator Array::begin() const
{
return _values.begin();
}
inline Array::ValueVector::const_iterator Array::end() const
{
return _values.end();
}
inline unsigned int Array::size() const
{
return _values.size();
}
inline bool Array::isArray(unsigned int index) const
{
DynamicAny value = get(index);
return value.type() == typeid(Array::Ptr);
}
inline bool Array::isNull(unsigned int index) const
{
if ( index < _values.size() )
{
DynamicAny value = _values[index];
return value.isEmpty();
}
return true;
}
inline void Array::remove(unsigned int index)
{
_values.erase(_values.begin() + index);
}
}} // Namespace Poco::JSON
namespace Poco
{
template <>
class DynamicAnyHolderImpl<JSON::Array::Ptr>: public DynamicAnyHolder
{
public:
DynamicAnyHolderImpl(const JSON::Array::Ptr& val): _val(val)
{
}
~DynamicAnyHolderImpl()
{
}
const std::type_info& type() const
{
return typeid(JSON::Array::Ptr);
}
void convert(Int8&) const
{
throw BadCastException();
}
void convert(Int16&) const
{
throw BadCastException();
}
void convert(Int32&) const
{
throw BadCastException();
}
void convert(Int64&) const
{
throw BadCastException();
}
void convert(UInt8&) const
{
throw BadCastException();
}
void convert(UInt16&) const
{
throw BadCastException();
}
void convert(UInt32&) const
{
throw BadCastException();
}
void convert(UInt64&) const
{
throw BadCastException();
}
void convert(bool& value) const
{
value = !_val.isNull() && _val->size() > 0;
}
void convert(float&) const
{
throw BadCastException();
}
void convert(double&) const
{
throw BadCastException();
}
void convert(char&) const
{
throw BadCastException();
}
void convert(std::string& s) const
{
std::ostringstream oss;
_val->stringify(oss, 2);
s = oss.str();
}
void convert(DateTime& val) const
{
throw BadCastException();
}
void convert(LocalDateTime& ldt) const
{
throw BadCastException();
}
void convert(Timestamp& ts) const
{
throw BadCastException();
}
DynamicAnyHolder* clone() const
{
return new DynamicAnyHolderImpl(_val);
}
const JSON::Array::Ptr& value() const
{
return _val;
}
bool isArray() const
{
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private:
JSON::Array::Ptr _val;
};
} // Namespace Poco
#endif // JSON_Array_INCLUDED

View File

@ -0,0 +1,166 @@
//
// DefaultHandler.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: DefaultHandler
//
// Definition of the DefaultHandler 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_DefaultHandler_INCLUDED
#define JSON_DefaultHandler_INCLUDED
#include "Poco/JSON/Handler.h"
#include <stack>
namespace Poco
{
namespace JSON
{
class JSON_API DefaultHandler : 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:
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
DynamicAny 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(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::DynamicAny& value);
std::stack<DynamicAny> _stack;
std::string _key;
DynamicAny _result;
};
inline DynamicAny DefaultHandler::result() const
{
return _result;
}
inline void DefaultHandler::value(int v)
{
setValue(v);
}
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::DynamicAny empty;
setValue(empty);
}
}} // Namespace Poco::JSON
#endif // JSON_DefaultHandler_INCLUDED

View File

@ -0,0 +1,106 @@
//
// Handler.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Handler
//
// Definition of the Handler 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_Handler_INCLUDED
#define JSON_Handler_INCLUDED
#include "Poco/DynamicAny.h"
#include "Poco/JSON/JSON.h"
namespace Poco
{
namespace JSON
{
class JSON_API Handler
{
public:
virtual void startObject() = 0;
/// The parser has read a {, meaning a new object will be read
virtual void endObject() = 0;
/// The parser has read a }, meaning the object is read
virtual void startArray() = 0;
/// The parser has read a [, meaning a new array will be read
virtual void endArray() = 0;
/// The parser has read a ], meaning the array is read
virtual void key(const std::string& k) = 0;
/// A key of an object is read
virtual void null() = 0;
/// A null value is read
virtual void value(int v) = 0;
/// An integer value is read
virtual void value(const std::string& value) = 0;
/// A string value is read.
virtual void value(double d) = 0;
/// A double value is read
virtual void value(bool b) = 0;
/// A boolean value is read
protected:
virtual ~Handler();
/// Destructor
private:
};
}} // Namespace Poco::JSON
#endif // JSON_Handler_INCLUDED

View File

@ -0,0 +1,80 @@
//
// JSON.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: JSON
//
// Basic definitions for the Poco Util library.
// This file must be the first file included by every other Util
// header file.
//
// 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_JSON_INCLUDED
#define JSON_JSON_INCLUDED
#include "Poco/Foundation.h"
//
// The following block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the Util_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// Util_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
//
#if defined(_WIN32) && defined(POCO_DLL)
#if defined(JSON_EXPORTS)
#define JSON_API __declspec(dllexport)
#else
#define JSON_API __declspec(dllimport)
#endif
#endif
#if !defined(JSON_API)
#define JSON_API
#endif
//
// Automatically link JSON library.
//
#if defined(_MSC_VER)
#if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(JSON_EXPORTS)
#pragma comment(lib, "PocoJSON" POCO_LIB_SUFFIX)
#endif
#endif
#endif // JSON_JSON_INCLUDED

View File

@ -0,0 +1,55 @@
//
// JSONException.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: JSONException
//
// Definition of the JSONException 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_JSONException_INCLUDED
#define JSON_JSONException_INCLUDED
#include "Poco/JSON/JSON.h"
#include "Poco/Exception.h"
namespace Poco
{
namespace JSON
{
POCO_DECLARE_EXCEPTION(JSON_API, JSONException, Poco::Exception)
}} // Namespace Poco::JSON
#endif //JSON_JSONException_INCLUDED

View File

@ -0,0 +1,359 @@
//
// Object.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Object
//
// Definition of the Object 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_Object_INCLUDED
#define JSON_Object_INCLUDED
#include <map>
#include <vector>
#include <iostream>
#include <sstream>
#include "Poco/SharedPtr.h"
#include "Poco/DynamicAny.h"
#include "Poco/JSON/JSON.h"
#include "Poco/JSON/Array.h"
namespace Poco
{
namespace JSON
{
class JSON_API Object
/// Represents a JSON object
{
public:
typedef SharedPtr<Object> Ptr;
Object();
/// Default constructor
Object(const Object& copy);
/// Copy constructor
virtual ~Object();
/// Destructor
DynamicAny get(const std::string& key) const;
/// Retrieves a property. An empty value is
/// returned when the property doesn't exist.
Array::Ptr getArray(const std::string& key) const;
/// Returns a SharedPtr to an array when the property
/// is an array. An empty SharedPtr is returned when
/// the element doesn't exist or is not an array.
Object::Ptr getObject(const std::string& key) const;
/// Returns a SharedPtr to an object when the property
/// is an object. An empty SharedPtr is returned when
/// the property doesn't exist or is not an object
template<typename T>
T getValue(const std::string& key) const
/// Retrieves the property with the given name and will
/// try to convert the value to the given template type.
/// The convert<T> method of Dynamic is called
/// which can also throw exceptions for invalid values.
/// Note: This will not work for an array or an object.
{
DynamicAny value = get(key);
return value.convert<T>();
}
void getNames(std::vector<std::string>& names) const;
/// Returns all property names
bool has(const std::string& key) const;
/// Returns true when the given property exists
bool isArray(const std::string& key) const;
/// Returns true when the given property contains an array
bool isNull(const std::string& key) const;
/// Returns true when the given property contains a null value
bool isObject(const std::string& key) const;
/// Returns true when the given property contains an object
template<typename T>
T optValue(const std::string& key, const T& def) const
/// Returns the value of a property when the property exists
/// and can be converted to the given type. Otherwise
/// def will be returned.
{
T value = def;
ValueMap::const_iterator it = _values.find(key);
if ( it != _values.end()
&& ! it->second.isEmpty() )
{
try
{
value = it->second.convert<T>();
}
catch(...)
{
// The default value will be returned
}
}
return value;
}
unsigned int size() const;
/// Returns the number of properties
void set(const std::string& key, const DynamicAny& value);
/// Sets a new value
void stringify(std::ostream& out, unsigned int indent = 0) const;
/// Prints the object to out. When indent is 0, the object
/// will be printed on one line without indentation.
void remove(const std::string& key);
/// Removes the property with the given key
private:
typedef std::map<std::string, DynamicAny> ValueMap;
ValueMap _values;
};
inline bool Object::has(const std::string& key) const
{
ValueMap::const_iterator it = _values.find(key);
return it != _values.end();
}
inline bool Object::isArray(const std::string& key) const
{
ValueMap::const_iterator it = _values.find(key);
return it != _values.end() || it->second.type() == typeid(Array::Ptr);
}
inline bool Object::isNull(const std::string& key) const
{
ValueMap::const_iterator it = _values.find(key);
return it == _values.end() || it->second.isEmpty();
}
inline bool Object::isObject(const std::string& key) const
{
ValueMap::const_iterator it = _values.find(key);
return it != _values.end() || it->second.type() == typeid(Object::Ptr);
}
inline void Object::set(const std::string& key, const DynamicAny& value)
{
_values[key] = value;
}
inline unsigned int Object::size() const
{
return _values.size();
}
inline void Object::remove(const std::string& key)
{
_values.erase(key);
}
}} // Namespace Poco::JSON
namespace Poco
{
template <>
class DynamicAnyHolderImpl<JSON::Object::Ptr>: public DynamicAnyHolder
{
public:
DynamicAnyHolderImpl(const JSON::Object::Ptr& val): _val(val)
{
}
~DynamicAnyHolderImpl()
{
}
const std::type_info& type() const
{
return typeid(JSON::Object::Ptr);
}
void convert(Int8&) const
{
throw BadCastException();
}
void convert(Int16&) const
{
throw BadCastException();
}
void convert(Int32&) const
{
throw BadCastException();
}
void convert(Int64&) const
{
throw BadCastException();
}
void convert(UInt8&) const
{
throw BadCastException();
}
void convert(UInt16&) const
{
throw BadCastException();
}
void convert(UInt32&) const
{
throw BadCastException();
}
void convert(UInt64&) const
{
throw BadCastException();
}
void convert(bool& value) const
{
value = !_val.isNull() && _val->size() > 0;
}
void convert(float&) const
{
throw BadCastException();
}
void convert(double&) const
{
throw BadCastException();
}
void convert(char&) const
{
throw BadCastException();
}
void convert(std::string& s) const
{
std::ostringstream oss;
_val->stringify(oss, 2);
s = oss.str();
}
void convert(DateTime& val) const
{
//TODO: val = _val;
}
void convert(LocalDateTime& ldt) const
{
//TODO: ldt = _val.timestamp();
}
void convert(Timestamp& ts) const
{
//TODO: ts = _val.timestamp();
}
DynamicAnyHolder* clone() const
{
return new DynamicAnyHolderImpl(_val);
}
const JSON::Object::Ptr& value() const
{
return _val;
}
bool isArray() const
{
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private:
JSON::Object::Ptr _val;
};
}
#endif // JSON_Object_INCLUDED

View File

@ -0,0 +1,140 @@
//
// Parser.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Parser
//
// Definition of the Parser 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_JSONParser_INCLUDED
#define JSON_JSONParser_INCLUDED
#include <istream>
#include <sstream>
#include "Poco/DynamicAny.h"
#include "Poco/StreamTokenizer.h"
#include "Poco/JSON/JSON.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Array.h"
#include "Poco/JSON/Handler.h"
namespace Poco
{
namespace JSON
{
class JSON_API Parser
/// A class for passing JSON strings or streams
{
public:
Parser();
/// Constructor
virtual ~Parser();
/// Destructor
void parse(const std::string& source);
/// Parses a string
void parse(std::istream& in);
/// Parses a JSON from the input stream
void setHandler(Handler* handler);
/// Set the handler
Handler* getHandler();
/// Returns the handler
private:
const Token* nextToken();
/// Returns the next token
void readObject();
/// Starts reading an object
void readArray();
/// Starts reading an array
bool readRow(bool firstCall = false);
/// Reads a property value pair. Returns true when a next row is expected.
void readValue(const Token* token);
/// Read a value from the token
bool readElements(bool firstCall = false);
/// Read all elements of an array
StreamTokenizer _tokenizer;
Handler* _handler;
};
inline void Parser::parse(const std::string& source)
{
std::istringstream is(source);
parse(is);
}
inline void Parser::setHandler(Handler* handler)
{
_handler = handler;
}
inline Handler* Parser::getHandler()
{
return _handler;
}
}} // Namespace Poco::JSON
#endif // JSON_JSONParser_INCLUDED

View File

@ -0,0 +1,118 @@
//
// Query.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Query
//
// Definition of the Query 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_JSONQuery_INCLUDED
#define JSON_JSONQuery_INCLUDED
#include "Poco/JSON/JSON.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Array.h"
namespace Poco
{
namespace JSON
{
class JSON_API Query
/// Class that can be used to search for a value in a JSON object or array.
{
public:
Query(const DynamicAny& source);
/// Constructor. Pass the start object/array.
virtual ~Query();
/// Destructor
Object::Ptr findObject(const std::string& path) const;
/// Search for an object. When the object can't be found, an empty
/// SharedPtr is returned.
Array::Ptr findArray(const std::string& path) const;
/// Search for an array. When the array can't be found, an empty
/// SharedPtr is returned.
DynamicAny find(const std::string& path) const;
/// Searches a value
/// For example: "person.children[0].name" will return the
/// the name of the first child. When the value can't be found
/// an empty value is returned.
template<typename T>
T findValue(const std::string& path, const T& def) const
/// Searches for a value will convert it to the given type.
/// When the value can't be found or has an invalid type
/// the default value will be returned.
{
T result = def;
DynamicAny value = find(path);
if ( ! value.isEmpty() )
{
try
{
result = value.convert<T>();
}
catch(...)
{
}
}
return result;
}
std::string findValue(const char* path, const char* def) const
/// Searches for a value will convert it to the given type.
/// When the value can't be found or has an invalid type
/// the default value will be returned.
{
return findValue<std::string>(path, def);
}
private:
DynamicAny _source;
};
}} // Namespace JSON
#endif // JSON_JSONQuery_INCLUDED

View File

@ -0,0 +1,64 @@
//
// Stringifier.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Stringifier
//
// Definition of the Stringifier 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_JSONStringifier_INCLUDED
#define JSON_JSONStringifier_INCLUDED
#include <iostream>
#include "Poco/DynamicAny.h"
#include "Poco/JSON/JSON.h"
namespace Poco
{
namespace JSON
{
class JSON_API Stringifier
/// Helper class for creating a String from a JSON object or array
{
public:
static void stringify(const DynamicAny& any, std::ostream& out, unsigned int indent = 0);
/// Writes a String representation of the value to the output stream.
/// When indent is 0, the String will be created as small as possible.
};
}} // Namespace Poco::JSON
#endif // JSON_JSONStringifier_INCLUDED

View File

@ -0,0 +1,182 @@
//
// Template.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Template
//
// Definition of the Template 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_JSONTemplate_INCLUDED
#define JSON_JSONTemplate_INCLUDED
#include <sstream>
#include <stack>
#include "Poco/JSON/JSON.h"
#include "Poco/DynamicAny.h"
#include "Poco/SharedPtr.h"
#include "Poco/Path.h"
#include "Poco/Timestamp.h"
namespace Poco
{
namespace JSON
{
class MultiPart;
POCO_DECLARE_EXCEPTION(JSON_API, JSONTemplateException, Poco::Exception)
class JSON_API Template
/// Template is a template engine which uses JSON as input
/// for generating output. There are commands for
/// looping over JSON arrays, include other templates,
/// conditional output, ...
///
/// All text is send to the outputstream. A command is placed
/// between <? and ?>.
///
/// These are the available commands:
/// <? echo query ?>
/// The result of the query is send to the output stream
/// This command can also be written as <?= query ?>
/// <? if query ?> <? else ?> <? endif ?>
/// When the result of query is true, all the text between
/// if and else (or endif when there is no else) is send to the
/// output stream. When the result of query is false, all the text
/// between else and endif is send to the output stream. An empty
/// object, an empty array or a null value is considered as a false value.
/// For numbers a zero is false. An empty String is also false.
/// <? ifexist query ?> <? else ?> <? endif ?>
/// This can be used to check the existance of the value.
/// Use this for example when a zero value is ok (which returns false for <? if ?>.
/// <? for variable query ?> <? endfor ?>
/// The result of the query must be an array. For each element
/// in the array the text between for and endfor is send to the
/// output stream. The active element is stored in the variable.
/// <? include "filename" ?>
/// Includes a template. When the filename is relative it will try
/// to resolve the filename against the active template. When this
/// file doesn't exist, it can still be found when the JSONTemplateCache
/// is used.
///
/// A query is passed to Poco::JSON::Query to get the value.
{
public:
typedef SharedPtr<Template> Ptr;
Template();
/// Constructor
Template(const Path& templatePath);
/// Constructor. Creates a template from a file.
virtual ~Template();
/// Destructor
void parse();
/// Parse a template from a file
void parse(const std::string& source);
/// Parse a template from a String
void parse(std::istream& in);
/// Parse a template from a input stream
Timestamp parseTime() const;
/// Returns the time when the template was parsed
void render(const DynamicAny& data, std::ostream& out) const;
/// Renders the template and send the output to the stream
private:
std::string readText(std::istream& in);
std::string readWord(std::istream& in);
std::string readQuery(std::istream& in);
std::string readTemplateCommand(std::istream& in);
std::string readString(std::istream& in);
void readWhiteSpace(std::istream& in);
MultiPart* _parts;
std::stack<MultiPart*> _partStack;
MultiPart* _currentPart;
Path _templatePath;
Timestamp _parseTime;
};
inline void Template::parse(const std::string& source)
{
std::istringstream is(source);
parse(is);
}
inline Timestamp Template::parseTime() const
{
return _parseTime;
}
}} // Namespace Poco::JSON
#endif // JSON_JSONTemplate_INCLUDED

View File

@ -0,0 +1,139 @@
//
// TemplateCache.h
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: TemplateCache
//
// Definition of the TemplateCache 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_JSONTemplateCache_INCLUDED
#define JSON_JSONTemplateCache_INCLUDED
#include <vector>
#include <map>
#include "Poco/Path.h"
#include "Poco/SharedPtr.h"
#include "Poco/Logger.h"
#include "Poco/JSON/Template.h"
namespace Poco
{
namespace JSON
{
class JSON_API TemplateCache
/// Use to cache parsed templates. Templates are
/// stored in a map with the full path as key.
/// When a template file has changed, the cache
/// will remove the old template from the cache
/// and load a new one.
{
public:
TemplateCache();
/// Constructor. The cache must be created
/// and not destroyed as long as it is used.
virtual ~TemplateCache();
/// Destructor
void addPath(const Path& path);
/// Add a path for resolving template paths.
/// The order of check is FIFO.
Template::Ptr getTemplate(const Path& path);
/// Returns a template from the cache.
/// When the template file is not yet loaded
/// or when the file has changed, the template
/// will be (re)loaded and parsed. A shared pointer
/// is returned, so it is safe to use this template
/// even when the template isn't stored anymore in
/// the cache.
static TemplateCache* instance();
/// Returns the only instance of this cache
void setLogger(Logger& logger);
/// Sets the logger for the cache.
private:
static TemplateCache* _instance;
std::vector<Path> _includePaths;
std::map<std::string, Template::Ptr> _cache;
Logger* _logger;
void setup();
Path resolvePath(const Path& path) const;
};
inline void TemplateCache::addPath(const Path& path)
{
_includePaths.push_back(path);
}
inline TemplateCache* TemplateCache::instance()
{
return _instance;
}
inline void TemplateCache::setLogger(Logger& logger)
{
_logger = &logger;
}
}} // Namespace Poco::JSON
#endif // JSON_JSONTemplateCache_INCLUDED

147
JSON/src/Array.cpp Normal file
View File

@ -0,0 +1,147 @@
//
// Array.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Array
//
// 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/Array.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Stringifier.h"
namespace Poco
{
namespace JSON
{
Array::Array()
{
}
Array::Array(const Array& copy) : _values(copy._values)
{
}
Array::~Array()
{
}
DynamicAny Array::get(unsigned int index) const
{
DynamicAny value;
try
{
value = _values.at(index);
}
catch(std::out_of_range)
{
//Ignore, we return an empty value
}
return value;
}
Array::Ptr Array::getArray(unsigned int index) const
{
Array::Ptr result;
DynamicAny value = get(index);
if ( value.type() == typeid(Array::Ptr) )
{
result = value.extract<Array::Ptr>();
}
return result;
}
Object::Ptr Array::getObject(unsigned int index) const
{
Object::Ptr result;
DynamicAny value = get(index);
if ( value.type() == typeid(Object::Ptr) )
{
result = value.extract<Object::Ptr>();
}
return result;
}
bool Array::isObject(unsigned int index) const
{
DynamicAny value = get(index);
return value.type() == typeid(Object::Ptr);
}
void Array::stringify(std::ostream& out, unsigned int indent) const
{
out << "[";
if ( indent > 0 )
out << std::endl;
for(ValueVector::const_iterator it = _values.begin(); it != _values.end();)
{
for(int i = 0; i < indent; i++)
{
out << ' ';
}
Stringifier::stringify(*it, out, indent);
if ( ++it != _values.end() )
{
out << ",";
if ( indent > 0 )
{
out << std::endl;
}
}
}
if ( indent > 0 )
{
out << std::endl;
}
if ( indent > 0 )
indent -= 2;
for(int i = 0; i < indent; i++)
{
out << ' ';
}
out << "]";
}
}} // Namespace Poco::JSON

150
JSON/src/DefaultHandler.cpp Normal file
View File

@ -0,0 +1,150 @@
//
// DefaultHandler.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: DefaultHandler
//
// 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/DefaultHandler.h"
#include "Poco/JSON/Object.h"
namespace Poco
{
namespace JSON
{
DefaultHandler::DefaultHandler() : Handler()
{
}
DefaultHandler::~DefaultHandler()
{
}
void DefaultHandler::startObject()
{
Object::Ptr newObj = new Object();
if ( _stack.empty() ) // The first object
{
_result = newObj;
}
else
{
DynamicAny parent = _stack.top();
if ( parent.type() == typeid(Array::Ptr) )
{
Array::Ptr arr = parent.extract<Array::Ptr>();
arr->add(newObj);
}
else if ( parent.type() == typeid(Object::Ptr) )
{
poco_assert_dbg(!_key.empty());
Object::Ptr obj = parent.extract<Object::Ptr>();
obj->set(_key, newObj);
_key.clear();
}
}
_stack.push(newObj);
}
void DefaultHandler::endObject()
{
_stack.pop();
}
void DefaultHandler::startArray()
{
Array::Ptr newArr = new Array();
if ( _stack.empty() ) // The first array
{
_result = newArr;
}
else
{
DynamicAny parent = _stack.top();
if ( parent.type() == typeid(Array::Ptr) )
{
Array::Ptr arr = parent.extract<Array::Ptr>();
arr->add(newArr);
}
else if ( parent.type() == typeid(Object::Ptr) )
{
poco_assert_dbg(!_key.empty());
Object::Ptr obj = parent.extract<Object::Ptr>();
obj->set(_key, newArr);
_key.clear();
}
}
_stack.push(newArr);
}
void DefaultHandler::endArray()
{
_stack.pop();
}
void DefaultHandler::key(const std::string& k)
{
_key = k;
}
void DefaultHandler::setValue(const Poco::DynamicAny& value)
{
DynamicAny parent = _stack.top();
if ( parent.type() == typeid(Array::Ptr) )
{
Array::Ptr arr = parent.extract<Array::Ptr>();
arr->add(value);
}
else if ( parent.type() == typeid(Object::Ptr) )
{
poco_assert_dbg(!_key.empty());
Object::Ptr obj = parent.extract<Object::Ptr>();
obj->set(_key, value);
_key.clear();
}
}
}} // Namespace Poco::JSON

48
JSON/src/Handler.cpp Normal file
View File

@ -0,0 +1,48 @@
//
// Handler.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Handler
//
// 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/Handler.h"
#include "Poco/JSON/Object.h"
namespace Poco
{
namespace JSON
{
Handler::~Handler()
{
}
}} // Namespace Poco::JSON

View File

@ -0,0 +1,44 @@
//
// JSONException.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: JSONException
//
// 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/JSONException.h"
#include <typeinfo>
namespace Poco {
namespace JSON {
POCO_IMPLEMENT_EXCEPTION(JSONException, Exception, "JSON Exception")
}} // Namespace Poco::JSON

155
JSON/src/Object.cpp Normal file
View File

@ -0,0 +1,155 @@
//
// Object.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Object
//
// 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/Object.h"
#include "Poco/JSON/Array.h"
#include "Poco/JSON/Stringifier.h"
#include <iostream>
#include <sstream>
namespace Poco
{
namespace JSON
{
Object::Object()
{
}
Object::Object(const Object& copy) : _values(copy._values)
{
}
Object::~Object()
{
}
DynamicAny Object::get(const std::string& key) const
{
DynamicAny value;
ValueMap::const_iterator it = _values.find(key);
if ( it != _values.end() )
{
value = it->second;
}
return value;
}
Array::Ptr Object::getArray(const std::string& key) const
{
Array::Ptr result;
DynamicAny value = get(key);
if ( value.type() == typeid(Array::Ptr) )
{
result = value.extract<Array::Ptr>();
}
return result;
}
Object::Ptr Object::getObject(const std::string& key) const
{
Object::Ptr result;
DynamicAny value = get(key);
if ( value.type() == typeid(Object::Ptr) )
{
result = value.extract<Object::Ptr>();
}
return result;
}
void Object::getNames(std::vector<std::string>& names) const
{
names.clear();
for(ValueMap::const_iterator it = _values.begin(); it != _values.end(); ++it)
{
names.push_back(it->first);
}
}
void Object::stringify(std::ostream& out, unsigned int indent) const
{
out << '{';
if ( indent > 0 )
{
out << std::endl;
}
for(ValueMap::const_iterator it = _values.begin(); it != _values.end();)
{
for(int i = 0; i < indent; i++)
{
out << ' ';
}
out << '"' << it->first << '"';
out << (( indent > 0 ) ? " : " : ":");
Stringifier::stringify(it->second, out, indent);
if ( ++it != _values.end() )
{
out << ',';
}
if ( indent > 0 )
{
out << std::endl;
}
}
if ( indent > 0 )
indent -= 2;
for(int i = 0; i < indent; i++)
{
out << ' ';
}
out << '}';
}
}} // Namespace Poco::JSON

678
JSON/src/Parser.cpp Normal file
View File

@ -0,0 +1,678 @@
//
// Parser.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Parser
//
// 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/Ascii.h"
#include "Poco/Token.h"
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/JSONException.h"
namespace Poco
{
namespace JSON
{
class SeparatorToken: public Token
{
public:
SeparatorToken()
{
}
virtual ~SeparatorToken()
{
}
Class tokenClass() const
{
return Token::SEPARATOR_TOKEN;
}
bool start(char c, std::istream& istr)
{
if ( c == '{'
|| c == '}'
|| c == ']'
|| c == '['
|| c == ','
|| c == ':' )
{
_value = c;
return true;
}
if ( c == '\'' )
{
throw JSONException("Invalid quote found");
}
else return false;
}
void finish(std::istream& istr)
{
}
};
class StringToken: public Token
{
public:
StringToken()
{
}
virtual ~StringToken()
{
}
Class tokenClass() const
{
return Token::STRING_LITERAL_TOKEN;
}
bool start(char c, std::istream& istr)
{
if ( c == '"')
{
_value = ""; // We don't need the quote!
return true;
}
else return false;
}
void finish(std::istream& istr)
{
int c = istr.get();
while (c != -1)
{
if ( c == 0 )
{
throw JSONException("Null byte not allowed");
}
if ( 0 < c && c <= 0x1F )
{
throw JSONException(format("Control character 0x%x not allowed", (unsigned int) c));
}
if ( c == '"' )
break;
if ( c == '\\' ) // Escaped String
{
c = istr.get();
switch(c)
{
case '"' :
c = '"';
break;
case '\\' :
c = '\\';
break;
case '/' :
c = '/';
break;
case 'b' :
c = '\b';
break;
case 'f' :
c = '\f';
break;
case 'n' :
c = '\n';
break;
case 'r' :
c = '\r';
break;
case 't' :
c = '\t';
break;
case 'u' : // Unicode
{
Poco::Int32 unicode = decodeUnicode(istr);
if ( unicode == 0 )
{
throw JSONException("\\u0000 is not allowed");
}
if ( unicode >= 0xD800 && unicode <= 0xDBFF )
{
c = istr.get();
if ( c != '\\' )
{
throw JSONException("Invalid unicode surrogate pair");
}
c = istr.get();
if ( c != 'u' )
{
throw JSONException("Invalid unicode surrogate pair");
}
Poco::Int32 surrogatePair = decodeUnicode(istr);
if ( 0xDC00 <= surrogatePair && surrogatePair <= 0xDFFF )
{
unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
}
else
{
throw JSONException("Invalid unicode surrogate pair");
}
}
else if ( 0xDC00 <= unicode && unicode <= 0xDFFF )
{
throw JSONException("Invalid unicode");
}
c = unicode;
break;
}
default:
{
throw JSONException(format("Invalid escape '%c' character used", (char) c));
}
}
}
_value += c;
c = istr.get();
}
if ( c == -1 )
{
throw JSONException("Unterminated string found");
}
}
Poco::Int32 decodeUnicode(std::istream& istr)
{
Poco::Int32 value = 0;
for(int i = 0; i < 4; i++)
{
value <<= 4;
int nc = istr.peek();
if ( nc == -1 )
{
throw JSONException("Invalid unicode sequence");
}
istr.get(); // No EOF, so read the character
if (nc >= '0' && nc <= '9')
value += nc - '0';
else if (nc >= 'A' && nc <= 'F')
value += 10 + nc - 'A';
else if (nc >= 'a' && nc <= 'f')
value += 10 + nc - 'a';
else
throw JSONException("Invalid unicode sequence. Hexadecimal digit expected");
}
return value;
}
};
class KeywordToken : public Token
{
public:
KeywordToken()
{
}
virtual ~KeywordToken()
{
}
Class tokenClass() const
{
return Token::KEYWORD_TOKEN;
}
bool start(char c, std::istream& istr)
{
if ( Ascii::isAlpha(c) )
{
_value = c;
return true;
}
return false;
}
void finish(std::istream& istr)
{
int c = istr.peek();
while (c != -1 && Ascii::isAlpha(c) )
{
istr.get();
_value += c;
c = istr.peek();
}
}
};
class NumberToken: public Token
{
public:
NumberToken() : _activeClass(INTEGER_LITERAL_TOKEN)
{
}
virtual ~NumberToken()
{
}
Class tokenClass() const
{
return _activeClass;
}
bool start(char c, std::istream& istr)
{
// Reset the active class to integer
_activeClass = INTEGER_LITERAL_TOKEN;
if ( c == -1 )
return false;
if ( Ascii::isDigit(c) )
{
if ( c == '0' )
{
int nc = istr.peek();
if ( Ascii::isDigit(nc) ) // A digit after a zero is not allowed
{
throw JSONException("Number can't start with a zero");
}
}
_value = c;
return true;
}
if ( c == '-' )
{
_value = c;
int nc = istr.peek();
if ( Ascii::isDigit(nc) )
{
if ( nc == '0' )
{
_value += '0';
istr.get();
nc = istr.peek();
if ( Ascii::isDigit(nc) ) // A digit after -0 is not allowed
{
throw JSONException("Number can't start with a zero");
}
}
return true;
}
}
return false;
}
void finish(std::istream& istr)
{
int c;
while( (c = istr.peek()) != -1)
{
if ( Ascii::isDigit(c) )
{
_value += c;
istr.get();
}
else
{
switch(c)
{
case '.': // Float
{
if ( _activeClass == Token::FLOAT_LITERAL_TOKEN )
{
throw JSONException("Invalid float value");
}
_activeClass = Token::FLOAT_LITERAL_TOKEN;
_value += c;
istr.get();
// After a . we need a digit
c = istr.peek();
if ( ! Ascii::isDigit(c) )
{
throw JSONException("Invalid float value");
}
break;
}
case 'E':
case 'e':
{
if ( _activeClass == Token::DOUBLE_LITERAL_TOKEN )
{
throw JSONException("Invalid double value");
}
_activeClass = Token::DOUBLE_LITERAL_TOKEN;
// Add the e or E
_value += c;
istr.get();
// When the next char is - or + then read the next char
c = istr.peek();
if ( c == '-' || c == '+' )
{
_value += c;
istr.get();
c = istr.peek();
}
if ( ! Ascii::isDigit(c) )
{
throw JSONException("Invalid double value");
}
break;
}
default:
return; // End of number token
}
istr.get(); // If we get here we have a valid character for a number
_value += c;
}
}
}
private:
Class _activeClass;
};
Parser::Parser() : _tokenizer(), _handler(NULL)
{
_tokenizer.addToken(new WhitespaceToken());
_tokenizer.addToken(new InvalidToken());
_tokenizer.addToken(new SeparatorToken());
_tokenizer.addToken(new StringToken());
_tokenizer.addToken(new NumberToken());
_tokenizer.addToken(new KeywordToken());
}
Parser::~Parser()
{
}
const Token* Parser::nextToken()
{
const Token* token = _tokenizer.next();
if ( token->is(Token::EOF_TOKEN) )
{
throw JSONException("Unexpected EOF found");
}
return token;
}
void Parser::parse(std::istream& in)
{
_tokenizer.attachToStream(in);
const Token* token = nextToken();
if ( token->is(Token::SEPARATOR_TOKEN) )
{
// This must be a { or a [
if ( token->asChar() == '{' )
{
readObject();
}
else if ( token->asChar() == '[' )
{
readArray();
}
else
{
throw JSONException(format("Invalid separator '%c' found. Expecting { or [", token->asChar()));
}
token = _tokenizer.next();
if ( ! token->is(Token::EOF_TOKEN) )
{
throw JSONException(format("EOF expected but found '%s'", token->asString()));
}
}
else
{
throw JSONException(format("Invalid token '%s' found. Expecting { or [", token->asString()));
}
}
void Parser::readObject()
{
if ( _handler != NULL )
{
_handler->startObject();
}
if ( readRow(true) ) // First call is special: check for empty object
{
while(readRow());
}
if ( _handler != NULL )
{
_handler->endObject();
}
}
bool Parser::readRow(bool firstCall)
{
const Token* token = nextToken();
if ( firstCall && token->tokenClass() == Token::SEPARATOR_TOKEN && token->asChar() == '}' )
{
return false; // End of object is possible for an empty object
}
if ( token->tokenClass() == Token::STRING_LITERAL_TOKEN )
{
std::string propertyName = token->tokenString();
if ( _handler != NULL )
{
_handler->key(propertyName);
}
token = nextToken();
if ( token->is(Token::SEPARATOR_TOKEN)
&& token->asChar() == ':' )
{
readValue(nextToken());
token = nextToken();
if ( token->is(Token::SEPARATOR_TOKEN) )
{
if ( token->asChar() == ',' )
{
return true; // Read next row
}
else if ( token->asChar() == '}' )
{
return false; // End of object
}
else
{
throw JSONException(format("Invalid separator '%c' found. Expecting , or }", token->asChar()));
}
}
else
{
throw JSONException(format("Invalid token '%s' found. Expecting , or }", token->asString()));
}
}
else
{
throw JSONException(format("Invalid token '%s' found. Expecting :", token->asString()));
}
}
else
{
throw JSONException(format("Invalid token '%s' found. Expecting key", token->asString()));
}
}
void Parser::readValue(const Token* token)
{
switch(token->tokenClass())
{
case Token::INTEGER_LITERAL_TOKEN:
if ( _handler != NULL )
{
_handler->value(token->asInteger());
}
break;
case Token::KEYWORD_TOKEN:
{
if ( token->tokenString().compare("null") == 0 )
{
if ( _handler != NULL )
{
_handler->null();
}
}
else if ( token->tokenString().compare("true") == 0 )
{
if ( _handler != NULL )
{
_handler->value(true);
}
}
else if ( token->tokenString().compare("false") == 0 )
{
if ( _handler != NULL )
{
_handler->value(false);
}
}
else
{
throw JSONException(format("Invalid keyword '%s' found", token->asString()));
}
break;
}
case Token::FLOAT_LITERAL_TOKEN:
// Fall through
case Token::DOUBLE_LITERAL_TOKEN:
if ( _handler != NULL )
{
_handler->value(token->asFloat());
}
break;
case Token::STRING_LITERAL_TOKEN:
if ( _handler != NULL )
{
_handler->value(token->tokenString());
}
break;
case Token::SEPARATOR_TOKEN:
{
if ( token->asChar() == '{' )
{
readObject();
}
else if ( token->asChar() == '[' )
{
readArray();
}
break;
}
}
}
void Parser::readArray()
{
if ( _handler != NULL )
{
_handler->startArray();
}
if ( readElements(true) ) // First call is special: check for empty array
{
while(readElements());
}
if ( _handler != NULL )
{
_handler->endArray();
}
}
bool Parser::readElements(bool firstCall)
{
const Token* token = nextToken();
if ( firstCall && token->is(Token::SEPARATOR_TOKEN) && token->asChar() == ']' )
{
// End of array is possible for an empty array
return false;
}
readValue(token);
token = nextToken();
if ( token->is(Token::SEPARATOR_TOKEN) )
{
if ( token->asChar() == ']' )
return false; // End of array
if ( token->asChar() == ',' )
return true;
throw JSONException(format("Invalid separator '%c' found. Expecting , or ]", token->asChar()));
}
throw JSONException(format("Invalid token '%s' found.", token->asString()));
}
}}

141
JSON/src/Query.cpp Normal file
View File

@ -0,0 +1,141 @@
//
// Query.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Query
//
// 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 <sstream>
#include "Poco/StringTokenizer.h"
#include "Poco/RegularExpression.h"
#include "Poco/NumberParser.h"
#include "Poco/JSON/Query.h"
namespace Poco
{
namespace JSON
{
Query::Query(const DynamicAny& source) : _source(source)
{
}
Query::~Query()
{
}
Object::Ptr Query::findObject(const std::string& path) const
{
Object::Ptr obj;
DynamicAny result = find(path);
if ( result.type() == typeid(Object::Ptr) )
{
obj = result.extract<Object::Ptr>();
}
return obj;
}
Array::Ptr Query::findArray(const std::string& path) const
{
Array::Ptr arr;
DynamicAny result = find(path);
if ( result.type() == typeid(Array::Ptr) )
{
arr = result.extract<Array::Ptr>();
}
return arr;
}
DynamicAny Query::find(const std::string& path) const
{
DynamicAny result = _source;
StringTokenizer tokenizer(path, ".");
for(StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); token++)
{
if ( !result.isEmpty() )
{
std::vector<int> indexes;
RegularExpression::MatchVec matches;
int firstOffset = -1;
int offset = 0;
RegularExpression regex("\\[([0-9]+)\\]");
while(regex.match(*token, offset, matches) > 0 )
{
if ( firstOffset == -1 )
{
firstOffset = matches[0].offset;
}
std::string num = token->substr(matches[1].offset, matches[1].length);
indexes.push_back(NumberParser::parse(num));
offset = matches[0].offset + matches[0].length;
}
std::string name(*token);
if ( firstOffset != -1 )
{
name = name.substr(0, firstOffset);
}
if ( name.length() > 0 )
{
if ( result.type() == typeid(Object::Ptr) )
{
Object::Ptr o = result.extract<Object::Ptr>();
result = o->get(name);
}
}
if ( !result.isEmpty()
&& !indexes.empty() )
{
for(std::vector<int>::iterator it = indexes.begin(); it != indexes.end(); ++it )
{
if ( result.type() == typeid(Array::Ptr) )
{
Array::Ptr array = result.extract<Array::Ptr>();
result = array->get(*it);
if ( result.isEmpty() )
{
break;
}
}
}
}
}
}
return result;
}
}} // Namespace Poco::JSON

114
JSON/src/Stringifier.cpp Normal file
View File

@ -0,0 +1,114 @@
//
// Stringifier.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Stringifier
//
// 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 <iomanip>
#include "Poco/JSON/Stringifier.h"
#include "Poco/JSON/Array.h"
#include "Poco/JSON/Object.h"
namespace Poco
{
namespace JSON
{
void Stringifier::stringify(const DynamicAny& any, std::ostream& out, unsigned int indent)
{
if ( any.type() == typeid(Object::Ptr) )
{
const Object::Ptr& o = any.extract<Object::Ptr>();
o->stringify(out, indent == 0 ? 0 : indent + 2);
}
else if ( any.type() == typeid(Array::Ptr) )
{
const Array::Ptr& a = any.extract<Array::Ptr>();
a->stringify(out, indent == 0 ? 0 : indent + 2);
}
else if ( any.isEmpty() )
{
out << "null";
}
else if ( any.isString() )
{
out << '"';
std::string value = any.convert<std::string>();
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 << '"';
}
else
{
out << any.convert<std::string>();
}
}
}} // Namespace Poco::JSON

736
JSON/src/Template.cpp Normal file
View File

@ -0,0 +1,736 @@
//
// Template.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: Template
//
// 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/File.h"
#include "Poco/FileStream.h"
#include "Poco/JSON/Template.h"
#include "Poco/JSON/TemplateCache.h"
#include "Poco/JSON/Query.h"
namespace Poco
{
namespace JSON
{
POCO_IMPLEMENT_EXCEPTION(JSONTemplateException, Exception, "Template Exception")
class Part
{
public:
Part()
{
}
virtual ~Part()
{
}
virtual void render(const DynamicAny& data, std::ostream& out) const = 0;
typedef std::vector<SharedPtr<Part> > VectorParts;
};
class StringPart : public Part
{
public:
StringPart() : Part()
{
}
StringPart(const std::string& content) : Part(), _content(content)
{
}
virtual ~StringPart()
{
}
void render(const DynamicAny& data, std::ostream& out) const
{
out << _content;
}
void setContent(const std::string& content)
{
_content = content;
}
inline std::string getContent() const
{
return _content;
}
private:
std::string _content;
};
class MultiPart : public Part
{
public:
MultiPart()
{
}
virtual ~MultiPart()
{
}
virtual void addPart(Part* part)
{
_parts.push_back(part);
}
void render(const DynamicAny& data, std::ostream& out) const
{
for(VectorParts::const_iterator it = _parts.begin(); it != _parts.end(); ++it)
{
(*it)->render(data, out);
}
}
protected:
VectorParts _parts;
};
class EchoPart : public Part
{
public:
EchoPart(const std::string& query) : Part(), _query(query)
{
}
virtual ~EchoPart()
{
}
void render(const DynamicAny& data, std::ostream& out) const
{
Query query(data);
DynamicAny value = query.find(_query);
if ( ! value.isEmpty() )
{
out << value.convert<std::string>();
}
}
private:
std::string _query;
};
class LogicQuery
{
public:
LogicQuery(const std::string& query) : _queryString(query)
{
}
virtual ~LogicQuery()
{
}
virtual bool apply(const DynamicAny& data) const
{
bool logic = false;
Query query(data);
DynamicAny value = query.find(_queryString);
if ( ! value.isEmpty() ) // When empty, logic will be false
{
if ( value.isString() )
// An empty string must result in false, otherwise true
// Which is not the case when we convert to bool with DynamicAny
{
std::string s = value.convert<std::string>();
logic = ! s.empty();
}
else
{
// All other values, try to convert to bool
// An empty object or array will turn into false
// all other values depend on the convert<> in DynamicAny
logic = value.convert<bool>();
}
}
return logic;
}
protected:
std::string _queryString;
};
class LogicExistQuery : public LogicQuery
{
public:
LogicExistQuery(const std::string& query) : LogicQuery(query)
{
}
virtual ~LogicExistQuery()
{
}
virtual bool apply(const DynamicAny& data) const
{
Query query(data);
DynamicAny value = query.find(_queryString);
return !value.isEmpty();
}
};
class LogicElseQuery : public LogicQuery
{
public:
LogicElseQuery() : LogicQuery("")
{
}
virtual ~LogicElseQuery()
{
}
virtual bool apply(const DynamicAny& data) const
{
return true;
}
};
class LogicPart : public MultiPart
{
public:
LogicPart() : MultiPart()
{
}
virtual ~LogicPart()
{
}
void addPart(LogicQuery* query, Part* part)
{
MultiPart::addPart(part);
_queries.push_back(query);
}
void addPart(Part* part)
{
MultiPart::addPart(part);
_queries.push_back(new LogicElseQuery());
}
void render(const DynamicAny& data, std::ostream& out) const
{
int count = 0;
for(std::vector<SharedPtr<LogicQuery> >::const_iterator it = _queries.begin(); it != _queries.end(); ++it, ++count)
{
if( (*it)->apply(data) && _parts.size() > count )
{
_parts[count]->render(data, out);
break;
}
}
}
private:
std::vector<SharedPtr<LogicQuery> > _queries;
};
class LoopPart : public MultiPart
{
public:
LoopPart(const std::string& name, const std::string& query) : MultiPart(), _name(name), _query(query)
{
}
virtual ~LoopPart()
{
}
void render(const DynamicAny& data, std::ostream& out) const
{
Query query(data);
if ( data.type() == typeid(Object::Ptr) )
{
Object::Ptr dataObject = data.extract<Object::Ptr>();
Array::Ptr array = query.findArray(_query);
if ( ! array.isNull() )
{
for(int i = 0; i < array->size(); i++)
{
DynamicAny value = array->get(i);
dataObject->set(_name, value);
MultiPart::render(data, out);
}
dataObject->remove(_name);
}
}
}
private:
std::string _name;
std::string _query;
};
class IncludePart : public Part
{
public:
IncludePart(const Path& parentPath, const Path& path)
: Part()
, _path(path)
{
// When the path is relative, try to make it absolute based
// on the path of the parent template. When the file doesn't
// exist, we keep it relative and hope that the cache can
// resolve it.
if ( _path.isRelative() )
{
Path templatePath(parentPath, _path);
File templateFile(templatePath);
if ( templateFile.exists() )
{
_path = templatePath;
}
}
}
virtual ~IncludePart()
{
}
void render(const DynamicAny& data, std::ostream& out) const
{
TemplateCache* cache = TemplateCache::instance();
if ( cache == NULL )
{
Template tpl(_path);
tpl.parse();
tpl.render(data, out);
}
else
{
Template::Ptr tpl = cache->getTemplate(_path);
tpl->render(data, out);
}
}
private:
Path _path;
};
Template::Template(const Path& templatePath)
: _parts(NULL)
, _templatePath(templatePath)
{
}
Template::Template()
: _parts(NULL)
{
}
Template::~Template()
{
if ( _parts != NULL )
{
delete _parts;
}
}
void Template::parse()
{
File file(_templatePath);
if ( file.exists() )
{
FileInputStream fis(_templatePath.toString());
parse(fis);
}
}
void Template::parse(std::istream& in)
{
_parseTime.update();
_parts = new MultiPart();
_currentPart = _parts;
while(in.good())
{
std::string text = readText(in); // Try to read text first
if ( text.length() > 0 )
{
_currentPart->addPart(new StringPart(text));
}
if ( in.bad() )
break; // Nothing to do anymore
std::string command = readTemplateCommand(in); // Try to read a template command
if ( command.empty() )
{
break;
}
readWhiteSpace(in);
if ( command.compare("echo") == 0 )
{
std::string query = readQuery(in);
if ( query.empty() )
{
throw JSONTemplateException("Missing query in <? echo ?>");
}
_currentPart->addPart(new EchoPart(query));
}
else if ( command.compare("for") == 0 )
{
std::string loopVariable = readWord(in);
if ( loopVariable.empty() )
{
throw JSONTemplateException("Missing variable in <? for ?> command");
}
readWhiteSpace(in);
std::string query = readQuery(in);
if ( query.empty() )
{
throw JSONTemplateException("Missing query in <? for ?> command");
}
_partStack.push(_currentPart);
LoopPart* part = new LoopPart(loopVariable, query);
_partStack.push(part);
_currentPart->addPart(part);
_currentPart = part;
}
else if ( command.compare("else") == 0 )
{
if ( _partStack.size() == 0 )
{
throw JSONTemplateException("Unexpected <? else ?> found");
}
_currentPart = _partStack.top();
LogicPart* lp = dynamic_cast<LogicPart*>(_currentPart);
if ( lp == NULL )
{
throw JSONTemplateException("Missing <? if ?> or <? ifexist ?> for <? else ?>");
}
MultiPart* part = new MultiPart();
lp->addPart(part);
_currentPart = part;
}
else if ( command.compare("elsif") == 0
|| command.compare("elif") == 0 )
{
std::string query = readQuery(in);
if ( query.empty() )
{
throw JSONTemplateException("Missing query in <? " + command + " ?>");
}
if ( _partStack.size() == 0 )
{
throw JSONTemplateException("Unexpected <? elsif / elif ?> found");
}
_currentPart = _partStack.top();
LogicPart* lp = dynamic_cast<LogicPart*>(_currentPart);
if ( lp == NULL )
{
throw JSONTemplateException("Missing <? if ?> or <? ifexist ?> for <? elsif / elif ?>");
}
MultiPart* part = new MultiPart();
lp->addPart(new LogicQuery(query), part);
_currentPart = part;
}
else if ( command.compare("endfor") == 0 )
{
if ( _partStack.size() < 2 )
{
throw JSONTemplateException("Unexpected <? endfor ?> found");
}
MultiPart* loopPart = _partStack.top();
LoopPart* lp = dynamic_cast<LoopPart*>(loopPart);
if ( lp == NULL )
{
throw JSONTemplateException("Missing <? for ?> command");
}
_partStack.pop();
_currentPart = _partStack.top();
_partStack.pop();
}
else if ( command.compare("endif") == 0 )
{
if ( _partStack.size() < 2 )
{
throw JSONTemplateException("Unexpected <? endif ?> found");
}
_currentPart = _partStack.top();
LogicPart* lp = dynamic_cast<LogicPart*>(_currentPart);
if ( lp == NULL )
{
throw JSONTemplateException("Missing <? if ?> or <? ifexist ?> for <? endif ?>");
}
_partStack.pop();
_currentPart = _partStack.top();
_partStack.pop();
}
else if ( command.compare("if") == 0
|| command.compare("ifexist") == 0 )
{
std::string query = readQuery(in);
if ( query.empty() )
{
throw JSONTemplateException("Missing query in <? " + command + " ?>");
}
_partStack.push(_currentPart);
LogicPart* lp = new LogicPart();
_partStack.push(lp);
_currentPart->addPart(lp);
_currentPart = new MultiPart();
if ( command.compare("ifexist") == 0 )
{
lp->addPart(new LogicExistQuery(query), _currentPart);
}
else
{
lp->addPart(new LogicQuery(query), _currentPart);
}
}
else if ( command.compare("include") == 0 )
{
readWhiteSpace(in);
std::string filename = readString(in);
if ( filename.empty() )
{
throw JSONTemplateException("Missing filename in <? include ?>");
}
else
{
Path resolvePath(_templatePath);
resolvePath.makeParent();
_currentPart->addPart(new IncludePart(resolvePath, filename));
}
}
else
{
throw JSONTemplateException("Unknown command " + command);
}
readWhiteSpace(in);
int c = in.get();
if ( c == '?' && in.peek() == '>' )
{
in.get(); // forget '>'
if ( command.compare("echo") != 0 )
{
if ( in.peek() == '\r' )
{
in.get();
}
if ( in.peek() == '\n' )
{
in.get();
}
}
}
else
{
throw JSONTemplateException("Missing ?>");
}
}
}
std::string Template::readText(std::istream& in)
{
std::string text;
int c = in.get();
while(c != -1)
{
if ( c == '<' )
{
if ( in.peek() == '?' )
{
in.get(); // forget '?'
break;
}
}
text += c;
c = in.get();
}
return text;
}
std::string Template::readTemplateCommand(std::istream& in)
{
std::string command;
readWhiteSpace(in);
int c = in.get();
while(c != -1)
{
if ( Ascii::isSpace(c) )
break;
if ( c == '?' && in.peek() == '>' )
{
in.putback(c);
break;
}
if ( c == '=' && command.length() == 0 )
{
command = "echo";
break;
}
command += c;
c = in.get();
}
return command;
}
std::string Template::readWord(std::istream& in)
{
std::string word;
int c;
while((c = in.peek()) != -1 && ! Ascii::isSpace(c))
{
in.get();
word += c;
}
return word;
}
std::string Template::readQuery(std::istream& in)
{
std::string word;
int c;
while((c = in.get()) != -1)
{
if ( c == '?' && in.peek() == '>' )
{
in.putback(c);
break;
}
if ( Ascii::isSpace(c) )
{
break;
}
word += c;
}
return word;
}
void Template::readWhiteSpace(std::istream& in)
{
int c;
while((c = in.peek()) != -1 && Ascii::isSpace(c))
{
in.get();
}
}
std::string Template::readString(std::istream& in)
{
std::string str;
int c = in.get();
if ( c == '"' )
{
while((c = in.get()) != -1 && c != '"')
{
str += c;
}
}
return str;
}
void Template::render(const DynamicAny& data, std::ostream& out) const
{
_parts->render(data, out);
}
}} // Namespace Poco::JSON

172
JSON/src/TemplateCache.cpp Normal file
View File

@ -0,0 +1,172 @@
//
// TemplateCache.cpp
//
// $Id$
//
// Library: JSON
// Package: JSON
// Module: TemplateCache
//
// 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/File.h"
#include "Poco/JSON/TemplateCache.h"
namespace Poco
{
namespace JSON
{
TemplateCache* TemplateCache::_instance = NULL;
TemplateCache::TemplateCache() : _logger(NULL)
{
setup();
}
TemplateCache::~TemplateCache()
{
_instance = NULL;
}
void TemplateCache::setup()
{
poco_assert (_instance == NULL);
_instance = this;
}
Template::Ptr TemplateCache::getTemplate(const Path& path)
{
if ( _logger )
{
poco_trace_f1(*_logger, "Trying to load %s", path.toString());
}
Path templatePath = resolvePath(path);
std::string templatePathname = templatePath.toString();
if ( _logger )
{
poco_trace_f1(*_logger, "Path resolved to %s", templatePathname);
}
File templateFile(templatePathname);
Template::Ptr tpl;
std::map<std::string, Template::Ptr>::iterator it = _cache.find(templatePathname);
if ( it == _cache.end() )
{
if ( templateFile.exists() )
{
if ( _logger )
{
poco_information_f1(*_logger, "Loading template %s", templatePath.toString());
}
tpl = new Template(templatePath);
try
{
tpl->parse();
_cache[templatePathname] = tpl;
}
catch(JSONTemplateException jte)
{
if ( _logger )
{
poco_error_f2(*_logger, "Template %s contains an error: %s", templatePath.toString(), jte.message());
}
}
}
else
{
if ( _logger )
{
poco_error_f1(*_logger, "Template file %s doesn't exist", templatePath.toString());
}
throw FileNotFoundException(templatePathname);
}
}
else
{
tpl = it->second;
if ( tpl->parseTime() < templateFile.getLastModified() )
{
if ( _logger )
{
poco_information_f1(*_logger, "Reloading template %s", templatePath.toString());
}
tpl = new Template(templatePath);
try
{
tpl->parse();
_cache[templatePathname] = tpl;
}
catch(JSONTemplateException jte)
{
if ( _logger )
{
poco_error_f2(*_logger, "Template %s contains an error: %s", templatePath.toString(), jte.message());
}
}
}
}
return tpl;
}
Path TemplateCache::resolvePath(const Path& path) const
{
if ( path.isAbsolute() )
return path;
for(std::vector<Path>::const_iterator it = _includePaths.begin(); it != _includePaths.end(); ++it)
{
Path templatePath(*it, path);
File templateFile(templatePath);
if ( templateFile.exists() )
{
if ( _logger )
{
poco_trace_f2(*_logger, "%s template file resolved to %s", path.toString(), templatePath.toString());
}
return templatePath;
}
if ( _logger )
{
poco_trace_f1(*_logger, "%s doesn't exist", templatePath.toString());
}
}
throw FileNotFoundException(path.toString());
}
}} // Poco::JSON

View File

@ -0,0 +1,807 @@
#include <set>
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/Query.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/JSON/Stringifier.h"
#include "Poco/JSON/DefaultHandler.h"
//#include "Poco/Util/JSONConfiguration.h"
#include "Poco/JSON/Template.h"
#include "Poco/Path.h"
#include "Poco/File.h"
#include "Poco/FileStream.h"
#include "Poco/Glob.h"
#include "CppUnit/TestCase.h"
#include "CppUnit/TestCaller.h"
#include "CppUnit/TestSuite.h"
#include "CppUnit/TestRunner.h"
class JSONTest : public CppUnit::TestCase
{
public:
JSONTest(const std::string& name): CppUnit::TestCase("JSON")
{
}
void setUp()
{
}
void tearDown()
{
}
protected:
void testNullProperty()
{
std::string json = "{ \"test\" : null }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
assert(object->isNull("test"));
Poco::DynamicAny test = object->get("test");
assert(test.isEmpty());
}
void testTrueProperty()
{
std::string json = "{ \"test\" : true }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
Poco::DynamicAny test = object->get("test");
assert(test.type() == typeid(bool));
bool value = test;
assert(value);
}
void testFalseProperty()
{
std::string json = "{ \"test\" : false }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
Poco::DynamicAny test = object->get("test");
assert(test.type() == typeid(bool));
bool value = test;
assert(!value);
}
void testNumberProperty()
{
std::string json = "{ \"test\" : 1969 }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
Poco::DynamicAny test = object->get("test");
assert(test.isInteger());
int value = test;
assert(value == 1969);
}
void testStringProperty()
{
std::string json = "{ \"test\" : \"value\" }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
Poco::DynamicAny test = object->get("test");
assert(test.isString());
std::string value = test;
assert(value.compare("value") == 0);
}
void testEmptyObject()
{
std::string json = "{}";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
assert(object->size() == 0);
}
void testDoubleProperty()
{
std::string json = "{ \"test\" : 123.45 }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
Poco::DynamicAny test = object->get("test");
assert(test.isNumeric());
double value = test;
assert(value == 123.45);
}
void testDouble2Property()
{
std::string json = "{ \"test\" : 12e34 }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
Poco::DynamicAny test = object->get("test");
assert(test.isNumeric());
double value = test;
assert(value == 12e34);
}
void testDouble3Property()
{
std::string json = "{ \"test\" : 12e-34 }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
Poco::DynamicAny test = object->get("test");
assert(test.isNumeric());
double value = test;
assert(value == 12e-34);
}
void testObjectProperty()
{
std::string json = "{ \"test\" : { \"property\" : \"value\" } }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
Poco::DynamicAny test = object->get("test");
assert(test.type() == typeid(Poco::JSON::Object::Ptr));
object = test.extract<Poco::JSON::Object::Ptr>();
test = object->get("property");
assert(test.isString());
std::string value = test;
assert(value.compare("value") == 0);
}
void testEmptyArray()
{
std::string json = "[]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
assert(array->size() == 0);
}
void testNestedArray()
{
std::string json = "[[[[]]]]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
assert(array->size() == 1);
}
void testNullElement()
{
std::string json = "[ null ]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
assert(array->isNull(0));
Poco::DynamicAny test = array->get(0);
assert(test.isEmpty());
}
void testTrueElement()
{
std::string json = "[ true ]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
Poco::DynamicAny test = array->get(0);
assert(test.type() == typeid(bool));
bool value = test;
assert(value);
}
void testFalseElement()
{
std::string json = "[ false ]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
Poco::DynamicAny test = array->get(0);
assert(test.type() == typeid(bool));
bool value = test;
assert(!value);
}
void testNumberElement()
{
std::string json = "[ 1969 ]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
Poco::DynamicAny test = array->get(0);
assert(test.isInteger());
int value = test;
assert(value == 1969);
}
void testStringElement()
{
std::string json = "[ \"value\" ]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
Poco::DynamicAny test = array->get(0);
assert(test.isString());
std::string value = test;
assert(value.compare("value") == 0);
}
void testEmptyObjectElement()
{
std::string json = "[{}]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
Poco::JSON::Object::Ptr object = array->getObject(0);
assert(object->size() == 0);
}
void testDoubleElement()
{
std::string json = "[ 123.45 ]";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Array::Ptr));
Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
Poco::DynamicAny test = array->get(0);
assert(test.isNumeric());
double value = test;
assert(value == 123.45);
}
void testOptValue()
{
std::string json = "{ }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
int n = object->optValue("test", 123);
assert(n == 123);
}
void testQuery()
{
std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ] }";
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(json);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
assert(result.type() == typeid(Poco::JSON::Object::Ptr));
Poco::JSON::Query query(result);
std::string firstChild = query.findValue("children[0]", "");
assert(firstChild.compare("Jonas") == 0);
}
void testValidJanssonFiles()
{
Poco::Path pathPattern("/home/bronx/Development/mqweb/JSON/testsuite/testfiles/valid/*");
std::set<std::string> paths;
Poco::Glob::glob(pathPattern, paths);
for(std::set<std::string>::iterator it = paths.begin(); it != paths.end(); ++it)
{
Poco::Path filePath(*it, "input");
if ( filePath.isFile() )
{
Poco::File inputFile(filePath);
if ( inputFile.exists() )
{
Poco::FileInputStream fis(filePath.toString());
std::cout << filePath.toString() << std::endl;
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(fis);
result = handler.result();
std::cout << "Ok!" << std::endl;
}
catch(Poco::JSON::JSONException jsone)
{
// We shouldn't get here.
assert(false);
}
}
}
}
}
void testInvalidJanssonFiles()
{
Poco::Path pathPattern("/home/bronx/Development/mqweb/JSON/testsuite/testfiles/invalid/*");
std::set<std::string> paths;
Poco::Glob::glob(pathPattern, paths);
for(std::set<std::string>::iterator it = paths.begin(); it != paths.end(); ++it)
{
Poco::Path filePath(*it, "input");
if ( filePath.isFile() )
{
Poco::File inputFile(filePath);
if ( inputFile.exists() )
{
Poco::FileInputStream fis(filePath.toString());
std::cout << filePath.toString() << std::endl;
Poco::JSON::Parser parser;
Poco::DynamicAny result;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(fis);
result = handler.result();
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << "Exception!!! " << jsone.message() << std::endl;
}
}
}
}
}
/*
void testConfiguration()
{
Poco::JSON::Configuration config;
std::string json = "{ \"config\" : "
" { \"prop1\" : \"value1\", "
" \"prop2\" : 10, "
" \"prop3\" : [ \"element1\", \"element2\" ], "
" \"prop4\" : { \"prop5\" : false, "
" \"prop6\" : null } "
"}"
"}";
std::istringstream iss(json);
try
{
config.load(iss);
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message() << std::endl;
assert(false);
}
std::string property1 = config.getString("config.prop1");
assert(property1.compare("value1") == 0);
int property2 = config.getInt("config.prop2");
assert(property2 == 10);
int nonExistingProperty = config.getInt("config.prop7", 5);
assert(nonExistingProperty == 5);
std::string arrProperty = config.getString("config.prop3[1]");
assert(arrProperty.compare("element2") == 0);
bool property35 = config.getBool("config.prop4.prop5");
assert(! property35);
try
{
config.getString("propertyUnknown");
assert(true);
}
catch(Poco::NotFoundException nfe)
{
}
}
*/
void testTemplate()
{
Poco::JSON::Template tpl;
tpl.parse("Hello world! From <?= person.name ?>\n<?if person.toOld ?>You're to old<?endif?>\n");
Poco::JSON::Object::Ptr data = new Poco::JSON::Object();
Poco::JSON::Object::Ptr person = new Poco::JSON::Object();
data->set("person", person);
person->set("name", "Franky");
person->set("toOld", true);
tpl.render(data, std::cout);
}
void testItunes()
{
Poco::FileInputStream fis("/home/bronx/Development/search.json");
Poco::JSON::Parser parser;
try
{
Poco::JSON::DefaultHandler handler;
parser.setHandler(&handler);
parser.parse(fis);
}
catch(Poco::JSON::JSONException jsone)
{
std::cout << jsone.message();
}
}
public:
static CppUnit::Test* suite()
{
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("JSONTest");
CppUnit_addTest(pSuite, JSONTest, testNullProperty);
CppUnit_addTest(pSuite, JSONTest, testTrueProperty);
CppUnit_addTest(pSuite, JSONTest, testFalseProperty);
CppUnit_addTest(pSuite, JSONTest, testNumberProperty);
CppUnit_addTest(pSuite, JSONTest, testStringProperty);
CppUnit_addTest(pSuite, JSONTest, testEmptyObject);
CppUnit_addTest(pSuite, JSONTest, testDoubleProperty);
CppUnit_addTest(pSuite, JSONTest, testDouble2Property);
CppUnit_addTest(pSuite, JSONTest, testDouble3Property);
CppUnit_addTest(pSuite, JSONTest, testObjectProperty);
CppUnit_addTest(pSuite, JSONTest, testEmptyArray);
CppUnit_addTest(pSuite, JSONTest, testNestedArray);
CppUnit_addTest(pSuite, JSONTest, testNullElement);
CppUnit_addTest(pSuite, JSONTest, testTrueElement);
CppUnit_addTest(pSuite, JSONTest, testFalseElement);
CppUnit_addTest(pSuite, JSONTest, testNumberElement);
CppUnit_addTest(pSuite, JSONTest, testStringElement);
CppUnit_addTest(pSuite, JSONTest, testEmptyObjectElement);
CppUnit_addTest(pSuite, JSONTest, testDoubleElement);
CppUnit_addTest(pSuite, JSONTest, testOptValue);
CppUnit_addTest(pSuite, JSONTest, testQuery);
//CppUnit_addTest(pSuite, JSONTest, testValidJanssonFiles);
//CppUnit_addTest(pSuite, JSONTest, testInvalidJanssonFiles);
//CppUnit_addTest(pSuite, JSONTest, testConfiguration);
CppUnit_addTest(pSuite, JSONTest, testTemplate);
//CppUnit_addTest(pSuite, JSONTest, testItunes);
return pSuite;
}
};
CppUnitMain(JSONTest)

View File

@ -0,0 +1 @@
["<22><><EFBFBD> <-- encoded surrogate half"]

View File

@ -0,0 +1 @@
["\u<>"]

View File

@ -0,0 +1 @@
[1e1å]

View File

@ -0,0 +1 @@
[0å]

View File

@ -0,0 +1 @@
["å <-- invalid UTF-8"]

View File

@ -0,0 +1 @@
<EFBFBD>

View File

@ -0,0 +1 @@
["<22><><EFBFBD><EFBFBD>"]

View File

@ -0,0 +1 @@
["<22><><EFBFBD> <-- overlong encoding"]

View File

@ -0,0 +1 @@
["<22><><EFBFBD><EFBFBD> <-- overlong encoding"]

View File

@ -0,0 +1 @@
["<22>"]

View File

@ -0,0 +1 @@
["<22>"]

View File

@ -0,0 +1 @@
["ŕ˙ <-- truncated UTF-8"]

View File

@ -0,0 +1 @@
['

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
{,

View File

@ -0,0 +1 @@
[,

View File

@ -0,0 +1 @@
[1,

View File

@ -0,0 +1 @@
["\u0000 (null byte not allowed)"]

View File

@ -0,0 +1 @@
[1,]

View File

@ -0,0 +1,6 @@
[1,
2,
3,
4,
5,
]

View File

@ -0,0 +1,2 @@
[1,2,3]
foo

View File

@ -0,0 +1 @@
[1,2,3]foo

View File

@ -0,0 +1 @@
[012]

View File

@ -0,0 +1 @@
["\a <-- invalid escape"]

View File

@ -0,0 +1 @@
[troo

View File

@ -0,0 +1 @@
[-123foo]

View File

@ -0,0 +1 @@
[-123.123foo]

View File

@ -0,0 +1 @@
["\uD888\u3210 (first surrogate and invalid second surrogate)"]

View File

@ -0,0 +1 @@
{

View File

@ -0,0 +1 @@
[

View File

@ -0,0 +1 @@
["\uDFAA (second surrogate on it's own)"]

View File

@ -0,0 +1 @@
[-foo]

View File

@ -0,0 +1 @@
null

View File

@ -0,0 +1 @@
{'a'

View File

@ -0,0 +1 @@
{"a":"a" 123}

View File

@ -0,0 +1 @@
{"a"

View File

@ -0,0 +1 @@
{"a":

View File

@ -0,0 +1 @@
{"a":"a

View File

@ -0,0 +1 @@
[1ea]

View File

@ -0,0 +1 @@
[-123123e100000]

View File

@ -0,0 +1 @@
[123123e100000]

View File

@ -0,0 +1 @@
[1e]

View File

@ -0,0 +1 @@
[1.]

View File

@ -0,0 +1 @@
[" <-- tab character"]

View File

@ -0,0 +1 @@
[-123123123123123123123123123123]

View File

@ -0,0 +1 @@
[123123123123123123123123123123]

View File

@ -0,0 +1 @@
["\uDADA (first surrogate without the second)"]

View File

@ -0,0 +1 @@
å

View File

@ -0,0 +1 @@
["a"

View File

@ -0,0 +1 @@
{"

View File

@ -0,0 +1 @@
{"a

View File

@ -0,0 +1 @@
["a

View File

@ -0,0 +1,5 @@
[1,2,3,4,
"a", "b", "c",
{"foo": "bar", "core": "dump"},
true, false, true, true, null, false
]

View File

@ -0,0 +1 @@
[]

View File

@ -0,0 +1 @@
[{}]

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1 @@
[""]

View File

@ -0,0 +1 @@
["\u0012 escaped control character"]

View File

@ -0,0 +1 @@
[false]

View File

@ -0,0 +1 @@
[-123]

View File

@ -0,0 +1 @@
[-1]

View File

@ -0,0 +1 @@
[-0]

View File

@ -0,0 +1 @@
[null]

View File

@ -0,0 +1 @@
["\u002c one-byte UTF-8"]

Some files were not shown because too many files have changed in this diff Show More