mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-11-02 14:03:41 +01:00 
			
		
		
		
	minor improvements to documentation and style
Conflicts: JSON/include/Poco/JSON/Stringifier.h JSON/src/PrintHandler.cpp JSON/src/Stringifier.cpp
This commit is contained in:
		@@ -35,9 +35,9 @@ class Object;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JSON_API Array
 | 
			
		||||
	/// Represents a JSON array. JSON array provides a representation
 | 
			
		||||
	/// Represents a JSON array. Array provides a representation
 | 
			
		||||
	/// based on shared pointers and optimized for performance. It is possible to 
 | 
			
		||||
	/// convert object to Poco::Dynamic::Array. Conversion requires copying and therefore
 | 
			
		||||
	/// convert Array to Poco::Dynamic::Array. Conversion requires copying and therefore
 | 
			
		||||
	/// has performance penalty; the benefit is in improved syntax, eg:
 | 
			
		||||
	/// 
 | 
			
		||||
	///    // use pointers to avoid copying
 | 
			
		||||
@@ -57,7 +57,7 @@ class JSON_API Array
 | 
			
		||||
	///    i = da[0]["test"];     // i == 0
 | 
			
		||||
	///    i = da[1]["test1"][1]; // i == 2
 | 
			
		||||
	///    i = da[1]["test2"];    // i == 4
 | 
			
		||||
	/// 
 | 
			
		||||
	/// ----
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef std::vector<Dynamic::Var>                 ValueVec;
 | 
			
		||||
@@ -66,27 +66,27 @@ public:
 | 
			
		||||
	typedef SharedPtr<Array> Ptr;
 | 
			
		||||
 | 
			
		||||
	Array();
 | 
			
		||||
		/// Default constructor
 | 
			
		||||
		/// Creates an empty Array.
 | 
			
		||||
 | 
			
		||||
	Array(const Array& copy);
 | 
			
		||||
		/// Copy Constructor
 | 
			
		||||
		/// Creates an Array by copying another one.
 | 
			
		||||
 | 
			
		||||
	virtual ~Array();
 | 
			
		||||
		/// Destructor
 | 
			
		||||
		/// Destroys the Array.
 | 
			
		||||
 | 
			
		||||
	ValueVec::const_iterator begin() const;
 | 
			
		||||
		/// Returns iterator
 | 
			
		||||
		/// Returns the begin iterator for values.
 | 
			
		||||
 | 
			
		||||
	ValueVec::const_iterator end() const;
 | 
			
		||||
		/// Returns iterator
 | 
			
		||||
		/// Returns the end iterator for values.
 | 
			
		||||
 | 
			
		||||
	Dynamic::Var get(unsigned int index) const;
 | 
			
		||||
		/// Retrieves an element. Will return an empty value
 | 
			
		||||
		/// when the element doesn't exist.
 | 
			
		||||
		/// Retrieves the element at the given index. 
 | 
			
		||||
		/// 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.
 | 
			
		||||
		/// an Array or doesn't exist, an empty SharedPtr is returned.
 | 
			
		||||
 | 
			
		||||
	template<typename T>
 | 
			
		||||
	T getElement(unsigned int index) const
 | 
			
		||||
@@ -104,30 +104,30 @@ public:
 | 
			
		||||
		/// Retrieves an object. When the element is not
 | 
			
		||||
		/// an object or doesn't exist, an empty SharedPtr is returned.
 | 
			
		||||
 | 
			
		||||
	std::size_t  size() const;
 | 
			
		||||
		/// Returns the size of the array
 | 
			
		||||
	std::size_t size() const;
 | 
			
		||||
		/// Returns the size of the array.
 | 
			
		||||
 | 
			
		||||
	bool isArray(unsigned int index) const;
 | 
			
		||||
		/// Returns true when the element is an array
 | 
			
		||||
		/// Returns true when the element is an array.
 | 
			
		||||
 | 
			
		||||
	bool isArray(const Dynamic::Var& value) const;
 | 
			
		||||
		/// Returns true when the element is an array
 | 
			
		||||
		/// Returns true when the element is an array.
 | 
			
		||||
 | 
			
		||||
	bool isArray(ConstIterator& value) const;
 | 
			
		||||
		/// Returns true when the element is an array
 | 
			
		||||
		/// 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
 | 
			
		||||
		/// Returns true when the element is an object.
 | 
			
		||||
 | 
			
		||||
	bool isObject(const Dynamic::Var& value) const;
 | 
			
		||||
		/// Returns true when the element is an object
 | 
			
		||||
		/// Returns true when the element is an object.
 | 
			
		||||
 | 
			
		||||
	bool isObject(ConstIterator& value) const;
 | 
			
		||||
		/// Returns true when the element is an object
 | 
			
		||||
		/// Returns true when the element is an object.
 | 
			
		||||
 | 
			
		||||
	template<typename T>
 | 
			
		||||
	T optElement(unsigned int index, const T& def) const
 | 
			
		||||
@@ -137,13 +137,13 @@ public:
 | 
			
		||||
		/// value will be returned
 | 
			
		||||
	{
 | 
			
		||||
		T value = def;
 | 
			
		||||
		if ( index < _values.size() )
 | 
			
		||||
		if (index < _values.size())
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				value = _values[index].convert<T>();
 | 
			
		||||
			}
 | 
			
		||||
			catch(...)
 | 
			
		||||
			catch (...)
 | 
			
		||||
			{
 | 
			
		||||
				// Default value is returned.
 | 
			
		||||
			}
 | 
			
		||||
@@ -180,6 +180,9 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// inlines
 | 
			
		||||
//
 | 
			
		||||
inline Array::ValueVec::const_iterator Array::begin() const
 | 
			
		||||
{
 | 
			
		||||
	return _values.begin();
 | 
			
		||||
@@ -236,7 +239,8 @@ inline void Array::remove(unsigned int index)
 | 
			
		||||
	_values.erase(_values.begin() + index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}} // Namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Poco {
 | 
			
		||||
