This commit is contained in:
Aleksandar Fabijanic
2018-02-08 09:08:42 -06:00
committed by Alex Fabijanic
parent 4a7ab78686
commit bd81aec779
13 changed files with 610 additions and 106 deletions

View File

@@ -63,8 +63,11 @@ public:
typedef std::vector<Dynamic::Var>::const_iterator ConstIterator;
typedef SharedPtr<Array> Ptr;
Array();
Array(bool escapeUnicode = false);
/// Creates an empty Array.
///
/// If escapeUnicode is true, when the object is stringified, all unicode
/// characters will be escaped in the resulting string.
Array(const Array& copy);
/// Creates an Array by copying another one.
@@ -85,6 +88,12 @@ public:
virtual ~Array();
/// Destroys the Array.
void setEscapeUnicode(bool escape = true);
/// Sets the flag for escaping unicode.
bool getEscapeUnicode() const;
/// Returns the flag for escaping unicode.
ValueVec::const_iterator begin() const;
/// Returns the begin iterator for values.
@@ -192,12 +201,30 @@ private:
ValueVec _values;
mutable ArrayPtr _pArray;
mutable bool _modified;
// Note:
// The reason we have this flag here (rather than as argument to stringify())
// is because Array can be returned stringified from a Dynamic::Var:toString(),
// so it must know whether to escape unicode or not.
bool _escapeUnicode;
};
//
// inlines
//
inline void Array::setEscapeUnicode(bool escape)
{
_escapeUnicode = true;
}
inline bool Array::getEscapeUnicode() const
{
return _escapeUnicode;
}
inline Array::ValueVec::const_iterator Array::begin() const
{
return _values.begin();

View File

@@ -37,8 +37,13 @@ namespace JSON {
class JSON_API Object
<<<<<<< HEAD
/// Represents a JSON object. Object provides a representation
/// based on shared pointers and optimized for performance. It is possible to
=======
/// Represents a JSON object. Object provides a representation based on
/// shared pointers and optimized for performance. It is possible to
>>>>>>> df5968ce1... Json unicode escape && preserveOrder keys sync (#2145)
/// convert Object to DynamicStruct. Conversion requires copying and therefore
/// has performance penalty; the benefit is in improved syntax, eg:
///
@@ -56,7 +61,7 @@ class JSON_API Object
/// // copy/convert to Poco::DynamicStruct
/// Poco::DynamicStruct ds = *object;
/// val = ds["test"]["property"]; // val holds "value"
/// ----
///
{
public:
typedef SharedPtr<Object> Ptr;
@@ -64,12 +69,36 @@ public:
typedef ValueMap::value_type ValueType;
typedef ValueMap::iterator Iterator;
typedef ValueMap::const_iterator ConstIterator;
typedef std::vector<std::string> NameList;
explicit Object(bool preserveInsertionOrder = false);
enum Options
{
JSON_PRESERVE_KEY_ORDER = 1,
/// If specified, the object will preserve the items
/// insertion order. Otherwise, items will be sorted
/// by keys.
JSON_ESCAPE_UNICODE = 2
/// If specified, when the object is stringified, all
/// unicode characters will be escaped in the resulting
/// string.
};
explicit Object(int options = 0);
/// Creates an empty Object.
///
<<<<<<< HEAD
/// If preserveInsertionOrder, object will preserve the items insertion
/// order. Otherwise, items will be sorted by keys.
=======
/// If JSON_PRESERVE_KEY_ORDER is specified, the object will
/// preserve the items insertion order. Otherwise, items will be
/// sorted by keys.
///
/// If JSON_ESCAPE_UNICODE is specified, when the object is
/// stringified, all unicode characters will be escaped in the
/// resulting string.
>>>>>>> df5968ce1... Json unicode escape && preserveOrder keys sync (#2145)
Object(const Object& copy);
/// Creates an Object by copying another one.
@@ -93,25 +122,33 @@ public:
Object &operator =(const Object &other);
// Assignment operator
<<<<<<< HEAD
Iterator begin()
{
return _values.begin();
}
=======
Object &operator =(Object &&other);
// Move asignment operator
ConstIterator begin() const
{
return _values.begin();
}
void setEscapeUnicode(bool escape = true);
/// Sets the flag for escaping unicode.
>>>>>>> df5968ce1... Json unicode escape && preserveOrder keys sync (#2145)
Iterator end()
{
return _values.end();
}
bool getEscapeUnicode() const;
/// Returns the flag for escaping unicode.
ConstIterator end() const
{
return _values.end();
}
Iterator begin();
/// Returns begin iterator for values.
ConstIterator begin() const;
/// Returns const begin iterator for values.
Iterator end();
/// Returns end iterator for values.
ConstIterator end() const;
/// Returns const end iterator for values.
Dynamic::Var get(const std::string& key) const;
/// Retrieves a property. An empty value is
@@ -155,7 +192,10 @@ public:
return value.convert<T>();
}
void getNames(std::vector<std::string>& names) const;
void getNames(NameList& names) const;
/// Fills the supplied vector with all property names.
NameList getNames() const;
/// Returns all property names.
bool has(const std::string& key) const;
@@ -225,7 +265,11 @@ public:
/// Insertion order preservation property is left intact.
private:
typedef std::deque<ValueMap::const_iterator> KeyList;
typedef Poco::DynamicStruct::Ptr StructPtr;
void resetDynStruct() const;
void syncKeys(const KeyList& keys);
template <typename C>
void doStringify(const C& container, std::ostream& out, unsigned int indent, unsigned int step) const
@@ -233,17 +277,17 @@ private:
out << '{';
if (indent > 0) out << std::endl;
typename C::const_iterator it = container.begin();
typename C::const_iterator end = container.end();
for (; it != end;)
{
for (unsigned int i = 0; i < indent; i++) out << ' ';
Stringifier::stringify(getKey(it), out);
Stringifier::stringify(getKey(it), out, indent, step, _escapeUnicode);
out << ((indent > 0) ? " : " : ":");
Stringifier::stringify(getValue(it), out, indent + step, step);
Stringifier::stringify(getValue(it), out, indent + step, step, _escapeUnicode);
if (++it != container.end()) out << ',';
@@ -257,17 +301,19 @@ private:
out << '}';
}
typedef std::deque<const std::string*> KeyPtrList;
typedef Poco::DynamicStruct::Ptr StructPtr;
const std::string& getKey(ValueMap::const_iterator& it) const;
const Dynamic::Var& getValue(ValueMap::const_iterator& it) const;
const std::string& getKey(KeyPtrList::const_iterator& it) const;
const Dynamic::Var& getValue(KeyPtrList::const_iterator& it) const;
const std::string& getKey(KeyList::const_iterator& it) const;
const Dynamic::Var& getValue(KeyList::const_iterator& it) const;
ValueMap _values;
KeyPtrList _keys;
KeyList _keys;
bool _preserveInsOrder;
// Note:
// The reason for this flag (rather than as argument to stringify()) is
// because Object can be returned stringified from Dynamic::Var::toString(),
// so it must know whether to escape unicode or not.
bool _escapeUnicode;
mutable StructPtr _pStruct;
mutable bool _modified;
};
@@ -276,6 +322,43 @@ private:
//
// inlines
//
inline void Object::setEscapeUnicode(bool escape)
{
_escapeUnicode = true;
}
inline bool Object::getEscapeUnicode() const
{
return _escapeUnicode;
}
inline Object::Iterator Object::begin()
{
return _values.begin();
}
inline Object::ConstIterator Object::begin() const
{
return _values.begin();
}
inline Object::Iterator Object::end()
{
return _values.end();
}
inline Object::ConstIterator Object::end() const
{
return _values.end();
}
inline bool Object::has(const std::string& key) const
{
ValueMap::const_iterator it = _values.find(key);
@@ -329,11 +412,11 @@ inline void Object::remove(const std::string& key)
_values.erase(key);
if (_preserveInsOrder)
{
KeyPtrList::iterator it = _keys.begin();
KeyPtrList::iterator end = _keys.end();
KeyList::iterator it = _keys.begin();
KeyList::iterator end = _keys.end();
for (; it != end; ++it)
{
if (key == **it)
if (key == (*it)->first)
{
_keys.erase(it);
break;
@@ -356,9 +439,9 @@ inline const Dynamic::Var& Object::getValue(ValueMap::const_iterator& it) const
}
inline const Dynamic::Var& Object::getValue(KeyPtrList::const_iterator& it) const
inline const Dynamic::Var& Object::getValue(KeyList::const_iterator& it) const
{
ValueMap::const_iterator itv = _values.find(**it);
ValueMap::const_iterator itv = _values.find((*it)->first);
if (itv != _values.end())
return itv->second;
else

View File

@@ -31,26 +31,29 @@ class JSON_API Stringifier
/// Helper class for creating a string from a JSON object or array.
{
public:
static void condense(const Dynamic::Var& any, std::ostream& out);
static void condense(const Dynamic::Var& any, std::ostream& out, bool escapeUnicode = false);
/// Writes a condensed string representation of the value to the output stream while preserving the insertion order.
///
/// This is just a "shortcut" to stringify(any, out) with name indicating the function effect.
static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0, int step = -1);
static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0, int step = -1, bool escapeUnicode = false);
/// Writes a string representation of the value to the output stream.
///
/// When indent is 0, the string will be created as small as possible.
/// When preserveInsertionOrder is true, the original string object members order will be preserved;
/// otherwise, object members are sorted by their names.
/// Indentation is increased/decreased using number of spaces defined in step.
/// The default value -1 for step indicates that step will be equal to the
/// indent size.
/// If escapeUnicode is true, all unicode characers will be escaped in the
/// resulting string.
static void formatString(const std::string& value, std::ostream& out);
static void formatString(const std::string& value, std::ostream& out, bool escapeUnicode = false);
/// Formats the JSON string and streams it into ostream.
};
inline void Stringifier::condense(const Dynamic::Var& any, std::ostream& out)
inline void Stringifier::condense(const Dynamic::Var& any, std::ostream& out, bool escapeUnicode)
{
stringify(any, out, 0, -1);
stringify(any, out, 0, -1, escapeUnicode);
}