mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-20 22:31:23 +01:00
Copy JSON from SandBox to trunk
This commit is contained in:
parent
5a639074d9
commit
95c62c00df
21
JSON/Makefile
Normal file
21
JSON/Makefile
Normal 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
|
358
JSON/include/Poco/JSON/Array.h
Normal file
358
JSON/include/Poco/JSON/Array.h
Normal 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
|
166
JSON/include/Poco/JSON/DefaultHandler.h
Normal file
166
JSON/include/Poco/JSON/DefaultHandler.h
Normal 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
|
106
JSON/include/Poco/JSON/Handler.h
Normal file
106
JSON/include/Poco/JSON/Handler.h
Normal 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
|
80
JSON/include/Poco/JSON/JSON.h
Normal file
80
JSON/include/Poco/JSON/JSON.h
Normal 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
|
55
JSON/include/Poco/JSON/JSONException.h
Normal file
55
JSON/include/Poco/JSON/JSONException.h
Normal 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
|
359
JSON/include/Poco/JSON/Object.h
Normal file
359
JSON/include/Poco/JSON/Object.h
Normal 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
|
140
JSON/include/Poco/JSON/Parser.h
Normal file
140
JSON/include/Poco/JSON/Parser.h
Normal 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
|
118
JSON/include/Poco/JSON/Query.h
Normal file
118
JSON/include/Poco/JSON/Query.h
Normal 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
|
64
JSON/include/Poco/JSON/Stringifier.h
Normal file
64
JSON/include/Poco/JSON/Stringifier.h
Normal 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
|
182
JSON/include/Poco/JSON/Template.h
Normal file
182
JSON/include/Poco/JSON/Template.h
Normal 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
|
139
JSON/include/Poco/JSON/TemplateCache.h
Normal file
139
JSON/include/Poco/JSON/TemplateCache.h
Normal 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
147
JSON/src/Array.cpp
Normal 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
150
JSON/src/DefaultHandler.cpp
Normal 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
48
JSON/src/Handler.cpp
Normal 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
|
44
JSON/src/JSONException.cpp
Normal file
44
JSON/src/JSONException.cpp
Normal 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
155
JSON/src/Object.cpp
Normal 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
678
JSON/src/Parser.cpp
Normal 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
141
JSON/src/Query.cpp
Normal 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
114
JSON/src/Stringifier.cpp
Normal 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
736
JSON/src/Template.cpp
Normal 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
172
JSON/src/TemplateCache.cpp
Normal 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
|
807
JSON/testsuite/src/JSONTest.cpp
Normal file
807
JSON/testsuite/src/JSONTest.cpp
Normal 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)
|
@ -0,0 +1 @@
|
||||
["<22><><EFBFBD> <-- encoded surrogate half"]
|
@ -0,0 +1 @@
|
||||
["\å"]
|
@ -0,0 +1 @@
|
||||
[å]
|
@ -0,0 +1 @@
|
||||
[123å]
|
@ -0,0 +1 @@
|
||||
["\u<>"]
|
@ -0,0 +1 @@
|
||||
[1e1å]
|
@ -0,0 +1 @@
|
||||
[a蘊
|
@ -0,0 +1 @@
|
||||
[0å]
|
@ -0,0 +1 @@
|
||||
[1e蘊
|
@ -0,0 +1 @@
|
||||
["å <-- invalid UTF-8"]
|
@ -0,0 +1 @@
|
||||
<EFBFBD>
|
@ -0,0 +1 @@
|
||||
["<22>"]
|
@ -0,0 +1 @@
|
||||
["<22><><EFBFBD><EFBFBD>"]
|
@ -0,0 +1 @@
|
||||
["<22><><EFBFBD> <-- overlong encoding"]
|
@ -0,0 +1 @@
|
||||
["<22><><EFBFBD><EFBFBD> <-- overlong encoding"]
|
@ -0,0 +1 @@
|
||||
["<22>"]
|
@ -0,0 +1 @@
|
||||
["<22>"]
|
@ -0,0 +1 @@
|
||||
["ŕ˙ <-- truncated UTF-8"]
|
1
JSON/testsuite/testfiles/invalid/apostrophe/input
Normal file
1
JSON/testsuite/testfiles/invalid/apostrophe/input
Normal file
@ -0,0 +1 @@
|
||||
['
|
@ -0,0 +1 @@
|
||||
aå
|
1
JSON/testsuite/testfiles/invalid/brace-comma/input
Normal file
1
JSON/testsuite/testfiles/invalid/brace-comma/input
Normal file
@ -0,0 +1 @@
|
||||
{,
|
1
JSON/testsuite/testfiles/invalid/bracket-comma/input
Normal file
1
JSON/testsuite/testfiles/invalid/bracket-comma/input
Normal file
@ -0,0 +1 @@
|
||||
[,
|
1
JSON/testsuite/testfiles/invalid/bracket-one-comma/input
Normal file
1
JSON/testsuite/testfiles/invalid/bracket-one-comma/input
Normal file
@ -0,0 +1 @@
|
||||
[1,
|
0
JSON/testsuite/testfiles/invalid/empty/input
Normal file
0
JSON/testsuite/testfiles/invalid/empty/input
Normal file
@ -0,0 +1 @@
|
||||
["\u0000 (null byte not allowed)"]
|
@ -0,0 +1 @@
|
||||
[1,]
|
@ -0,0 +1,6 @@
|
||||
[1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
]
|
@ -0,0 +1,2 @@
|
||||
[1,2,3]
|
||||
foo
|
@ -0,0 +1 @@
|
||||
[1,2,3]foo
|
@ -0,0 +1 @@
|
||||
[012]
|
1
JSON/testsuite/testfiles/invalid/invalid-escape/input
Normal file
1
JSON/testsuite/testfiles/invalid/invalid-escape/input
Normal file
@ -0,0 +1 @@
|
||||
["\a <-- invalid escape"]
|
@ -0,0 +1 @@
|
||||
[troo
|
@ -0,0 +1 @@
|
||||
[-123foo]
|
@ -0,0 +1 @@
|
||||
[-123.123foo]
|
@ -0,0 +1 @@
|
||||
["\uD888\u3210 (first surrogate and invalid second surrogate)"]
|
1
JSON/testsuite/testfiles/invalid/lone-open-brace/input
Normal file
1
JSON/testsuite/testfiles/invalid/lone-open-brace/input
Normal file
@ -0,0 +1 @@
|
||||
{
|
1
JSON/testsuite/testfiles/invalid/lone-open-bracket/input
Normal file
1
JSON/testsuite/testfiles/invalid/lone-open-bracket/input
Normal file
@ -0,0 +1 @@
|
||||
[
|
@ -0,0 +1 @@
|
||||
["\uDFAA (second surrogate on it's own)"]
|
@ -0,0 +1 @@
|
||||
[-foo]
|
@ -0,0 +1 @@
|
||||
[-012]
|
BIN
JSON/testsuite/testfiles/invalid/null-byte-in-string/input
Normal file
BIN
JSON/testsuite/testfiles/invalid/null-byte-in-string/input
Normal file
Binary file not shown.
BIN
JSON/testsuite/testfiles/invalid/null-byte-outside-string/input
Normal file
BIN
JSON/testsuite/testfiles/invalid/null-byte-outside-string/input
Normal file
Binary file not shown.
1
JSON/testsuite/testfiles/invalid/null/input
Normal file
1
JSON/testsuite/testfiles/invalid/null/input
Normal file
@ -0,0 +1 @@
|
||||
null
|
@ -0,0 +1 @@
|
||||
{'a'
|
@ -0,0 +1 @@
|
||||
{"a":"a" 123}
|
@ -0,0 +1 @@
|
||||
[{}
|
1
JSON/testsuite/testfiles/invalid/object-no-colon/input
Normal file
1
JSON/testsuite/testfiles/invalid/object-no-colon/input
Normal file
@ -0,0 +1 @@
|
||||
{"a"
|
1
JSON/testsuite/testfiles/invalid/object-no-value/input
Normal file
1
JSON/testsuite/testfiles/invalid/object-no-value/input
Normal file
@ -0,0 +1 @@
|
||||
{"a":
|
@ -0,0 +1 @@
|
||||
{"a":"a
|
@ -0,0 +1 @@
|
||||
[1ea]
|
@ -0,0 +1 @@
|
||||
[-123123e100000]
|
@ -0,0 +1 @@
|
||||
[123123e100000]
|
@ -0,0 +1 @@
|
||||
[1e]
|
@ -0,0 +1 @@
|
||||
[1.]
|
@ -0,0 +1 @@
|
||||
[" <-- tab character"]
|
@ -0,0 +1 @@
|
||||
[-123123123123123123123123123123]
|
@ -0,0 +1 @@
|
||||
[123123123123123123123123123123]
|
@ -0,0 +1 @@
|
||||
["\uDADA (first surrogate without the second)"]
|
@ -0,0 +1 @@
|
||||
å
|
@ -0,0 +1 @@
|
||||
[{
|
@ -0,0 +1 @@
|
||||
["a"
|
@ -0,0 +1 @@
|
||||
{"
|
1
JSON/testsuite/testfiles/invalid/unterminated-key/input
Normal file
1
JSON/testsuite/testfiles/invalid/unterminated-key/input
Normal file
@ -0,0 +1 @@
|
||||
{"a
|
@ -0,0 +1 @@
|
||||
{[
|
@ -0,0 +1 @@
|
||||
["a
|
5
JSON/testsuite/testfiles/valid/complex-array/input
Normal file
5
JSON/testsuite/testfiles/valid/complex-array/input
Normal file
@ -0,0 +1,5 @@
|
||||
[1,2,3,4,
|
||||
"a", "b", "c",
|
||||
{"foo": "bar", "core": "dump"},
|
||||
true, false, true, true, null, false
|
||||
]
|
1
JSON/testsuite/testfiles/valid/empty-array/input
Normal file
1
JSON/testsuite/testfiles/valid/empty-array/input
Normal file
@ -0,0 +1 @@
|
||||
[]
|
@ -0,0 +1 @@
|
||||
[{}]
|
1
JSON/testsuite/testfiles/valid/empty-object/input
Normal file
1
JSON/testsuite/testfiles/valid/empty-object/input
Normal file
@ -0,0 +1 @@
|
||||
{}
|
1
JSON/testsuite/testfiles/valid/empty-string/input
Normal file
1
JSON/testsuite/testfiles/valid/empty-string/input
Normal file
@ -0,0 +1 @@
|
||||
[""]
|
@ -0,0 +1 @@
|
||||
["\u0012 escaped control character"]
|
1
JSON/testsuite/testfiles/valid/false/input
Normal file
1
JSON/testsuite/testfiles/valid/false/input
Normal file
@ -0,0 +1 @@
|
||||
[false]
|
1
JSON/testsuite/testfiles/valid/negative-int/input
Normal file
1
JSON/testsuite/testfiles/valid/negative-int/input
Normal file
@ -0,0 +1 @@
|
||||
[-123]
|
1
JSON/testsuite/testfiles/valid/negative-one/input
Normal file
1
JSON/testsuite/testfiles/valid/negative-one/input
Normal file
@ -0,0 +1 @@
|
||||
[-1]
|
1
JSON/testsuite/testfiles/valid/negative-zero/input
Normal file
1
JSON/testsuite/testfiles/valid/negative-zero/input
Normal file
@ -0,0 +1 @@
|
||||
[-0]
|
1
JSON/testsuite/testfiles/valid/null/input
Normal file
1
JSON/testsuite/testfiles/valid/null/input
Normal file
@ -0,0 +1 @@
|
||||
[null]
|
1
JSON/testsuite/testfiles/valid/one-byte-utf-8/input
Normal file
1
JSON/testsuite/testfiles/valid/one-byte-utf-8/input
Normal 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
Loading…
x
Reference in New Issue
Block a user