diff --git a/JSON/include/Poco/JSON/Object.h b/JSON/include/Poco/JSON/Object.h index b85bce8ad4..0d6041fb09 100644 --- a/JSON/include/Poco/JSON/Object.h +++ b/JSON/include/Poco/JSON/Object.h @@ -191,7 +191,7 @@ class JSON_API Object /// Sets a new value void stringify(std::ostream& out, unsigned int indent = 0, int step = -1) const; - /// Prints the object to out. When indent is 0, the object + /// Prints the object to out stream. When indent is 0, the object /// will be printed on a single line without indentation. void remove(const std::string& key); @@ -239,16 +239,16 @@ class JSON_API Object out << '}'; } - typedef std::deque KeyList; - typedef Poco::DynamicStruct::Ptr StructPtr; + typedef std::deque 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(KeyList::const_iterator& it) const; - const Dynamic::Var& getValue(KeyList::const_iterator& it) const; + const std::string& getKey(KeyPtrList::const_iterator& it) const; + const Dynamic::Var& getValue(KeyPtrList::const_iterator& it) const; ValueMap _values; - KeyList _keys; + KeyPtrList _keys; bool _preserveInsOrder; mutable StructPtr _pStruct; }; @@ -318,9 +318,9 @@ inline const Dynamic::Var& Object::getValue(ValueMap::const_iterator& it) const } -inline const Dynamic::Var& Object::getValue(KeyList::const_iterator& it) const +inline const Dynamic::Var& Object::getValue(KeyPtrList::const_iterator& it) const { - return _values.at(*it); + return _values.at(**it); } diff --git a/JSON/include/Poco/JSON/Stringifier.h b/JSON/include/Poco/JSON/Stringifier.h index 9001ced7f8..de3336ff1c 100644 --- a/JSON/include/Poco/JSON/Stringifier.h +++ b/JSON/include/Poco/JSON/Stringifier.h @@ -37,15 +37,9 @@ class JSON_API Stringifier /// 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, bool preserveInsertionOrder, std::ostream& out, unsigned int indent = 0); - /// Writes a String representation of the value to the output stream while preserving the insertion order. - /// When indent is 0, the generated string will be created as small as possible (condensed). - /// When preserveInsertionOrder is true, the original string object members order will be preserved. - /// This is a "shortcut" to stringify(any, out, indent, -1, preserveInsertionOrder). - - static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0, int step = -1, bool preserveInsertionOrder = 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. + static void stringify(const Dynamic::Var& any, std::ostream& out, unsigned int indent = 0, int step = -1); + /// Writes a string representation of the value to the output stream. + /// When indent is 0, the string will be created as small as possible. /// When preserveInsertionOrder is true, the original string object members order will be preserved; /// otherwise, object members are sorted by their names. @@ -56,16 +50,9 @@ class JSON_API Stringifier inline void Stringifier::condense(const Dynamic::Var& any, std::ostream& out) { - stringify(any, out, 0, -1, true); -} - - -inline void Stringifier::stringify(const Dynamic::Var& any, bool preserveInsertionOrder, std::ostream& out, unsigned int indent) -{ - stringify(any, out, indent, -1, preserveInsertionOrder); + stringify(any, out, 0, -1); } - }} // namespace Poco::JSON diff --git a/JSON/src/Object.cpp b/JSON/src/Object.cpp index 7531c73a03..95e80522ea 100644 --- a/JSON/src/Object.cpp +++ b/JSON/src/Object.cpp @@ -101,31 +101,31 @@ void Object::stringify(std::ostream& out, unsigned int indent, int step) const } -const std::string& Object::getKey(KeyList::const_iterator& iter) const +const std::string& Object::getKey(KeyPtrList::const_iterator& iter) const { ValueMap::const_iterator it = _values.begin(); ValueMap::const_iterator end = _values.end(); for (; it != end; ++it) { - if (it->first == *iter) return it->first; + if (it->first == **iter) return it->first; } - throw NotFoundException(*iter); + throw NotFoundException(**iter); } void Object::set(const std::string& key, const Dynamic::Var& value) { - _values[key] = value; + std::pair ret = _values.insert(ValueMap::value_type(key, value)); if (_preserveInsOrder) { - KeyList::iterator it = _keys.begin(); - KeyList::iterator end = _keys.end(); + KeyPtrList::iterator it = _keys.begin(); + KeyPtrList::iterator end = _keys.end(); for (; it != end; ++it) { - if (key == *it) return; + if (key == **it) return; } - _keys.push_back(key); + _keys.push_back(&ret.first->first); } } diff --git a/JSON/src/Stringifier.cpp b/JSON/src/Stringifier.cpp index af240c395f..170f714a38 100644 --- a/JSON/src/Stringifier.cpp +++ b/JSON/src/Stringifier.cpp @@ -28,7 +28,7 @@ namespace Poco { namespace JSON { -void Stringifier::stringify(const Var& any, std::ostream& out, unsigned int indent, int step, bool preserveInsertionOrder) +void Stringifier::stringify(const Var& any, std::ostream& out, unsigned int indent, int step) { if (step == -1) step = indent; diff --git a/JSON/testsuite/src/JSONTest.cpp b/JSON/testsuite/src/JSONTest.cpp index b84274d0ab..8b5209513c 100644 --- a/JSON/testsuite/src/JSONTest.cpp +++ b/JSON/testsuite/src/JSONTest.cpp @@ -1394,13 +1394,27 @@ void JSONTest::testStringify() void JSONTest::testStringifyPreserveOrder() { - Object jObj(true); - jObj.set("foo", 0); - jObj.set("bar", 0); - jObj.set("baz", 0); + Object presObj(true); + presObj.set("foo", 0); + presObj.set("bar", 0); + presObj.set("baz", 0); std::stringstream ss; - jObj.stringify(ss); + presObj.stringify(ss); assert(ss.str() == "{\"foo\":0,\"bar\":0,\"baz\":0}"); + ss.str(""); + Stringifier::stringify(presObj, ss); + assert(ss.str() == "{\"foo\":0,\"bar\":0,\"baz\":0}"); + + Object noPresObj; + noPresObj.set("foo", 0); + noPresObj.set("bar", 0); + noPresObj.set("baz", 0); + ss.str(""); + noPresObj.stringify(ss); + assert(ss.str() == "{\"bar\":0,\"baz\":0,\"foo\":0}"); + ss.str(""); + Stringifier::stringify(noPresObj, ss); + assert(ss.str() == "{\"bar\":0,\"baz\":0,\"foo\":0}"); std::string json = "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\" , \"age\" : 38 }, \"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, " "\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], " diff --git a/doc/99100-ReleaseNotes.page b/doc/99100-ReleaseNotes.page index 303eead042..9987274fba 100644 --- a/doc/99100-ReleaseNotes.page +++ b/doc/99100-ReleaseNotes.page @@ -1,6 +1,30 @@ POCO C++ Libraries Release Notes AAAIntroduction +!!!Release 1.7.0 + +!!Summary of Changes + + - JSON Stringifier fails with preserve insert order #819 + + +!!Incompatible Changes and Possible Transition Issues + + - Modified JSON::Stringifier interface (removed preserve order flag which had no effect) + + +!!!Release 1.6.1 + +!!Summary of Changes + + - + + +!!Incompatible Changes and Possible Transition Issues + + - + + !!!Release 1.6.0 !!Summary of Changes