Fix another two bugs in json to xml convert library
authorEduardo Ramos Testillano (eramedu) <eduardo.ramos.testillano@ericsson.com>
Fri, 8 May 2020 13:05:44 +0000 (15:05 +0200)
committerEduardo Ramos Testillano (eramedu) <eduardo.ramos.testillano@ericsson.com>
Fri, 8 May 2020 13:05:44 +0000 (15:05 +0200)
The first one: the third nested child in 'test.json' was being
considered 'grandchild', that is to say, stack pop was not
correctly managed. The problem arised when poping after a
nested previous array. Fixed with new control booleans.

Also, a problem to finish a parent node xml tag arised when
we had two consecutive nested levels. This is ensured and
tested with new 'test2.json'.

include/anna/json/SaxConsumer.hpp

index 33473ed..a3cd194 100644 (file)
@@ -22,7 +22,7 @@ namespace json {
 class SaxConsumer : public nlohmann::json::json_sax_t
 {
   int indent_;
-  bool started_;
+  bool started_, last_was_start_, last_was_array_;
   std::stringstream result_;
   std::stringstream current_object_;
   std::stack<std::string> nodes_stack_;
@@ -30,52 +30,62 @@ class SaxConsumer : public nlohmann::json::json_sax_t
 
   public:
 
-  SaxConsumer() : started_(false), indent_(-ANNA_XML_INDENTATION_SPACES) {}
+  SaxConsumer() : started_(false), last_was_start_(false), last_was_array_(false), indent_(-ANNA_XML_INDENTATION_SPACES) {}
 
   const std::stringstream & getResult() const { return result_; }
 
   bool null() override
   {
     current_object_ << "<null>";
+    last_was_start_ = false;
     return true;
   }
 
   bool boolean(bool val) override
   {
     current_object_ << std::quoted(val ? "true" : "false");
+    last_was_start_ = false;
     return true;
   }
 
   bool number_integer(number_integer_t val) override
   {
     current_object_ << std::quoted(std::to_string(val));
+    last_was_start_ = false;
     return true;
   }
 
   bool number_unsigned(number_unsigned_t val) override
   {
     current_object_ << std::quoted(std::to_string(val));
+    last_was_start_ = false;
     return true;
   }
 
   bool number_float(number_float_t val, const string_t& s) override
   {
     current_object_ << std::quoted(s);
+    last_was_start_ = false;
     return true;
   }
 
   bool string(string_t& val) override
   {
     current_object_ << std::quoted(val);
+    last_was_start_ = false;
     return true;
   }
 
   bool start_object(std::size_t elements) override
   {
-    nodes_stack_.push(key_);
-    if (!started_) { started_ = true ; return true; } // ignore first start object (which is whole json object {)
+    if (!started_) { started_ = true ; return true; }
     indent_ += ANNA_XML_INDENTATION_SPACES;
+    if (last_was_start_) result_ << ">\n";
+    last_was_start_ = true;
+    if (!last_was_array_) nodes_stack_.push(key_);
     result_ << std::string(indent_, ' ') << "<" << nodes_stack_.top();
+    if (last_was_array_) nodes_stack_.push(key_);
+    last_was_array_ = false;
     return true;
   }
 
@@ -85,8 +95,8 @@ class SaxConsumer : public nlohmann::json::json_sax_t
     if (current_object_.str().empty()) close = "";
     result_ << current_object_.str() << close;
     if (indent_ < 0) return true;
+    if (close == "") result_ << std::string(indent_, ' ') << "</" << nodes_stack_.top() << ">";
     indent_ -= ANNA_XML_INDENTATION_SPACES;
-    if (close == "") result_ << "</" << nodes_stack_.top() << ">";
     result_ << "\n";
     current_object_.str("");
     nodes_stack_.pop();
@@ -103,8 +113,8 @@ class SaxConsumer : public nlohmann::json::json_sax_t
 
   bool end_array() override
   {
-    result_ << std::string(indent_, ' ');
     nodes_stack_.pop();
+    last_was_array_ = true;
     return true;
   }