@@ -521,7 +525,7 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::Dynamic
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_Array_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -31,39 +31,44 @@ namespace JSON {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JSON_API Handler
 | 
			
		||||
	/// Interface for handling parsing events generated by the JSON Parser.
 | 
			
		||||
	///
 | 
			
		||||
	/// An application can implement a subclass of Handler to implement
 | 
			
		||||
	/// callback-based parsing of a JSON document, similar to how a SAX
 | 
			
		||||
	/// parser would handle XML.
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef SharedPtr<Handler> Ptr;
 | 
			
		||||
 | 
			
		||||
	Handler();
 | 
			
		||||
		/// Constructor;
 | 
			
		||||
		/// Creates an empty Handler.
 | 
			
		||||
	
 | 
			
		||||
	virtual ~Handler();
 | 
			
		||||
		/// Destructor
 | 
			
		||||
		/// Destroys the Handler.
 | 
			
		||||
 | 
			
		||||
	virtual void reset() = 0;
 | 
			
		||||
		/// Resets the handler state.
 | 
			
		||||
 | 
			
		||||
	virtual void startObject() = 0;
 | 
			
		||||
		/// The parser has read a {, meaning a new object will be read
 | 
			
		||||
		/// The parser has read a {, meaning a new object will be read.
 | 
			
		||||
 | 
			
		||||
	virtual void endObject() = 0;
 | 
			
		||||
		/// The parser has read a }, meaning the object is read
 | 
			
		||||
		/// 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
 | 
			
		||||
		/// 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
 | 
			
		||||
		/// 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
 | 
			
		||||
		/// A key of an object is read.
 | 
			
		||||
 | 
			
		||||
	virtual void null() = 0;
 | 
			
		||||
		/// A null value is read
 | 
			
		||||
		/// A null value is read.
 | 
			
		||||
 | 
			
		||||
	virtual void value(int v) = 0;
 | 
			
		||||
		/// An integer value is read
 | 
			
		||||
		/// An integer value is read.
 | 
			
		||||
 | 
			
		||||
	virtual void value(unsigned v) = 0;
 | 
			
		||||
		/// An unsigned value is read. This will only be triggered if the
 | 
			
		||||
@@ -71,7 +76,7 @@ public:
 | 
			
		||||
 | 
			
		||||
#if defined(POCO_HAVE_INT64)
 | 
			
		||||
	virtual void value(Int64 v) = 0;
 | 
			
		||||
		/// A 64-bit integer value is read
 | 
			
		||||
		/// A 64-bit integer value is read.
 | 
			
		||||
 | 
			
		||||
	virtual void value(UInt64 v) = 0;
 | 
			
		||||
		/// An unsigned 64-bit integer value is read. This will only be
 | 
			
		||||
@@ -82,10 +87,10 @@ public:
 | 
			
		||||
		/// A string value is read.
 | 
			
		||||
 | 
			
		||||
	virtual void value(double d) = 0;
 | 
			
		||||
		/// A double value is read
 | 
			
		||||
		/// A double value is read.
 | 
			
		||||
 | 
			
		||||
	virtual void value(bool b) = 0;
 | 
			
		||||
		/// A boolean value is read
 | 
			
		||||
		/// A boolean value is read.
 | 
			
		||||
 | 
			
		||||
	virtual Poco::Dynamic::Var asVar() const;
 | 
			
		||||
		/// Returns the result of the parser (an object, array or string),
 | 
			
		||||
@@ -97,7 +102,7 @@ public:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_Handler_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ namespace JSON {
 | 
			
		||||
POCO_DECLARE_EXCEPTION(JSON_API, JSONException, Poco::Exception)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif //JSON_JSONException_INCLUDED
 | 
			
		||||
#endif // JSON_JSONException_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -39,9 +39,9 @@ namespace JSON {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JSON_API Object
 | 
			
		||||
	/// Represents a JSON object. JSON object provides a representation
 | 
			
		||||
	/// Represents a JSON object. Object provides a representation
 | 
			
		||||
	/// based on shared pointers and optimized for performance. It is possible to 
 | 
			
		||||
	/// convert object to DynamicStruct. Conversion requires copying and therefore
 | 
			
		||||
	/// convert Object to DynamicStruct. Conversion requires copying and therefore
 | 
			
		||||
	/// has performance penalty; the benefit is in improved syntax, eg:
 | 
			
		||||
	/// 
 | 
			
		||||
	///    std::string json = "{ \"test\" : { \"property\" : \"value\" } }";
 | 
			
		||||
@@ -58,7 +58,7 @@ class JSON_API Object
 | 
			
		||||
	///    // copy/convert to Poco::DynamicStruct
 | 
			
		||||
	///    Poco::DynamicStruct ds = *object;
 | 
			
		||||
	///    val = ds["test"]["property"]; // val holds "value"
 | 
			
		||||
	/// 
 | 
			
		||||
	/// ----
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef SharedPtr<Object>                   Ptr;
 | 
			
		||||
@@ -68,16 +68,19 @@ public:
 | 
			
		||||
	typedef ValueMap::const_iterator            ConstIterator;
 | 
			
		||||
 | 
			
		||||
	explicit Object(bool preserveInsertionOrder = false);
 | 
			
		||||
		/// Default constructor. If preserveInsertionOrder, object
 | 
			
		||||
		/// will preserve the items insertion order. Otherwise, items
 | 
			
		||||
		/// will be sorted by keys.
 | 
			
		||||
		/// Creates an empty Object.
 | 
			
		||||
		///
 | 
			
		||||
		/// If preserveInsertionOrder, object will preserve the items insertion 
 | 
			
		||||
		/// order. Otherwise, items will be sorted by keys.
 | 
			
		||||
 | 
			
		||||
	Object(const Object& copy);
 | 
			
		||||
		/// Copy constructor. Struct is not copied to keep the operation as
 | 
			
		||||
		/// Creates an Object by copying another one.
 | 
			
		||||
		///
 | 
			
		||||
		/// Struct is not copied to keep the operation as
 | 
			
		||||
		/// efficient as possible (when needed, it will be generated upon request).
 | 
			
		||||
 | 
			
		||||
	virtual ~Object();
 | 
			
		||||
		/// Destroys Object.
 | 
			
		||||
		/// Destroys the Object.
 | 
			
		||||
 | 
			
		||||
	Iterator begin()
 | 
			
		||||
	{
 | 
			
		||||
@@ -117,7 +120,7 @@ public:
 | 
			
		||||
	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
 | 
			
		||||
		/// The convert<T>() method of Var is called
 | 
			
		||||
		/// which can also throw exceptions for invalid values.
 | 
			
		||||
		/// Note: This will not work for an array or an object.
 | 
			
		||||
	{
 | 
			
		||||
@@ -129,8 +132,8 @@ public:
 | 
			
		||||
	Poco::Nullable<T> getNullableValue(const std::string& key) const
 | 
			
		||||
		/// Retrieves the property with the given name and will
 | 
			
		||||
		/// try to convert the value to the given template type.
 | 
			
		||||
		/// Returns null if isNull.
 | 
			
		||||
		/// The convert<T> method of Dynamic is called
 | 
			
		||||
		/// 
 | 
			
		||||
		/// The convert<T> method of Var is called
 | 
			
		||||
		/// which can also throw exceptions for invalid values.
 | 
			
		||||
		/// Note: This will not work for an array or an object.
 | 
			
		||||
	{
 | 
			
		||||
@@ -142,25 +145,25 @@ public:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void getNames(std::vector<std::string>& names) const;
 | 
			
		||||
		/// Returns all property names
 | 
			
		||||
		/// Returns all property names.
 | 
			
		||||
 | 
			
		||||
	bool has(const std::string& key) const;
 | 
			
		||||
		/// Returns true when the given property exists
 | 
			
		||||
		/// Returns true when the given property exists.
 | 
			
		||||
 | 
			
		||||
	bool isArray(const std::string& key) const;
 | 
			
		||||
		/// Returns true when the given property contains an array
 | 
			
		||||
		/// Returns true when the given property contains an array.
 | 
			
		||||
 | 
			
		||||
	bool isArray(ConstIterator& it) const;
 | 
			
		||||
		/// Returns true when the given property contains an array
 | 
			
		||||
		/// 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
 | 
			
		||||
		/// 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
 | 
			
		||||
		/// Returns true when the given property contains an object.
 | 
			
		||||
 | 
			
		||||
	bool isObject(ConstIterator& it) const;
 | 
			
		||||
		/// Returns true when the given property contains an object
 | 
			
		||||
		/// Returns true when the given property contains an object.
 | 
			
		||||
 | 
			
		||||
	template<typename T>
 | 
			
		||||
	T optValue(const std::string& key, const T& def) const
 | 
			
		||||
@@ -170,13 +173,13 @@ public:
 | 
			
		||||
	{
 | 
			
		||||
		T value = def;
 | 
			
		||||
		ValueMap::const_iterator it = _values.find(key);
 | 
			
		||||
		if (it != _values.end() && ! it->second.isEmpty() )
 | 
			
		||||
		if (it != _values.end() && ! it->second.isEmpty())
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				value = it->second.convert<T>();
 | 
			
		||||
			}
 | 
			
		||||
			catch(...)
 | 
			
		||||
			catch (...)
 | 
			
		||||
			{
 | 
			
		||||
				// The default value will be returned
 | 
			
		||||
			}
 | 
			
		||||
@@ -185,17 +188,19 @@ public:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::size_t size() const;
 | 
			
		||||
		/// Returns the number of properties
 | 
			
		||||
		/// Returns the number of properties.
 | 
			
		||||
 | 
			
		||||
	void set(const std::string& key, const Dynamic::Var& value);
 | 
			
		||||
		/// Sets a new value
 | 
			
		||||
		/// Sets a new value.
 | 
			
		||||
 | 
			
		||||
	void stringify(std::ostream& out, unsigned int indent = 0, int step = -1) const;
 | 
			
		||||
		/// Prints the object to out stream. When indent is 0, the object
 | 
			
		||||
		/// will be printed on a single line without indentation.
 | 
			
		||||
		/// Prints the object to out stream. 
 | 
			
		||||
		///
 | 
			
		||||
		/// When indent is 0, the object will be printed on a single 
 | 
			
		||||
		/// line without indentation.
 | 
			
		||||
 | 
			
		||||
	void remove(const std::string& key);
 | 
			
		||||
		/// Removes the property with the given key
 | 
			
		||||
		/// Removes the property with the given key.
 | 
			
		||||
 | 
			
		||||
	static Poco::DynamicStruct makeStruct(const Object::Ptr& obj);
 | 
			
		||||
		/// Utility function for creation of struct.
 | 
			
		||||
@@ -204,8 +209,9 @@ public:
 | 
			
		||||
		/// Cast operator to Poco::DynamiStruct.
 | 
			
		||||
 | 
			
		||||
	void clear();
 | 
			
		||||
		/// Clears the contents of the object. Insertion order 
 | 
			
		||||
		/// preservation property is left intact.
 | 
			
		||||
		/// Clears the contents of the object.
 | 
			
		||||
		///
 | 
			
		||||
		/// Insertion order preservation property is left intact.
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	template <typename C>
 | 
			
		||||
@@ -219,7 +225,7 @@ private:
 | 
			
		||||
		typename C::const_iterator end = container.end();
 | 
			
		||||
		for (; it != end;)
 | 
			
		||||
		{
 | 
			
		||||
			for(unsigned int i = 0; i < indent; i++) out << ' ';
 | 
			
		||||
			for (unsigned int i = 0; i < indent; i++) out << ' ';
 | 
			
		||||
 | 
			
		||||
			Stringifier::stringify(getKey(it), out);
 | 
			
		||||
			out << ((indent > 0) ? " : " : ":");
 | 
			
		||||
@@ -233,8 +239,7 @@ private:
 | 
			
		||||
 | 
			
		||||
		if (indent >= step) indent -= step;
 | 
			
		||||
 | 
			
		||||
		for (unsigned int i = 0; i < indent; i++)
 | 
			
		||||
			out << ' ';
 | 
			
		||||
		for (unsigned int i = 0; i < indent; i++) out << ' ';
 | 
			
		||||
 | 
			
		||||
		out << '}';
 | 
			
		||||
	}
 | 
			
		||||
@@ -254,6 +259,9 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// inlines
 | 
			
		||||
//
 | 
			
		||||
inline bool Object::has(const std::string& key) const
 | 
			
		||||
{
 | 
			
		||||
	ValueMap::const_iterator it = _values.find(key);
 | 
			
		||||
@@ -341,7 +349,7 @@ inline const Dynamic::Var& Object::getValue(KeyPtrList::const_iterator& it) cons
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // Namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Poco {
 | 
			
		||||
@@ -632,7 +640,7 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::Dynamic
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_Object_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -28,14 +28,19 @@ namespace Poco {
 | 
			
		||||
namespace JSON {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JSON_API ParseHandler : public Handler
 | 
			
		||||
	/// Provides a default handler for the JSON parser.
 | 
			
		||||
	/// This handler will build up an object or array based
 | 
			
		||||
	/// on the handlers called by the parser.
 | 
			
		||||
class JSON_API ParseHandler: public Handler
 | 
			
		||||
	/// ParseHandler is the default handler for the JSON Parser.
 | 
			
		||||
	///
 | 
			
		||||
	/// This handler will construct an Object or Array based
 | 
			
		||||
	/// on the handlers called by the Parser.
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	ParseHandler(bool preserveObjectOrder = false);
 | 
			
		||||
		/// Creates the ParseHandler.
 | 
			
		||||
		///
 | 
			
		||||
		/// If preserveObjectOrder is true, the order of properties
 | 
			
		||||
		/// inside objects is preserved. Otherwise, items
 | 
			
		||||
		/// will be sorted by keys.
 | 
			
		||||
 | 
			
		||||
	virtual ~ParseHandler();
 | 
			
		||||
		/// Destroys the ParseHandler.
 | 
			
		||||
@@ -100,6 +105,9 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// inlines
 | 
			
		||||
//
 | 
			
		||||
inline Dynamic::Var ParseHandler::asVar() const
 | 
			
		||||
{
 | 
			
		||||
	return _result;
 | 
			
		||||
@@ -157,11 +165,7 @@ inline void ParseHandler::null()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef ParseHandler ParseHandler;
 | 
			
		||||
//@ deprecated
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_ParseHandler_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
// SPDX-License-Identifier:	BSL-1.0
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2005 JSON.org
 | 
			
		||||
 | 
			
		||||
@@ -39,6 +40,7 @@ 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
 | 
			
		||||
 | 
			
		||||
@@ -58,22 +60,34 @@ namespace JSON {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JSON_API Parser
 | 
			
		||||
	/// A RFC 4627 compatible class for parsing JSON strings or streams.
 | 
			
		||||
	/// A parser for reading RFC 4627 compliant JSON from strings or streams.
 | 
			
		||||
	/// 
 | 
			
		||||
	/// See http://www.ietf.org/rfc/rfc4627.txt for specification.
 | 
			
		||||
	/// 
 | 
			
		||||
	/// Usage example:
 | 
			
		||||
	/// Simple usage example:
 | 
			
		||||
	/// 
 | 
			
		||||
	///    std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ] }";
 | 
			
		||||
	///    Parser parser;
 | 
			
		||||
	///    Var result = parser.parse(json);
 | 
			
		||||
	///    // ... use result
 | 
			
		||||
	///    // ... use result (see next example)
 | 
			
		||||
	///    parser.reset();
 | 
			
		||||
	///    std::ostringstream ostr;
 | 
			
		||||
	///    PrintHandler::Ptr pHandler = new PrintHandler(ostr);
 | 
			
		||||
	///    parser.setHandler(pHandler);
 | 
			
		||||
	///    parser.parse(json); // ostr.str() == json
 | 
			
		||||
	/// ----
 | 
			
		||||
	///
 | 
			
		||||
	/// The result of parsing a valid JSON document will be either an Object
 | 
			
		||||
	/// or an Array. Therefore the result of parse() is a Poco::Dynamic::Var
 | 
			
		||||
	/// containing a Poco::SharedPtr to an Object or Array instance.
 | 
			
		||||
	///
 | 
			
		||||
	/// Example:
 | 
			
		||||
	/// 
 | 
			
		||||
	///    std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ] }";
 | 
			
		||||
	///    Parser parser;
 | 
			
		||||
	///    Var result = parser.parse(json);
 | 
			
		||||
	///    Object::Ptr object = result.extract<Object::Ptr>();
 | 
			
		||||
	///    std::string name = object.getValue<std::string>("name");
 | 
			
		||||
	///    Array::Ptr children = object.getArray("children");
 | 
			
		||||
	/// ----
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef std::char_traits<char> CharTraits;
 | 
			
		||||
@@ -201,7 +215,7 @@ public:
 | 
			
		||||
	static const int         JSON_UNLIMITED_DEPTH = -1;
 | 
			
		||||
 | 
			
		||||
	Parser(const Handler::Ptr& pHandler = new ParseHandler, std::size_t bufSize = JSON_PARSE_BUFFER_SIZE);
 | 
			
		||||
		/// Creates JSON Parser.
 | 
			
		||||
		/// Creates JSON Parser, using the given Handler and buffer size.
 | 
			
		||||
 | 
			
		||||
	virtual ~Parser();
 | 
			
		||||
		/// Destroys JSON Parser.
 | 
			
		||||
@@ -210,17 +224,21 @@ public:
 | 
			
		||||
		/// Resets the parser.
 | 
			
		||||
 | 
			
		||||
	void setAllowComments(bool comments);
 | 
			
		||||
		/// Allow comments. By default, comments are not allowed.
 | 
			
		||||
		/// Allow or disallow comments. By default, comments are not allowed.
 | 
			
		||||
 | 
			
		||||
	bool getAllowComments() const;
 | 
			
		||||
		/// Returns true if comments are allowed, false otherwise.
 | 
			
		||||
		///
 | 
			
		||||
		/// By default, comments are not allowed.
 | 
			
		||||
		
 | 
			
		||||
	void setAllowNullByte(bool nullByte);
 | 
			
		||||
		/// Allow null byte in strings. By default, null byte is allowed.
 | 
			
		||||
		/// Allow or disallow null byte in strings. 
 | 
			
		||||
		///
 | 
			
		||||
		/// By default, null byte is allowed.
 | 
			
		||||
 | 
			
		||||
	bool getAllowNullByte() const;
 | 
			
		||||
		/// Returns true if null byte is allowed, false otherwise.
 | 
			
		||||
		///
 | 
			
		||||
		/// By default, null bytes are allowed.
 | 
			
		||||
 | 
			
		||||
	void setDepth(std::size_t depth);
 | 
			
		||||
@@ -230,16 +248,16 @@ public:
 | 
			
		||||
		/// Returns the allowed JSON depth.
 | 
			
		||||
 | 
			
		||||
	Dynamic::Var parse(const std::string& json);
 | 
			
		||||
		/// Parses a string.
 | 
			
		||||
		/// Parses JSON from a string.
 | 
			
		||||
 | 
			
		||||
	Dynamic::Var parse(std::istream& in);
 | 
			
		||||
		/// Parses a JSON from the input stream.
 | 
			
		||||
		/// Parses JSON from an input stream.
 | 
			
		||||
 | 
			
		||||
	void setHandler(const Handler::Ptr& pHandler);
 | 
			
		||||
		/// Set the handler.
 | 
			
		||||
		/// Set the Handler.
 | 
			
		||||
 | 
			
		||||
	const Handler::Ptr& getHandler();
 | 
			
		||||
		/// Returns the handler.
 | 
			
		||||
		/// Returns the Handler.
 | 
			
		||||
 | 
			
		||||
	Dynamic::Var asVar() const;
 | 
			
		||||
		/// Returns the result of parsing;
 | 
			
		||||
@@ -261,23 +279,14 @@ private:
 | 
			
		||||
		/// Returns false if there is underflow or if the modes mismatch.
 | 
			
		||||
 | 
			
		||||
	void growBuffer();
 | 
			
		||||
 | 
			
		||||
	void clearBuffer();
 | 
			
		||||
 | 
			
		||||
	void parseBufferPushBackChar(char c);
 | 
			
		||||
 | 
			
		||||
	void parseBufferPopBackChar();
 | 
			
		||||
 | 
			
		||||
	void addCharToParseBuffer(CharIntType nextChar, int nextClass);
 | 
			
		||||
 | 
			
		||||
	void addEscapedCharToParseBuffer(CharIntType nextChar);
 | 
			
		||||
 | 
			
		||||
	CharIntType decodeUnicodeChar();
 | 
			
		||||
 | 
			
		||||
	void assertNotStringNullBool();
 | 
			
		||||
 | 
			
		||||
	void assertNonContainer();
 | 
			
		||||
 | 
			
		||||
	void parseBuffer();
 | 
			
		||||
 | 
			
		||||
	template <typename IT>
 | 
			
		||||
@@ -315,7 +324,7 @@ private:
 | 
			
		||||
		unsigned char ch = static_cast<unsigned char>(CharTraits::to_char_type(nextChar));
 | 
			
		||||
 | 
			
		||||
		// Determine the character's class.
 | 
			
		||||
		if ((!_allowNullByte && ch == 0)) return false;
 | 
			
		||||
		if (!_allowNullByte && ch == 0) return false;
 | 
			
		||||
		if (ch >= 0x80)
 | 
			
		||||
		{
 | 
			
		||||
			nextClass = C_ETC;
 | 
			
		||||
@@ -327,7 +336,7 @@ private:
 | 
			
		||||
 | 
			
		||||
			char buffer[4];
 | 
			
		||||
			buffer[0] = nextChar;
 | 
			
		||||
			for(int i = 1; i < count; ++i)
 | 
			
		||||
			for (int i = 1; i < count; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				int c = 0;
 | 
			
		||||
				if (!source.nextChar(c)) throw Poco::JSON::JSONException("Invalid UTF8 sequence found");
 | 
			
		||||
@@ -339,7 +348,7 @@ private:
 | 
			
		||||
				throw Poco::JSON::JSONException("No legal UTF8 found");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < count; ++i)
 | 
			
		||||
			for (int i = 0; i < count; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				parseBufferPushBackChar(buffer[i]);
 | 
			
		||||
			}
 | 
			
		||||
@@ -366,7 +375,7 @@ private:
 | 
			
		||||
			{
 | 
			
		||||
			// Unicode character 
 | 
			
		||||
			case UC:
 | 
			
		||||
				if(!decodeUnicodeChar()) return false;
 | 
			
		||||
				if (!decodeUnicodeChar()) return false;
 | 
			
		||||
				// check if we need to read a second UTF-16 char
 | 
			
		||||
				if (_utf16HighSurrogate) _state = D1;
 | 
			
		||||
				else _state = ST;
 | 
			
		||||
@@ -449,7 +458,7 @@ private:
 | 
			
		||||
				{
 | 
			
		||||
				case MODE_ARRAY:
 | 
			
		||||
					case MODE_OBJECT:
 | 
			
		||||
						switch(_state)
 | 
			
		||||
						switch (_state)
 | 
			
		||||
						{
 | 
			
		||||
						case VA:
 | 
			
		||||
						case AR:
 | 
			
		||||
@@ -591,8 +600,10 @@ private:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool done();
 | 
			
		||||
 | 
			
		||||
	static CharIntType utf8CheckFirst(char byte);
 | 
			
		||||
	bool isHighSurrogate(unsigned uc);
 | 
			
		||||
	bool isLowSurrogate(unsigned uc);
 | 
			
		||||
	unsigned decodeSurrogatePair(unsigned hi, unsigned lo);
 | 
			
		||||
 | 
			
		||||
	static const int _asciiClass[128];
 | 
			
		||||
		/// This array maps the 128 ASCII characters into character classes.
 | 
			
		||||
@@ -602,10 +613,6 @@ private:
 | 
			
		||||
	static const int _stateTransitionTable[NR_STATES][NR_CLASSES];
 | 
			
		||||
	static const int xx = -1;
 | 
			
		||||
 | 
			
		||||
	bool isHighSurrogate(unsigned uc);
 | 
			
		||||
	bool isLowSurrogate(unsigned uc);
 | 
			
		||||
	unsigned decodeSurrogatePair(unsigned hi, unsigned lo);
 | 
			
		||||
 | 
			
		||||
	Handler::Ptr   _pHandler;
 | 
			
		||||
	signed char    _state;
 | 
			
		||||
	signed char    _beforeCommentState;
 | 
			
		||||
@@ -623,6 +630,9 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// inlines
 | 
			
		||||
//
 | 
			
		||||
inline void Parser::setAllowComments(bool comments)
 | 
			
		||||
{
 | 
			
		||||
	_allowComments = comments;
 | 
			
		||||
@@ -735,7 +745,7 @@ inline unsigned Parser::decodeSurrogatePair(unsigned hi, unsigned lo)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_JSONParser_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -28,10 +28,10 @@ namespace Poco {
 | 
			
		||||
namespace JSON {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JSON_API PrintHandler : public Handler
 | 
			
		||||
class JSON_API PrintHandler: public Handler
 | 
			
		||||
	/// PrintHandler formats and prints the JSON object
 | 
			
		||||
	/// to either user-provided std::ostream or standard out.
 | 
			
		||||
	/// If indent i zero, the output is condensed JSON string,
 | 
			
		||||
	/// to either user-provided std::ostream or standard output.
 | 
			
		||||
	/// If indent is zero, the output is a condensed JSON string,
 | 
			
		||||
	/// otherwise, the proper indentation is applied to elements.
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
@@ -104,7 +104,6 @@ public:
 | 
			
		||||
		/// Sets indentation.
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	const char* endLine() const;
 | 
			
		||||
	unsigned indent();
 | 
			
		||||
	bool printFlat() const;
 | 
			
		||||
@@ -119,6 +118,9 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// inlines
 | 
			
		||||
//
 | 
			
		||||
inline void PrintHandler::setIndent(unsigned indent)
 | 
			
		||||
{
 | 
			
		||||
	_indent = indent;
 | 
			
		||||
@@ -131,8 +133,7 @@ inline bool PrintHandler::array() const
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_PrintHandler_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
// SPDX-License-Identifier:	BSL-1.0
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef JSON_JSONQuery_INCLUDED
 | 
			
		||||
#define JSON_JSONQuery_INCLUDED
 | 
			
		||||
 | 
			
		||||
@@ -33,44 +34,56 @@ class JSON_API Query
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	Query(const Dynamic::Var& source);
 | 
			
		||||
		/// Creates the Query; source must be JSON Object, Array, Object::Ptr,
 | 
			
		||||
		/// Creates a Query/
 | 
			
		||||
		///
 | 
			
		||||
		/// Source must be JSON Object, Array, Object::Ptr,
 | 
			
		||||
		/// Array::Ptr or empty Var. Any other type will trigger throwing of 
 | 
			
		||||
		/// InvalidArgumentException.
 | 
			
		||||
		///
 | 
			
		||||
		/// Creating Query holding Ptr will typically result in faster
 | 
			
		||||
		/// performance.
 | 
			
		||||
 | 
			
		||||
	virtual ~Query();
 | 
			
		||||
		/// Destructor
 | 
			
		||||
		/// Destroys the Query.
 | 
			
		||||
 | 
			
		||||
	Object::Ptr findObject(const std::string& path) const;
 | 
			
		||||
		/// Search for an object. When the object can't be found, a zero Ptr
 | 
			
		||||
		/// is returned; otherwise, a shared pointer to internally held object
 | 
			
		||||
		/// Search for an object. 
 | 
			
		||||
		///
 | 
			
		||||
		/// When the object can't be found, a zero Ptr is returned; 
 | 
			
		||||
		/// otherwise, a shared pointer to internally held object
 | 
			
		||||
		/// is returned.
 | 
			
		||||
		/// If object (as opposed to a pointer to object) is held
 | 
			
		||||
		/// internally, a shared pointer to new (heap-allocated) Object is
 | 
			
		||||
		/// returned; this may be expensive operation.
 | 
			
		||||
 | 
			
		||||
	Object& findObject(const std::string& path, Object& obj) const;
 | 
			
		||||
		/// Search for an object. If object is found, it is assigned to the
 | 
			
		||||
		/// Search for an object. 
 | 
			
		||||
		///
 | 
			
		||||
		/// If object is found, it is assigned to the
 | 
			
		||||
		/// Object through the reference passed in. When the object can't be 
 | 
			
		||||
		/// found, the provided Object is emptied and returned.
 | 
			
		||||
 | 
			
		||||
	Array::Ptr findArray(const std::string& path) const;
 | 
			
		||||
		/// Search for an array. When the array can't be found, a zero Ptr
 | 
			
		||||
		/// is returned; otherwise, a shared pointer to internally held array
 | 
			
		||||
		/// Search for an array. 
 | 
			
		||||
		///
 | 
			
		||||
		/// When the array can't be found, a zero Ptr is returned; 
 | 
			
		||||
		/// otherwise, a shared pointer to internally held array
 | 
			
		||||
		/// is returned.
 | 
			
		||||
		/// If array (as opposed to a pointer to array) is held
 | 
			
		||||
		/// internally, a shared pointer to new (heap-allocated) Object is
 | 
			
		||||
		/// returned; this may be expensive operation.
 | 
			
		||||
 | 
			
		||||
	Array& findArray(const std::string& path, Array& obj) const;
 | 
			
		||||
		/// Search for an array. If array is found, it is assigned to the
 | 
			
		||||
		/// Search for an array. 
 | 
			
		||||
		///
 | 
			
		||||
		/// If array is found, it is assigned to the
 | 
			
		||||
		/// Object through the reference passed in. When the array can't be 
 | 
			
		||||
		/// found, the provided Object is emptied and returned.
 | 
			
		||||
 | 
			
		||||
	Dynamic::Var find(const std::string& path) const;
 | 
			
		||||
		/// Searches a value
 | 
			
		||||
		/// For example: "person.children[0].name" will return the
 | 
			
		||||
		/// Searches a value.
 | 
			
		||||
		///
 | 
			
		||||
		/// 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.
 | 
			
		||||
 | 
			
		||||
@@ -82,13 +95,15 @@ public:
 | 
			
		||||
	{
 | 
			
		||||
		T result = def;
 | 
			
		||||
		Dynamic::Var value = find(path);
 | 
			
		||||
		if ( ! value.isEmpty() )
 | 
			
		||||
		if (!value.isEmpty())
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				result = value.convert<T>();
 | 
			
		||||
			}
 | 
			
		||||
			catch(...) { }
 | 
			
		||||
			catch (...) 
 | 
			
		||||
			{ 
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
@@ -106,7 +121,7 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_JSONQuery_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -30,15 +30,17 @@ namespace JSON {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JSON_API Stringifier
 | 
			
		||||
	/// Helper class for creating a String from a JSON object or array
 | 
			
		||||
	/// Helper class for creating a string from a JSON object or array.
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	static void condense(const Dynamic::Var& any, std::ostream& out);
 | 
			
		||||
		/// Writes a condensed string representation of the value to the output stream while preserving the insertion order.
 | 
			
		||||
		///
 | 
			
		||||
		/// This is just a "shortcut" to stringify(any, out) with name indicating the function effect.
 | 
			
		||||
 | 
			
		||||
	static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0, int step = -1);
 | 
			
		||||
		/// Writes a string representation of the value to the output stream.
 | 
			
		||||
		///
 | 
			
		||||
		/// When indent is 0, the string will be created as small as possible.
 | 
			
		||||
		/// When preserveInsertionOrder is true, the original string object members order will be preserved;
 | 
			
		||||
		/// otherwise, object members are sorted by their names.
 | 
			
		||||
@@ -53,7 +55,8 @@ inline void Stringifier::condense(const Dynamic::Var& any, std::ostream& out)
 | 
			
		||||
	stringify(any, out, 0, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_JSONStringifier_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
// SPDX-License-Identifier:	BSL-1.0
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef JSON_JSONTemplate_INCLUDED
 | 
			
		||||
#define JSON_JSONTemplate_INCLUDED
 | 
			
		||||
 | 
			
		||||
@@ -42,7 +43,7 @@ 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, ...
 | 
			
		||||
	/// conditional output, etc.
 | 
			
		||||
	///
 | 
			
		||||
	/// All text is send to the outputstream. A command is placed
 | 
			
		||||
	/// between 
 | 
			
		||||
@@ -91,13 +92,13 @@ public:
 | 
			
		||||
	typedef SharedPtr<Template> Ptr;
 | 
			
		||||
 | 
			
		||||
	Template();
 | 
			
		||||
		/// Constructor.
 | 
			
		||||
		/// Creates a Template.
 | 
			
		||||
 | 
			
		||||
	Template(const Path& templatePath);
 | 
			
		||||
		/// Constructor. Creates a template from a file.
 | 
			
		||||
		/// Creates a Template from the file with the given templatePath.
 | 
			
		||||
 | 
			
		||||
	virtual ~Template();
 | 
			
		||||
		/// Destructor.
 | 
			
		||||
		/// Destroys the Template.
 | 
			
		||||
 | 
			
		||||
	void parse();
 | 
			
		||||
		/// Parse a template from a file.
 | 
			
		||||
@@ -106,7 +107,7 @@ public:
 | 
			
		||||
		/// Parse a template from a string.
 | 
			
		||||
 | 
			
		||||
	void parse(std::istream& in);
 | 
			
		||||
		/// Parse a template from a input stream.
 | 
			
		||||
		/// Parse a template from an input stream.
 | 
			
		||||
 | 
			
		||||
	Timestamp parseTime() const;
 | 
			
		||||
		/// Returns the time when the template was parsed.
 | 
			
		||||
@@ -130,6 +131,9 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// inlines
 | 
			
		||||
//
 | 
			
		||||
inline void Template::parse(const std::string& source)
 | 
			
		||||
{
 | 
			
		||||
	std::istringstream is(source);
 | 
			
		||||
@@ -143,7 +147,7 @@ inline Timestamp Template::parseTime() const
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_JSONTemplate_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
// SPDX-License-Identifier:	BSL-1.0
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef JSON_JSONTemplateCache_INCLUDED
 | 
			
		||||
#define JSON_JSONTemplateCache_INCLUDED
 | 
			
		||||
 | 
			
		||||
@@ -41,11 +42,13 @@ class JSON_API TemplateCache
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	TemplateCache();
 | 
			
		||||
		/// Constructor. The cache must be created
 | 
			
		||||
		/// and not destroyed as long as it is used.
 | 
			
		||||
		/// Creates an empty TemplateCache.
 | 
			
		||||
		///
 | 
			
		||||
		/// The cache must be created and not destroyed 
 | 
			
		||||
		/// as long as it is used.
 | 
			
		||||
 | 
			
		||||
	virtual ~TemplateCache();
 | 
			
		||||
		/// Destructor.
 | 
			
		||||
		/// Destroys the TemplateCache.
 | 
			
		||||
 | 
			
		||||
	void addPath(const Path& path);
 | 
			
		||||
		/// Add a path for resolving template paths.
 | 
			
		||||
@@ -61,22 +64,25 @@ public:
 | 
			
		||||
		/// the cache.
 | 
			
		||||
 | 
			
		||||
	static TemplateCache* instance();
 | 
			
		||||
		/// Returns the only instance of this cache
 | 
			
		||||
		/// 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;
 | 
			
		||||
 | 
			
		||||
	static TemplateCache*                _pInstance;
 | 
			
		||||
	std::vector<Path>                    _includePaths;
 | 
			
		||||
	std::map<std::string, Template::Ptr> _cache;
 | 
			
		||||
	Logger*                              _pLogger;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// inlines
 | 
			
		||||
//
 | 
			
		||||
inline void TemplateCache::addPath(const Path& path)
 | 
			
		||||
{
 | 
			
		||||
	_includePaths.push_back(path);
 | 
			
		||||
@@ -85,17 +91,17 @@ inline void TemplateCache::addPath(const Path& path)
 | 
			
		||||
 | 
			
		||||
inline TemplateCache* TemplateCache::instance()
 | 
			
		||||
{
 | 
			
		||||
	return _instance;
 | 
			
		||||
	return _pInstance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline void TemplateCache::setLogger(Logger& logger)
 | 
			
		||||
{
 | 
			
		||||
	_logger = &logger;
 | 
			
		||||
	_pLogger = &logger;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}} // Namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // JSON_JSONTemplateCache_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ Var Array::get(unsigned int index) const
 | 
			
		||||
	{
 | 
			
		||||
		value = _values.at(index);
 | 
			
		||||
	}
 | 
			
		||||
	catch(std::out_of_range&)
 | 
			
		||||
	catch (std::out_of_range&)
 | 
			
		||||
	{
 | 
			
		||||
		//Ignore, we return an empty value
 | 
			
		||||
	}
 | 
			
		||||
@@ -61,7 +61,7 @@ Array::Ptr Array::getArray(unsigned int index) const
 | 
			
		||||
	Array::Ptr result;
 | 
			
		||||
 | 
			
		||||
	Var value = get(index);
 | 
			
		||||
	if ( value.type() == typeid(Array::Ptr) )
 | 
			
		||||
	if (value.type() == typeid(Array::Ptr))
 | 
			
		||||
	{
 | 
			
		||||
		result = value.extract<Array::Ptr>();
 | 
			
		||||
	}
 | 
			
		||||
@@ -74,7 +74,7 @@ Object::Ptr Array::getObject(unsigned int index) const
 | 
			
		||||
	Object::Ptr result;
 | 
			
		||||
 | 
			
		||||
	Var value = get(index);
 | 
			
		||||
	if ( value.type() == typeid(Object::Ptr) )
 | 
			
		||||
	if (value.type() == typeid(Object::Ptr))
 | 
			
		||||
	{
 | 
			
		||||
		result = value.extract<Object::Ptr>();
 | 
			
		||||
	}
 | 
			
		||||
@@ -84,7 +84,7 @@ Object::Ptr Array::getObject(unsigned int index) const
 | 
			
		||||
 | 
			
		||||
bool Array::isNull(unsigned int index) const
 | 
			
		||||
{
 | 
			
		||||
	if ( index < _values.size() )
 | 
			
		||||
	if (index < _values.size())
 | 
			
		||||
	{
 | 
			
		||||
		Dynamic::Var value = _values[index];
 | 
			
		||||
		return value.isEmpty();
 | 
			
		||||
@@ -122,11 +122,11 @@ void Array::stringify(std::ostream& out, unsigned int indent, int step) const
 | 
			
		||||
 | 
			
		||||
	for (ValueVec::const_iterator it = _values.begin(); it != _values.end();)
 | 
			
		||||
	{
 | 
			
		||||
		for(int i = 0; i < indent; i++) out << ' ';
 | 
			
		||||
		for (int i = 0; i < indent; i++) out << ' ';
 | 
			
		||||
 | 
			
		||||
		Stringifier::stringify(*it, out, indent + step, step);
 | 
			
		||||
 | 
			
		||||
		if ( ++it != _values.end() )
 | 
			
		||||
		if (++it != _values.end())
 | 
			
		||||
		{
 | 
			
		||||
			out << ",";
 | 
			
		||||
			if (step > 0) out << '\n';
 | 
			
		||||
 
 | 
			
		||||
@@ -25,4 +25,4 @@ namespace JSON {
 | 
			
		||||
POCO_IMPLEMENT_EXCEPTION(JSONException, Exception, "JSON Exception")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} } // Namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 
 | 
			
		||||
@@ -92,7 +92,7 @@ Object::Ptr Object::getObject(const std::string& key) const
 | 
			
		||||
void Object::getNames(std::vector<std::string>& names) const
 | 
			
		||||
{
 | 
			
		||||
	names.clear();
 | 
			
		||||
	for(ValueMap::const_iterator it = _values.begin(); it != _values.end(); ++it)
 | 
			
		||||
	for (ValueMap::const_iterator it = _values.begin(); it != _values.end(); ++it)
 | 
			
		||||
	{
 | 
			
		||||
		names.push_back(it->first);
 | 
			
		||||
	}
 | 
			
		||||
@@ -103,7 +103,7 @@ void Object::stringify(std::ostream& out, unsigned int indent, int step) const
 | 
			
		||||
{
 | 
			
		||||
	if (step < 0) step = indent;
 | 
			
		||||
 | 
			
		||||
	if(!_preserveInsOrder)
 | 
			
		||||
	if (!_preserveInsOrder)
 | 
			
		||||
		doStringify(_values, out, indent, step);
 | 
			
		||||
	else
 | 
			
		||||
		doStringify(_keys, out, indent, step);
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ void ParseHandler::startObject()
 | 
			
		||||
{
 | 
			
		||||
	Object::Ptr newObj = new Object(_preserveObjectOrder);
 | 
			
		||||
 | 
			
		||||
	if ( _stack.empty() ) // The first object
 | 
			
		||||
	if (_stack.empty()) // The first object
 | 
			
		||||
	{
 | 
			
		||||
		_result = newObj;
 | 
			
		||||
	}
 | 
			
		||||
@@ -56,12 +56,12 @@ void ParseHandler::startObject()
 | 
			
		||||
	{
 | 
			
		||||
		Var parent = _stack.top();
 | 
			
		||||
 | 
			
		||||
		if ( parent.type() == typeid(Array::Ptr) )
 | 
			
		||||
		if (parent.type() == typeid(Array::Ptr))
 | 
			
		||||
		{
 | 
			
		||||
			Array::Ptr arr = parent.extract<Array::Ptr>();
 | 
			
		||||
			arr->add(newObj);
 | 
			
		||||
		}
 | 
			
		||||
		else if ( parent.type() == typeid(Object::Ptr) )
 | 
			
		||||
		else if (parent.type() == typeid(Object::Ptr))
 | 
			
		||||
		{
 | 
			
		||||
			poco_assert_dbg(!_key.empty());
 | 
			
		||||
			Object::Ptr obj = parent.extract<Object::Ptr>();
 | 
			
		||||
@@ -84,7 +84,7 @@ void ParseHandler::startArray()
 | 
			
		||||
{
 | 
			
		||||
	Array::Ptr newArr = new Array();
 | 
			
		||||
 | 
			
		||||
	if ( _stack.empty() ) // The first array
 | 
			
		||||
	if (_stack.empty()) // The first array
 | 
			
		||||
	{
 | 
			
		||||
		_result = newArr;
 | 
			
		||||
	}
 | 
			
		||||
@@ -92,12 +92,12 @@ void ParseHandler::startArray()
 | 
			
		||||
	{
 | 
			
		||||
		Var parent = _stack.top();
 | 
			
		||||
 | 
			
		||||
		if ( parent.type() == typeid(Array::Ptr) )
 | 
			
		||||
		if (parent.type() == typeid(Array::Ptr))
 | 
			
		||||
		{
 | 
			
		||||
			Array::Ptr arr = parent.extract<Array::Ptr>();
 | 
			
		||||
			arr->add(newArr);
 | 
			
		||||
		}
 | 
			
		||||
		else if ( parent.type() == typeid(Object::Ptr) )
 | 
			
		||||
		else if (parent.type() == typeid(Object::Ptr))
 | 
			
		||||
		{
 | 
			
		||||
			poco_assert_dbg(!_key.empty());
 | 
			
		||||
			Object::Ptr obj = parent.extract<Object::Ptr>();
 | 
			
		||||
@@ -126,12 +126,12 @@ void ParseHandler::setValue(const Var& value)
 | 
			
		||||
{
 | 
			
		||||
	Var parent = _stack.top();
 | 
			
		||||
 | 
			
		||||
	if ( parent.type() == typeid(Array::Ptr) )
 | 
			
		||||
	if (parent.type() == typeid(Array::Ptr))
 | 
			
		||||
	{
 | 
			
		||||
		Array::Ptr arr = parent.extract<Array::Ptr>();
 | 
			
		||||
		arr->add(value);
 | 
			
		||||
	}
 | 
			
		||||
	else if ( parent.type() == typeid(Object::Ptr) )
 | 
			
		||||
	else if (parent.type() == typeid(Object::Ptr))
 | 
			
		||||
	{
 | 
			
		||||
		Object::Ptr obj = parent.extract<Object::Ptr>();
 | 
			
		||||
		obj->set(_key, value);
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,8 @@ namespace JSON {
 | 
			
		||||
static const unsigned char UTF8_LEAD_BITS[4] = { 0x00, 0xC0, 0xE0, 0xF0 };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const int Parser::_asciiClass[] = {
 | 
			
		||||
const int Parser::_asciiClass[] = 
 | 
			
		||||
{
 | 
			
		||||
    xx,      xx,      xx,      xx,      xx,      xx,      xx,      xx,
 | 
			
		||||
    xx,      C_WHITE, C_WHITE, xx,      xx,      C_WHITE, xx,      xx,
 | 
			
		||||
    xx,      xx,      xx,      xx,      xx,      xx,      xx,      xx,
 | 
			
		||||
@@ -57,7 +58,8 @@ const int Parser::_asciiClass[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const int Parser::_stateTransitionTable[NR_STATES][NR_CLASSES] = {
 | 
			
		||||
const int Parser::_stateTransitionTable[NR_STATES][NR_CLASSES] = 
 | 
			
		||||
{
 | 
			
		||||
/*
 | 
			
		||||
                 white                                      1-9                                   ABCDF  etc
 | 
			
		||||
             space |  {  }  [  ]  :  ,  "  \  /  +  -  .  0  |  a  b  c  d  e  f  l  n  r  s  t  u  |  E  |  * */
 | 
			
		||||
@@ -100,7 +102,7 @@ const int Parser::_stateTransitionTable[NR_STATES][NR_CLASSES] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Parser::Parser(const Handler::Ptr& pHandler, std::size_t bufSize) :
 | 
			
		||||
Parser::Parser(const Handler::Ptr& pHandler, std::size_t bufSize):
 | 
			
		||||
	_pHandler(pHandler),
 | 
			
		||||
	_state(GO),
 | 
			
		||||
	_beforeCommentState(0),
 | 
			
		||||
@@ -149,7 +151,7 @@ Dynamic::Var Parser::parse(const std::string& json)
 | 
			
		||||
	Source<std::string::const_iterator> source(it, end);
 | 
			
		||||
 | 
			
		||||
	int c = 0;
 | 
			
		||||
	while(source.nextChar(c))
 | 
			
		||||
	while (source.nextChar(c))
 | 
			
		||||
	{
 | 
			
		||||
		if (0 == parseChar(c, source))
 | 
			
		||||
			throw SyntaxException("JSON syntax error");
 | 
			
		||||
@@ -169,7 +171,7 @@ Dynamic::Var Parser::parse(std::istream& in)
 | 
			
		||||
	Source<std::istreambuf_iterator<char> > source(it, end);
 | 
			
		||||
 | 
			
		||||
	int c = 0;
 | 
			
		||||
	while(source.nextChar(c))
 | 
			
		||||
	while (source.nextChar(c))
 | 
			
		||||
	{
 | 
			
		||||
		if (0 == parseChar(c, source)) throw JSONException("JSON syntax error");
 | 
			
		||||
	}
 | 
			
		||||
@@ -237,7 +239,7 @@ void Parser::addEscapedCharToParseBuffer(CharIntType nextChar)
 | 
			
		||||
	// remove the backslash
 | 
			
		||||
	parseBufferPopBackChar();
 | 
			
		||||
 | 
			
		||||
	switch(nextChar)
 | 
			
		||||
	switch (nextChar)
 | 
			
		||||
	{
 | 
			
		||||
	case 'b':
 | 
			
		||||
		parseBufferPushBackChar('\b');
 | 
			
		||||
@@ -313,7 +315,7 @@ Parser::CharIntType Parser::decodeUnicodeChar()
 | 
			
		||||
		uc |= x << i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( !_allowNullByte && uc == 0 ) return 0; 
 | 
			
		||||
	if (!_allowNullByte && uc == 0) return 0; 
 | 
			
		||||
 | 
			
		||||
	// clear UTF-16 char from buffer
 | 
			
		||||
	_parseBuffer.resize(_parseBuffer.size() - 6);
 | 
			
		||||
@@ -379,7 +381,7 @@ void Parser::parseBuffer()
 | 
			
		||||
		{
 | 
			
		||||
			assertNonContainer();
 | 
			
		||||
 | 
			
		||||
			switch(type)
 | 
			
		||||
			switch (type)
 | 
			
		||||
			{
 | 
			
		||||
			case JSON_T_TRUE:
 | 
			
		||||
				{
 | 
			
		||||
@@ -399,7 +401,7 @@ void Parser::parseBuffer()
 | 
			
		||||
			case JSON_T_FLOAT:
 | 
			
		||||
				{ 
 | 
			
		||||
					// Float can't end with a dot
 | 
			
		||||
					if (_parseBuffer[_parseBuffer.size() - 1] == '.' ) throw SyntaxException("JSON syntax error");
 | 
			
		||||
					if (_parseBuffer[_parseBuffer.size() - 1] == '.') throw SyntaxException("JSON syntax error");
 | 
			
		||||
 | 
			
		||||
					double float_value = NumberParser::parseFloat(std::string(_parseBuffer.begin(), _parseBuffer.size()));
 | 
			
		||||
					_pHandler->value(float_value);
 | 
			
		||||
@@ -415,7 +417,7 @@ void Parser::parseBuffer()
 | 
			
		||||
						Int64 value = NumberParser::parse64(numStr);
 | 
			
		||||
						// if number is 32-bit, then handle as such
 | 
			
		||||
						if (value > std::numeric_limits<int>::max()
 | 
			
		||||
						 || value < std::numeric_limits<int>::min() )
 | 
			
		||||
						 || value < std::numeric_limits<int>::min())
 | 
			
		||||
						{
 | 
			
		||||
							_pHandler->value(value);
 | 
			
		||||
						}
 | 
			
		||||
@@ -425,11 +427,11 @@ void Parser::parseBuffer()
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					// try to handle error as unsigned in case of overflow
 | 
			
		||||
					catch ( const SyntaxException& )
 | 
			
		||||
					catch (const SyntaxException&)
 | 
			
		||||
					{
 | 
			
		||||
						UInt64 value = NumberParser::parseUnsigned64(numStr);
 | 
			
		||||
						// if number is 32-bit, then handle as such
 | 
			
		||||
						if ( value > std::numeric_limits<unsigned>::max() )
 | 
			
		||||
						if (value > std::numeric_limits<unsigned>::max())
 | 
			
		||||
						{
 | 
			
		||||
							_pHandler->value(value);
 | 
			
		||||
						}
 | 
			
		||||
@@ -445,7 +447,7 @@ void Parser::parseBuffer()
 | 
			
		||||
						_pHandler->value(value);
 | 
			
		||||
					}
 | 
			
		||||
					// try to handle error as unsigned in case of overflow
 | 
			
		||||
					catch ( const SyntaxException& )
 | 
			
		||||
					catch (const SyntaxException&)
 | 
			
		||||
					{
 | 
			
		||||
						unsigned value = NumberParser::parseUnsigned(numStr);
 | 
			
		||||
						_pHandler->value(value);
 | 
			
		||||
@@ -465,11 +467,12 @@ void Parser::parseBuffer()
 | 
			
		||||
	clearBuffer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int Parser::utf8CheckFirst(char byte)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char u = (unsigned char) byte;
 | 
			
		||||
 | 
			
		||||
	if(u < 0x80)
 | 
			
		||||
	if (u < 0x80)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (0x80 <= u && u <= 0xBF) 
 | 
			
		||||
@@ -478,22 +481,22 @@ int Parser::utf8CheckFirst(char byte)
 | 
			
		||||
		// sequence, i.e. a "continuation byte"
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	else if(u == 0xC0 || u == 0xC1) 
 | 
			
		||||
	else if (u == 0xC0 || u == 0xC1) 
 | 
			
		||||
	{
 | 
			
		||||
		// overlong encoding of an ASCII byte
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	else if(0xC2 <= u && u <= 0xDF) 
 | 
			
		||||
	else if (0xC2 <= u && u <= 0xDF) 
 | 
			
		||||
	{
 | 
			
		||||
		// 2-byte sequence
 | 
			
		||||
		return 2;
 | 
			
		||||
	}
 | 
			
		||||
	else if(0xE0 <= u && u <= 0xEF) 
 | 
			
		||||
	else if (0xE0 <= u && u <= 0xEF) 
 | 
			
		||||
	{
 | 
			
		||||
		// 3-byte sequence
 | 
			
		||||
		return 3;
 | 
			
		||||
	}
 | 
			
		||||
	else if(0xF0 <= u && u <= 0xF4) 
 | 
			
		||||
	else if (0xF0 <= u && u <= 0xF4) 
 | 
			
		||||
	{
 | 
			
		||||
		// 4-byte sequence
 | 
			
		||||
		return 4;
 | 
			
		||||
@@ -506,4 +509,5 @@ int Parser::utf8CheckFirst(char byte)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@ void PrintHandler::startObject()
 | 
			
		||||
 | 
			
		||||
void PrintHandler::endObject()
 | 
			
		||||
{
 | 
			
		||||
	if( _tab.length() >= indent())
 | 
			
		||||
	if (_tab.length() >= indent())
 | 
			
		||||
		_tab.erase(_tab.length() - indent());
 | 
			
		||||
 | 
			
		||||
	_out << endLine() << _tab << '}';
 | 
			
		||||
@@ -205,7 +205,7 @@ void PrintHandler::comma()
 | 
			
		||||
void PrintHandler::arrayValue()
 | 
			
		||||
{
 | 
			
		||||
	if (!_objStart) comma();
 | 
			
		||||
	if (array())
 | 
			
		||||
	if (array()) 
 | 
			
		||||
	{
 | 
			
		||||
		_out << _tab;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -104,7 +104,7 @@ Var Query::find(const std::string& path) const
 | 
			
		||||
{
 | 
			
		||||
	Var result = _source;
 | 
			
		||||
	StringTokenizer tokenizer(path, ".");
 | 
			
		||||
	for(StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); token++)
 | 
			
		||||
	for (StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); token++)
 | 
			
		||||
	{
 | 
			
		||||
		if (!result.isEmpty())
 | 
			
		||||
		{
 | 
			
		||||
@@ -113,7 +113,7 @@ Var Query::find(const std::string& path) const
 | 
			
		||||
			int firstOffset = -1;
 | 
			
		||||
			int offset = 0;
 | 
			
		||||
			RegularExpression regex("\\[([0-9]+)\\]");
 | 
			
		||||
			while(regex.match(*token, offset, matches) > 0)
 | 
			
		||||
			while (regex.match(*token, offset, matches) > 0)
 | 
			
		||||
			{
 | 
			
		||||
				if (firstOffset == -1)
 | 
			
		||||
				{
 | 
			
		||||
@@ -149,7 +149,7 @@ Var Query::find(const std::string& path) const
 | 
			
		||||
 | 
			
		||||
			if (!result.isEmpty() && !indexes.empty())
 | 
			
		||||
			{
 | 
			
		||||
				for(std::vector<int>::iterator it = indexes.begin(); it != indexes.end(); ++it)
 | 
			
		||||
				for (std::vector<int>::iterator it = indexes.begin(); it != indexes.end(); ++it)
 | 
			
		||||
				{
 | 
			
		||||
					if (result.type() == typeid(Array::Ptr))
 | 
			
		||||
					{
 | 
			
		||||
@@ -171,4 +171,4 @@ Var Query::find(const std::string& path) const
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} } // Namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 
 | 
			
		||||
@@ -80,4 +80,4 @@ void Stringifier::formatString(const std::string& value, std::ostream& out)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} }  // Namespace Poco::JSON
 | 
			
		||||
} }  // namespace Poco::JSON
 | 
			
		||||
 
 | 
			
		||||
@@ -51,11 +51,11 @@ public:
 | 
			
		||||
class StringPart: public Part
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	StringPart() : Part()
 | 
			
		||||
	StringPart(): Part()
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	StringPart(const std::string& content) : Part(), _content(content)
 | 
			
		||||
	StringPart(const std::string& content): Part(), _content(content)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -101,7 +101,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	void render(const Var& data, std::ostream& out) const
 | 
			
		||||
	{
 | 
			
		||||
		for(VectorParts::const_iterator it = _parts.begin(); it != _parts.end(); ++it)
 | 
			
		||||
		for (VectorParts::const_iterator it = _parts.begin(); it != _parts.end(); ++it)
 | 
			
		||||
		{
 | 
			
		||||
			(*it)->render(data, out);
 | 
			
		||||
		}
 | 
			
		||||
@@ -115,7 +115,7 @@ protected:
 | 
			
		||||
class EchoPart: public Part
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	EchoPart(const std::string& query) : Part(), _query(query)
 | 
			
		||||
	EchoPart(const std::string& query): Part(), _query(query)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -128,7 +128,7 @@ public:
 | 
			
		||||
		Query query(data);
 | 
			
		||||
		Var value = query.find(_query);
 | 
			
		||||
 | 
			
		||||
		if ( ! value.isEmpty() )
 | 
			
		||||
		if (!value.isEmpty())
 | 
			
		||||
		{
 | 
			
		||||
			out << value.convert<std::string>();
 | 
			
		||||
		}
 | 
			
		||||
@@ -142,7 +142,7 @@ private:
 | 
			
		||||
class LogicQuery
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	LogicQuery(const std::string& query) : _queryString(query)
 | 
			
		||||
	LogicQuery(const std::string& query): _queryString(query)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -157,14 +157,14 @@ public:
 | 
			
		||||
		Query query(data);
 | 
			
		||||
		Var value = query.find(_queryString);
 | 
			
		||||
 | 
			
		||||
		if ( ! value.isEmpty() ) // When empty, logic will be false
 | 
			
		||||
		if (!value.isEmpty()) // When empty, logic will be false
 | 
			
		||||
		{
 | 
			
		||||
			if ( value.isString() )
 | 
			
		||||
			if (value.isString())
 | 
			
		||||
				// An empty string must result in false, otherwise true
 | 
			
		||||
				// Which is not the case when we convert to bool with Var
 | 
			
		||||
			{
 | 
			
		||||
				std::string s = value.convert<std::string>();
 | 
			
		||||
				logic = ! s.empty();
 | 
			
		||||
				logic = !s.empty();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
@@ -183,10 +183,10 @@ protected:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LogicExistQuery : public LogicQuery
 | 
			
		||||
class LogicExistQuery: public LogicQuery
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	LogicExistQuery(const std::string& query) : LogicQuery(query)
 | 
			
		||||
	LogicExistQuery(const std::string& query): LogicQuery(query)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -204,10 +204,10 @@ public:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LogicElseQuery : public LogicQuery
 | 
			
		||||
class LogicElseQuery: public LogicQuery
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	LogicElseQuery() : LogicQuery("")
 | 
			
		||||
	LogicElseQuery(): LogicQuery("")
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -222,10 +222,10 @@ public:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LogicPart : public MultiPart
 | 
			
		||||
class LogicPart: public MultiPart
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	LogicPart() : MultiPart()
 | 
			
		||||
	LogicPart(): MultiPart()
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -248,9 +248,9 @@ public:
 | 
			
		||||
	void render(const Var& data, std::ostream& out) const
 | 
			
		||||
	{
 | 
			
		||||
		int count = 0;
 | 
			
		||||
		for(std::vector<SharedPtr<LogicQuery> >::const_iterator it = _queries.begin(); it != _queries.end(); ++it, ++count)
 | 
			
		||||
		for (std::vector<SharedPtr<LogicQuery> >::const_iterator it = _queries.begin(); it != _queries.end(); ++it, ++count)
 | 
			
		||||
		{
 | 
			
		||||
			if( (*it)->apply(data) && _parts.size() > count )
 | 
			
		||||
			if ((*it)->apply(data) && _parts.size() > count)
 | 
			
		||||
			{
 | 
			
		||||
				_parts[count]->render(data, out);
 | 
			
		||||
				break;
 | 
			
		||||
@@ -266,7 +266,7 @@ private:
 | 
			
		||||
class LoopPart: public MultiPart
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	LoopPart(const std::string& name, const std::string& query) : MultiPart(), _name(name), _query(query)
 | 
			
		||||
	LoopPart(const std::string& name, const std::string& query): MultiPart(), _name(name), _query(query)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -278,13 +278,13 @@ public:
 | 
			
		||||
	{
 | 
			
		||||
		Query query(data);
 | 
			
		||||
 | 
			
		||||
		if ( data.type() == typeid(Object::Ptr) )
 | 
			
		||||
		if (data.type() == typeid(Object::Ptr))
 | 
			
		||||
		{
 | 
			
		||||
			Object::Ptr dataObject = data.extract<Object::Ptr>();
 | 
			
		||||
			Array::Ptr array = query.findArray(_query);
 | 
			
		||||
			if ( ! array.isNull() )
 | 
			
		||||
			if (!array.isNull())
 | 
			
		||||
			{
 | 
			
		||||
				for(int i = 0; i < array->size(); i++)
 | 
			
		||||
				for (int i = 0; i < array->size(); i++)
 | 
			
		||||
				{
 | 
			
		||||
					Var value = array->get(i);
 | 
			
		||||
					dataObject->set(_name, value);
 | 
			
		||||
@@ -305,19 +305,19 @@ class IncludePart: public Part
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	IncludePart(const Path& parentPath, const Path& path)
 | 
			
		||||
		: Part()
 | 
			
		||||
		, _path(path)
 | 
			
		||||
	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() )
 | 
			
		||||
		if (_path.isRelative())
 | 
			
		||||
		{
 | 
			
		||||
			Path templatePath(parentPath, _path);
 | 
			
		||||
			File templateFile(templatePath);
 | 
			
		||||
			if ( templateFile.exists() )
 | 
			
		||||
			if (templateFile.exists())
 | 
			
		||||
			{
 | 
			
		||||
				_path = templatePath;
 | 
			
		||||
			}
 | 
			
		||||
@@ -331,7 +331,7 @@ public:
 | 
			
		||||
	void render(const Var& data, std::ostream& out) const
 | 
			
		||||
	{
 | 
			
		||||
		TemplateCache* cache = TemplateCache::instance();
 | 
			
		||||
		if ( cache == NULL )
 | 
			
		||||
		if (cache == 0)
 | 
			
		||||
		{
 | 
			
		||||
			Template tpl(_path);
 | 
			
		||||
			tpl.parse();
 | 
			
		||||
@@ -349,17 +349,17 @@ private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Template::Template(const Path& templatePath)
 | 
			
		||||
	: _parts(0)
 | 
			
		||||
	, _currentPart(0)
 | 
			
		||||
	, _templatePath(templatePath)
 | 
			
		||||
Template::Template(const Path& templatePath): 
 | 
			
		||||
	_parts(0), 
 | 
			
		||||
	_currentPart(0), 
 | 
			
		||||
	_templatePath(templatePath)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Template::Template()
 | 
			
		||||
	: _parts(0)
 | 
			
		||||
	, _currentPart(0)
 | 
			
		||||
Template::Template():
 | 
			
		||||
	_parts(0), 
 | 
			
		||||
	_currentPart(0)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -373,7 +373,7 @@ Template::~Template()
 | 
			
		||||
void Template::parse()
 | 
			
		||||
{
 | 
			
		||||
	File file(_templatePath);
 | 
			
		||||
	if ( file.exists() )
 | 
			
		||||
	if (file.exists())
 | 
			
		||||
	{
 | 
			
		||||
		FileInputStream fis(_templatePath.toString());
 | 
			
		||||
		parse(fis);
 | 
			
		||||
@@ -385,48 +385,48 @@ void Template::parse(std::istream& in)
 | 
			
		||||
{
 | 
			
		||||
	_parseTime.update();
 | 
			
		||||
 | 
			
		||||
	_parts = new MultiPart();
 | 
			
		||||
	_parts = new MultiPart;
 | 
			
		||||
	_currentPart = _parts;
 | 
			
		||||
 | 
			
		||||
	while(in.good())
 | 
			
		||||
	while (in.good())
 | 
			
		||||
	{
 | 
			
		||||
		std::string text = readText(in); // Try to read text first
 | 
			
		||||
		if ( text.length() > 0 )
 | 
			
		||||
		if (text.length() > 0)
 | 
			
		||||
		{
 | 
			
		||||
			_currentPart->addPart(new StringPart(text));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( in.bad() )
 | 
			
		||||
		if (in.bad())
 | 
			
		||||
			break; // Nothing to do anymore
 | 
			
		||||
 | 
			
		||||
		std::string command = readTemplateCommand(in);  // Try to read a template command
 | 
			
		||||
		if ( command.empty() )
 | 
			
		||||
		if (command.empty())
 | 
			
		||||
		{
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		readWhiteSpace(in);
 | 
			
		||||
 | 
			
		||||
		if ( command.compare("echo") == 0 )
 | 
			
		||||
		if (command.compare("echo") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			std::string query = readQuery(in);
 | 
			
		||||
			if ( query.empty() )
 | 
			
		||||
			if (query.empty())
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing query in <? echo ?>");
 | 
			
		||||
			}
 | 
			
		||||
			_currentPart->addPart(new EchoPart(query));
 | 
			
		||||
		}
 | 
			
		||||
		else if ( command.compare("for") == 0 )
 | 
			
		||||
		else if (command.compare("for") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			std::string loopVariable = readWord(in);
 | 
			
		||||
			if ( loopVariable.empty() )
 | 
			
		||||
			if (loopVariable.empty())
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing variable in <? for ?> command");
 | 
			
		||||
			}
 | 
			
		||||
			readWhiteSpace(in);
 | 
			
		||||
 | 
			
		||||
			std::string query = readQuery(in);
 | 
			
		||||
			if ( query.empty() )
 | 
			
		||||
			if (query.empty())
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing query in <? for ?> command");
 | 
			
		||||
			}
 | 
			
		||||
@@ -437,15 +437,15 @@ void Template::parse(std::istream& in)
 | 
			
		||||
			_currentPart->addPart(part);
 | 
			
		||||
			_currentPart = part;
 | 
			
		||||
		}
 | 
			
		||||
		else if ( command.compare("else") == 0 )
 | 
			
		||||
		else if (command.compare("else") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			if ( _partStack.size() == 0 )
 | 
			
		||||
			if (_partStack.size() == 0)
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Unexpected <? else ?> found");
 | 
			
		||||
			}
 | 
			
		||||
			_currentPart = _partStack.top();
 | 
			
		||||
			LogicPart* lp = dynamic_cast<LogicPart*>(_currentPart);
 | 
			
		||||
			if ( lp == NULL )
 | 
			
		||||
			if (lp == 0)
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing <? if ?> or <? ifexist ?> for <? else ?>");
 | 
			
		||||
			}
 | 
			
		||||
@@ -453,23 +453,22 @@ void Template::parse(std::istream& in)
 | 
			
		||||
			lp->addPart(part);
 | 
			
		||||
			_currentPart = part;
 | 
			
		||||
		}
 | 
			
		||||
		else if (    command.compare("elsif") == 0
 | 
			
		||||
		             || command.compare("elif") == 0 )
 | 
			
		||||
		else if (command.compare("elsif") == 0 || command.compare("elif") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			std::string query = readQuery(in);
 | 
			
		||||
			if ( query.empty() )
 | 
			
		||||
			if (query.empty())
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing query in <? " + command + " ?>");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ( _partStack.size() == 0 )
 | 
			
		||||
			if (_partStack.size() == 0)
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Unexpected <? elsif / elif ?> found");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			_currentPart = _partStack.top();
 | 
			
		||||
			LogicPart* lp = dynamic_cast<LogicPart*>(_currentPart);
 | 
			
		||||
			if ( lp == NULL )
 | 
			
		||||
			if (lp == 0)
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing <? if ?> or <? ifexist ?> for <? elsif / elif ?>");
 | 
			
		||||
			}
 | 
			
		||||
@@ -477,15 +476,15 @@ void Template::parse(std::istream& in)
 | 
			
		||||
			lp->addPart(new LogicQuery(query), part);
 | 
			
		||||
			_currentPart = part;
 | 
			
		||||
		}
 | 
			
		||||
		else if ( command.compare("endfor") == 0 )
 | 
			
		||||
		else if (command.compare("endfor") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			if ( _partStack.size() < 2 )
 | 
			
		||||
			if (_partStack.size() < 2)
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Unexpected <? endfor ?> found");
 | 
			
		||||
			}
 | 
			
		||||
			MultiPart* loopPart = _partStack.top();
 | 
			
		||||
			LoopPart* lp = dynamic_cast<LoopPart*>(loopPart);
 | 
			
		||||
			if ( lp == NULL )
 | 
			
		||||
			if (lp == 0)
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing <? for ?> command");
 | 
			
		||||
			}
 | 
			
		||||
@@ -493,16 +492,16 @@ void Template::parse(std::istream& in)
 | 
			
		||||
			_currentPart = _partStack.top();
 | 
			
		||||
			_partStack.pop();
 | 
			
		||||
		}
 | 
			
		||||
		else if ( command.compare("endif") == 0 )
 | 
			
		||||
		else if (command.compare("endif") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			if ( _partStack.size() < 2 )
 | 
			
		||||
			if (_partStack.size() < 2)
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Unexpected <? endif ?> found");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			_currentPart = _partStack.top();
 | 
			
		||||
			LogicPart* lp = dynamic_cast<LogicPart*>(_currentPart);
 | 
			
		||||
			if ( lp == NULL )
 | 
			
		||||
			if (lp == 0)
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing <? if ?> or <? ifexist ?> for <? endif ?>");
 | 
			
		||||
			}
 | 
			
		||||
@@ -511,11 +510,10 @@ void Template::parse(std::istream& in)
 | 
			
		||||
			_currentPart = _partStack.top();
 | 
			
		||||
			_partStack.pop();
 | 
			
		||||
		}
 | 
			
		||||
		else if (    command.compare("if") == 0
 | 
			
		||||
		             || command.compare("ifexist") == 0 )
 | 
			
		||||
		else if (command.compare("if") == 0 || command.compare("ifexist") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			std::string query = readQuery(in);
 | 
			
		||||
			if ( query.empty() )
 | 
			
		||||
			if (query.empty())
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing query in <? " + command + " ?>");
 | 
			
		||||
			}
 | 
			
		||||
@@ -524,7 +522,7 @@ void Template::parse(std::istream& in)
 | 
			
		||||
			_partStack.push(lp);
 | 
			
		||||
			_currentPart->addPart(lp);
 | 
			
		||||
			_currentPart = new MultiPart();
 | 
			
		||||
			if ( command.compare("ifexist") == 0 )
 | 
			
		||||
			if (command.compare("ifexist") == 0)
 | 
			
		||||
			{
 | 
			
		||||
				lp->addPart(new LogicExistQuery(query), _currentPart);
 | 
			
		||||
			}
 | 
			
		||||
@@ -533,11 +531,11 @@ void Template::parse(std::istream& in)
 | 
			
		||||
				lp->addPart(new LogicQuery(query), _currentPart);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if ( command.compare("include") == 0 )
 | 
			
		||||
		else if (command.compare("include") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			readWhiteSpace(in);
 | 
			
		||||
			std::string filename = readString(in);
 | 
			
		||||
			if ( filename.empty() )
 | 
			
		||||
			if (filename.empty())
 | 
			
		||||
			{
 | 
			
		||||
				throw JSONTemplateException("Missing filename in <? include ?>");
 | 
			
		||||
			}
 | 
			
		||||
@@ -556,17 +554,17 @@ void Template::parse(std::istream& in)
 | 
			
		||||
		readWhiteSpace(in);
 | 
			
		||||
 | 
			
		||||
		int c = in.get();
 | 
			
		||||
		if ( c == '?' && in.peek() == '>' )
 | 
			
		||||
		if (c == '?' && in.peek() == '>')
 | 
			
		||||
		{
 | 
			
		||||
			in.get(); // forget '>'
 | 
			
		||||
 | 
			
		||||
			if ( command.compare("echo") != 0 )
 | 
			
		||||
			if (command.compare("echo") != 0)
 | 
			
		||||
			{
 | 
			
		||||
				if ( in.peek() == '\r' )
 | 
			
		||||
				if (in.peek() == '\r')
 | 
			
		||||
				{
 | 
			
		||||
					in.get();
 | 
			
		||||
				}
 | 
			
		||||
				if ( in.peek() == '\n' )
 | 
			
		||||
				if (in.peek() == '\n')
 | 
			
		||||
				{
 | 
			
		||||
					in.get();
 | 
			
		||||
				}
 | 
			
		||||
@@ -584,11 +582,11 @@ std::string Template::readText(std::istream& in)
 | 
			
		||||
{
 | 
			
		||||
	std::string text;
 | 
			
		||||
	int c = in.get();
 | 
			
		||||
	while(c != -1)
 | 
			
		||||
	while (c != -1)
 | 
			
		||||
	{
 | 
			
		||||
		if ( c == '<' )
 | 
			
		||||
		if (c == '<')
 | 
			
		||||
		{
 | 
			
		||||
			if ( in.peek() == '?' )
 | 
			
		||||
			if (in.peek() == '?')
 | 
			
		||||
			{
 | 
			
		||||
				in.get(); // forget '?'
 | 
			
		||||
				break;
 | 
			
		||||
@@ -609,18 +607,18 @@ std::string Template::readTemplateCommand(std::istream& in)
 | 
			
		||||
	readWhiteSpace(in);
 | 
			
		||||
 | 
			
		||||
	int c = in.get();
 | 
			
		||||
	while(c != -1)
 | 
			
		||||
	while (c != -1)
 | 
			
		||||
	{
 | 
			
		||||
		if ( Ascii::isSpace(c) )
 | 
			
		||||
		if (Ascii::isSpace(c))
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		if ( c == '?' && in.peek() == '>' )
 | 
			
		||||
		if (c == '?' && in.peek() == '>')
 | 
			
		||||
		{
 | 
			
		||||
			in.putback(c);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( c == '=' && command.length() == 0 )
 | 
			
		||||
		if (c == '=' && command.length() == 0)
 | 
			
		||||
		{
 | 
			
		||||
			command = "echo";
 | 
			
		||||
			break;
 | 
			
		||||
@@ -639,7 +637,7 @@ std::string Template::readWord(std::istream& in)
 | 
			
		||||
{
 | 
			
		||||
	std::string word;
 | 
			
		||||
	int c;
 | 
			
		||||
	while((c = in.peek()) != -1 && ! Ascii::isSpace(c))
 | 
			
		||||
	while ((c = in.peek()) != -1 && !Ascii::isSpace(c))
 | 
			
		||||
	{
 | 
			
		||||
		in.get();
 | 
			
		||||
		word += c;
 | 
			
		||||
@@ -652,15 +650,15 @@ std::string Template::readQuery(std::istream& in)
 | 
			
		||||
{
 | 
			
		||||
	std::string word;
 | 
			
		||||
	int c;
 | 
			
		||||
	while((c = in.get()) != -1)
 | 
			
		||||
	while ((c = in.get()) != -1)
 | 
			
		||||
	{
 | 
			
		||||
		if ( c == '?' && in.peek() == '>' )
 | 
			
		||||
		if (c == '?' && in.peek() == '>')
 | 
			
		||||
		{
 | 
			
		||||
			in.putback(c);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( Ascii::isSpace(c) )
 | 
			
		||||
		if (Ascii::isSpace(c))
 | 
			
		||||
		{
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
@@ -673,7 +671,7 @@ std::string Template::readQuery(std::istream& in)
 | 
			
		||||
void Template::readWhiteSpace(std::istream& in)
 | 
			
		||||
{
 | 
			
		||||
	int c;
 | 
			
		||||
	while((c = in.peek()) != -1 && Ascii::isSpace(c))
 | 
			
		||||
	while ((c = in.peek()) != -1 && Ascii::isSpace(c))
 | 
			
		||||
	{
 | 
			
		||||
		in.get();
 | 
			
		||||
	}
 | 
			
		||||
@@ -685,9 +683,9 @@ std::string Template::readString(std::istream& in)
 | 
			
		||||
	std::string str;
 | 
			
		||||
 | 
			
		||||
	int c = in.get();
 | 
			
		||||
	if ( c == '"' )
 | 
			
		||||
	if (c == '"')
 | 
			
		||||
	{
 | 
			
		||||
		while((c = in.get()) != -1 && c != '"')
 | 
			
		||||
		while ((c = in.get()) != -1 && c != '"')
 | 
			
		||||
		{
 | 
			
		||||
			str += c;
 | 
			
		||||
		}
 | 
			
		||||
@@ -702,4 +700,4 @@ void Template::render(const Var& data, std::ostream& out) const
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} } // Namespace Poco::JSON
 | 
			
		||||
} } // namespace Poco::JSON
 | 
			
		||||
 
 | 
			
		||||
@@ -22,10 +22,10 @@ namespace Poco {
 | 
			
		||||
namespace JSON {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TemplateCache* TemplateCache::_instance = NULL;
 | 
			
		||||
TemplateCache* TemplateCache::_pInstance = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TemplateCache::TemplateCache() : _logger(NULL)
 | 
			
		||||
TemplateCache::TemplateCache(): _pLogger(0)
 | 
			
		||||
{
 | 
			
		||||
	setup();
 | 
			
		||||
}
 | 
			
		||||
@@ -33,40 +33,44 @@ TemplateCache::TemplateCache() : _logger(NULL)
 | 
			
		||||
 | 
			
		||||
TemplateCache::~TemplateCache()
 | 
			
		||||
{
 | 
			
		||||
	_instance = NULL;
 | 
			
		||||
	_pInstance = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void TemplateCache::setup()
 | 
			
		||||
{
 | 
			
		||||
	poco_assert (_instance == NULL);
 | 
			
		||||
	_instance = this;
 | 
			
		||||
	poco_assert (_pInstance == 0);
 | 
			
		||||
	_pInstance = this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Template::Ptr TemplateCache::getTemplate(const Path& path)
 | 
			
		||||
{
 | 
			
		||||
	if ( _logger )
 | 
			
		||||
	if (_pLogger)
 | 
			
		||||
	{
 | 
			
		||||
		poco_trace_f1(*_logger, "Trying to load %s", path.toString());
 | 
			
		||||
		poco_trace_f1(*_pLogger, "Trying to load %s", path.toString());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Path templatePath = resolvePath(path);
 | 
			
		||||
	std::string templatePathname = templatePath.toString();
 | 
			
		||||
	if ( _logger )
 | 
			
		||||
	
 | 
			
		||||
	if (_pLogger)
 | 
			
		||||
	{
 | 
			
		||||
		poco_trace_f1(*_logger, "Path resolved to %s", templatePathname);
 | 
			
		||||
		poco_trace_f1(*_pLogger, "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 (it == _cache.end())
 | 
			
		||||
	{
 | 
			
		||||
		if ( templateFile.exists() )
 | 
			
		||||
		if (templateFile.exists())
 | 
			
		||||
		{
 | 
			
		||||
			if ( _logger )
 | 
			
		||||
			if (_pLogger)
 | 
			
		||||
			{
 | 
			
		||||
				poco_information_f1(*_logger, "Loading template %s", templatePath.toString());
 | 
			
		||||
				poco_information_f1(*_pLogger, "Loading template %s", templatePath.toString());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			tpl = new Template(templatePath);
 | 
			
		||||
@@ -76,19 +80,19 @@ Template::Ptr TemplateCache::getTemplate(const Path& path)
 | 
			
		||||
				tpl->parse();
 | 
			
		||||
				_cache[templatePathname] = tpl;
 | 
			
		||||
			}
 | 
			
		||||
			catch(JSONTemplateException& jte)
 | 
			
		||||
			catch (JSONTemplateException& jte)
 | 
			
		||||
			{
 | 
			
		||||
				if ( _logger )
 | 
			
		||||
				if (_pLogger)
 | 
			
		||||
				{
 | 
			
		||||
					poco_error_f2(*_logger, "Template %s contains an error: %s", templatePath.toString(), jte.message());
 | 
			
		||||
					poco_error_f2(*_pLogger, "Template %s contains an error: %s", templatePath.toString(), jte.message());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			if ( _logger )
 | 
			
		||||
			if (_pLogger)
 | 
			
		||||
			{
 | 
			
		||||
				poco_error_f1(*_logger, "Template file %s doesn't exist", templatePath.toString());
 | 
			
		||||
				poco_error_f1(*_pLogger, "Template file %s doesn't exist", templatePath.toString());
 | 
			
		||||
			}
 | 
			
		||||
			throw FileNotFoundException(templatePathname);
 | 
			
		||||
		}
 | 
			
		||||
@@ -96,11 +100,11 @@ Template::Ptr TemplateCache::getTemplate(const Path& path)
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		tpl = it->second;
 | 
			
		||||
		if ( tpl->parseTime() < templateFile.getLastModified() )
 | 
			
		||||
		if (tpl->parseTime() < templateFile.getLastModified())
 | 
			
		||||
		{
 | 
			
		||||
			if ( _logger )
 | 
			
		||||
			if (_pLogger)
 | 
			
		||||
			{
 | 
			
		||||
				poco_information_f1(*_logger, "Reloading template %s", templatePath.toString());
 | 
			
		||||
				poco_information_f1(*_pLogger, "Reloading template %s", templatePath.toString());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			tpl = new Template(templatePath);
 | 
			
		||||
@@ -110,11 +114,11 @@ Template::Ptr TemplateCache::getTemplate(const Path& path)
 | 
			
		||||
				tpl->parse();
 | 
			
		||||
				_cache[templatePathname] = tpl;
 | 
			
		||||
			}
 | 
			
		||||
			catch(JSONTemplateException& jte)
 | 
			
		||||
			catch (JSONTemplateException& jte)
 | 
			
		||||
			{
 | 
			
		||||
				if ( _logger )
 | 
			
		||||
				if (_pLogger)
 | 
			
		||||
				{
 | 
			
		||||
					poco_error_f2(*_logger, "Template %s contains an error: %s", templatePath.toString(), jte.message());
 | 
			
		||||
					poco_error_f2(*_pLogger, "Template %s contains an error: %s", templatePath.toString(), jte.message());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -126,25 +130,25 @@ Template::Ptr TemplateCache::getTemplate(const Path& path)
 | 
			
		||||
 | 
			
		||||
Path TemplateCache::resolvePath(const Path& path) const
 | 
			
		||||
{
 | 
			
		||||
	if ( path.isAbsolute() )
 | 
			
		||||
	if (path.isAbsolute())
 | 
			
		||||
		return path;
 | 
			
		||||
 | 
			
		||||
	for(std::vector<Path>::const_iterator it = _includePaths.begin(); it != _includePaths.end(); ++it)
 | 
			
		||||
	for (std::vector<Path>::const_iterator it = _includePaths.begin(); it != _includePaths.end(); ++it)
 | 
			
		||||
	{
 | 
			
		||||
		Path templatePath(*it, path);
 | 
			
		||||
 | 
			
		||||
		File templateFile(templatePath);
 | 
			
		||||
		if ( templateFile.exists() )
 | 
			
		||||
		if (templateFile.exists())
 | 
			
		||||
		{
 | 
			
		||||
			if ( _logger )
 | 
			
		||||
			if (_pLogger)
 | 
			
		||||
			{
 | 
			
		||||
				poco_trace_f2(*_logger, "%s template file resolved to %s", path.toString(), templatePath.toString());
 | 
			
		||||
				poco_trace_f2(*_pLogger, "%s template file resolved to %s", path.toString(), templatePath.toString());
 | 
			
		||||
			}
 | 
			
		||||
			return templatePath;
 | 
			
		||||
		}
 | 
			
		||||
		if ( _logger )
 | 
			
		||||
		if (_pLogger)
 | 
			
		||||
		{
 | 
			
		||||
			poco_trace_f1(*_logger, "%s doesn't exist", templatePath.toString());
 | 
			
		||||
			poco_trace_f1(*_pLogger, "%s doesn't exist", templatePath.toString());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user