Explorar el Código

[refs #24][add] sort objects by keys

isundil hace 9 años
padre
commit
fae7352de1

+ 5 - 2
doc/jsonstroll.1

@@ -1,7 +1,7 @@
 .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.47.3.
-.TH JSONSTROLL "1" "August 2016" "jsonstroll (jsonstroller suite) 1.0RC1 generated on Aug 17 2016" "User Commands"
+.TH JSONSTROLL "1" "September 2016" "jsonstroll (jsonstroller suite) 1.0RC1 generated on Sep  6 2016" "User Commands"
 .SH NAME
-jsonstroll \- manual page for jsonstroll (jsonstroller suite) 1.0RC1 generated on Aug 17 2016
+jsonstroll \- manual page for jsonstroll (jsonstroller suite) 1.0RC1 generated on Sep  6 2016
 .SH SYNOPSIS
 .B jsonstroll
 [\fI\,OPTIONS\/\fR]
@@ -31,6 +31,9 @@ consider continuing on non\-blocking errors
 \fB\-\-ascii\fR
 ignore unicode values
 .TP
+\fB\-\-keep\-order\fR
+do not sort objects by key
+.TP
 \fB\-\-color\fR[=\fI\,MODE\/\fR]
 colorize output, MODE can be never or always (default when ommited)
 .TP

+ 9 - 1
include/jsonObject.hh

@@ -20,7 +20,7 @@ class JSonObject: public JSonContainer
         /**
          * Add entry
         **/
-        void push(const std::string &key, JSonElement *child);
+        virtual void push(const std::string &key, JSonElement *child);
 
         /**
          * find object by key
@@ -64,3 +64,11 @@ class JSonObject: public JSonContainer
     };
 };
 
+class JSonSortedObject: public JSonObject
+{
+    public:
+        JSonSortedObject(JSonContainer *parent);
+
+        void push(const std::string &key, JSonElement *child);
+};
+

+ 2 - 0
include/jsonObjectEntry.hh

@@ -19,6 +19,8 @@ class JSonObjectEntry: public JSonElement
         std::string stringify() const;
 
         bool operator==(const std::string &) const;
+        bool operator<(const JSonElement *) const;
+        bool operator<(const JSonElement &) const;
         /**
          * Get associated value
         **/

+ 7 - 0
include/params.hh

@@ -30,6 +30,11 @@ class AParams
          * true if --color match conditions
         **/
         virtual bool colorEnabled() const =0;
+
+        /**
+         * true if need sorted object
+        **/
+        virtual bool sortObjects() const =0;
 };
 
 class Params: public AParams
@@ -78,6 +83,7 @@ class Params: public AParams
         bool colorEnabled() const;
         bool isIgnoringUnicode() const;
         bool isDiff() const;
