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