+        bool sortObjects() const;
 
     private:
         /**
@@ -93,5 +99,6 @@ class Params: public AParams
         bool colorMode;
         bool strict;
         bool diffMode;
+        bool sorted;
 };
 

+ 12 - 0
src/jsonObject.cpp

@@ -9,6 +9,9 @@
 JSonObject::JSonObject(JSonContainer *p): JSonContainer(p)
 { }
 
+JSonSortedObject::JSonSortedObject(JSonContainer *p): JSonObject(p)
+{ }
+
 JSonObject::~JSonObject()
 {
     for (JSonElement *i : *this)
@@ -20,6 +23,15 @@ void JSonObject::push(const std::string &key, JSonElement *child)
     this->push_back(new JSonObjectEntry(this, key, child));
 }
 
+void JSonSortedObject::push(const std::string &key, JSonElement *child)
+{
+    JSonObject::iterator pos = begin();
+    JSonObjectEntry *ent = new JSonObjectEntry(this, key, child);
+
+    for (pos = begin(); (pos != end() && *ent < *pos); pos++);
+    this->insert(pos, ent);
+}
+
 JSonObject::const_iterator JSonObject::find(const std::string &key) const
 {
     JSonObject::const_iterator it = cbegin();

+ 12 - 0
src/jsonObjectEntry.cpp

@@ -37,3 +37,15 @@ std::string JSonObjectEntry::stringify() const
     return key;
 }
 
+bool JSonObjectEntry::operator<(const JSonElement *e) const
+{
+    if (dynamic_cast<const JSonObjectEntry*>(e))
+    {
+        return ((const JSonObjectEntry*)e)->key < key;
+    }
+    return false;
+}
+
+bool JSonObjectEntry::operator<(const JSonElement &e) const
+{ return (*this < &e); }
+

+ 7 - 1
src/params.cpp

@@ -34,7 +34,7 @@ bool Params::read()
     bool written = false;
     std::stringstream *input = nullptr;
     ignoreUnicode = false;
-    colorMode = true;
+    colorMode = sorted = true;
 
     for (std::list<std::string>::const_iterator i = params.cbegin(); i != params.cend(); i++)
     {
@@ -61,6 +61,8 @@ bool Params::read()
                 version();
                 return false;
             }
+            else if (tmp == "--keep-order")
+                sorted = false;
             else if (tmp.find("--color=") == 0)
             {
                 std::string mode = tmp.substr(8);
@@ -140,6 +142,7 @@ void Params::usage() const noexcept
     << "  INPUT\t\t\tuse this as input instead of stdin" << std::endl
     << "  -W \t\t\tconsider continuing on non-blocking errors" << std::endl
     << "  --ascii\t\tignore unicode values" << std::endl
+    << "  --keep-order\t\tdo not sort objects by key" << std::endl
     << "  --color[=MODE]\tcolorize output, MODE can be never or always (default when ommited)" << std::endl
     << "  -v, -version\t\tdisplay version information" << std::endl
     << "  -h, --helph\t\tshow this message and exit" << std::endl << std::endl
@@ -170,6 +173,9 @@ bool Params::isStrict() const
 bool Params::colorEnabled() const
 { return colorMode; }
 
+bool Params::sortObjects() const
+{ return sorted; }
+
 bool Params::isIgnoringUnicode() const
 { return ignoreUnicode; }
 

+ 3 - 3
src/streamConsumer.cpp

@@ -77,10 +77,10 @@ JSonObject *StreamConsumer::readObject(JSonContainer *parent)
         if (consumeToken(parent, buf) != nullptr || buf.str() != ":")
             throw JsonUnexpectedException(':', stream.tellg(), history);
         if (result == nullptr)
-            result = new JSonObject(parent);
+            result = (!params || params->sortObjects()) ? new JSonSortedObject(parent) : new JSonObject(parent);
         else if (result->contains(key->getValue()))
         {
-            if (params->isStrict())
+            if (!params || params->isStrict())
                 throw JSonObject::DoubleKeyException(stream.tellg(), key->getValue(), history);
             else // add Warning, new key erase previous one
             {
@@ -177,7 +177,7 @@ JSonElement *StreamConsumer::consumeString(JSonContainer *parent, std::stringstr
                     }
                 }
             }
-            else if (params->isStrict())
+            else if (params && params->isStrict())
                 throw JsonEscapedException(c, stream.tellg(), history);
             else
             {

+ 23 - 0
test/testObjectUnordered.json

@@ -0,0 +1,23 @@
+{
+    "1":"b026324c6904b2a9cb4b88d6d61c81d1",
+    "3":"6d7fce9fee471194aa8b5b6e47267f03",
+    "15":"8c9eb686bf3eb5bd83d9373eadf6504b",
+    "4":"48a24b70a0b376535542b996af517398",
+    "5":"1dcca23355272056f04fe8bf20edfce0",
+    "0":"897316929176464ebc9ad085f31e7284",
+    "6":"9ae0ea9e3c9c6e1b9b6252c8395efdc1",
+    "7":"84bc3da1b3e33a18e8d5e1bdd7a18d7a",
+    "12":"2737b49252e2a4c0fe4c342e92b13285",
+    "8":"c30f7472766d25af1dc80b3ffc9a58c7",
+    "9":"7c5aba41f53293b712fd86d08ed5b36e",
+    "10":"31d30eea8d0968d6458e0ad0027c9f80",
+    "2":"26ab0db90d72e28ad0ba1e22ee510510",
+    "11":"166d77ac1b46a1ec38aa35ab7e628ab5",
+    "13":"aa6ed9e0f26a6eba784aae8267df1951",
+    "14":"367764329430db34be92fd14a7a770ee",
+    "16":"5b6b41ed9b343fed9cd05a66d36650f0",
+    "17":"4d095eeac8ed659b1ce69dcef32ed0dc",
+    "18":"cf4278314ef8e4b996e1b798d8eb92cf",
+    "19":"3bb50ff8eeb7ad116724b56a820139fa",
+    "20":"dbbf8220893d497d403bb9cdf49db7a4"
+}