sync wip_alan_T7196_Json_generator
authorAlan <alan@roojs.com>
Fri, 22 Apr 2022 04:16:08 +0000 (12:16 +0800)
committerAlan <alan@roojs.com>
Fri, 22 Apr 2022 04:16:08 +0000 (12:16 +0800)
src/JsRender/JsonGen.vala [new file with mode: 0644]

diff --git a/src/JsRender/JsonGen.vala b/src/JsRender/JsonGen.vala
new file mode 100644 (file)
index 0000000..1c982b0
--- /dev/null
@@ -0,0 +1,230 @@
+
+/**
+
+based on...
+https://gitlab.gnome.org/GNOME/json-glib/-/blob/master/json-glib/json-generator.c
+
+note - that could probably be fixed by just adding the sort method on members List..
+
+*/
+namespace JsRender {
+       public class JsonGen : Object 
+       {
+               Json.Generator generator;
+               Json.Node node;
+               public bool pretty = true;
+               public int indent = 1;
+               public char indent_char = ' ';
+               public JsonGen( Json.Node node )
+               {
+                        
+                       this.generator = new Json.Generator ();
+                       this.generator.indent = this.indent;
+                       this.generator.pretty = this.pretty;
+                       this.node = node;
+               }
+                
+               
+               public string to_data()
+               {
+                       var buffer = new GLib.StringBuilder();
+                       dump_node(buffer,0, this.node, "", false);
+                       return buffer.str;
+               }
+               
+               
+
+               void dump_node (
+                               GLib.StringBuilder buffer,
+                               int                     level,
+                      Json.Node        node,
+                      string           name,
+                      bool                     has_name
+                      )
+               {
+               
+                       
+                         if (this.pretty) {
+
+                                 for (var i = 0; i < (level * this.indent); i++) {
+                                               buffer.append_c(this.indent_char);
+                                 }
+                         }
+
+                         if (has_name){
+                                       // fixme...
+                                       // initiate a node as a string... then output it..
+                                       //buffer.append_c( '"'); // might not be needed..
+                                       var k = new Json.Node(Json.NodeType.VALUE);
+                                       k.init_string(name);
+                                       dump_value(buffer,k);
+                                       
+                                       //buffer.append_c( '"');
+                       
+                                 if (this.pretty) {
+                                       buffer.append( " : ");
+                                 } else {
+                                       buffer.append_c( ':');
+                               }
+               }
+
+                       switch (node.get_node_type()) {
+                               case Json.NodeType.NULL:
+                                 buffer.append( "null");
+                                 break;
+
+                               case Json.NodeType.VALUE:
+                                 size_t strlen;
+                                 this.generator.set_root(node);
+                                 buffer.append( this.generator.to_data(out strlen) );
+                                 break;
+
+                               case Json.NodeType.ARRAY:
+                                 this.dump_array ( buffer, level, node.get_array());
+                                 break;
+
+                               case Json.NodeType.OBJECT:
+                                 this.dump_object (buffer, level, node.get_object());
+                                 break;
+                       }
+               }
+               
+               void dump_value (GLib.StringBuilder buffer, Json.Node node)
+               {
+                       size_t slen;
+                       this.generator.set_root(node);
+                       buffer.append( this.generator.to_data(out slen) );
+               }
+               
+               void dump_array (
+           GLib.StringBuilder buffer,
+            int           level,
+            Json.Array     array)
+               {
+
+
+                 var array_len = array.get_length();
+                 
+                 var pretty = this.pretty;
+                 var  indent = this.indent;
+
+                 buffer.append_c( '[');
+
+                 if (array_len == 0) {
+                          buffer.append_c( ']');
+                          return;
+                 }
+
+                 for (var i = 0; i < array_len; i++) {
+                         var cur = array.get_element ( i);
+
+                         if (i == 0 && pretty) {
+                               buffer.append_c('\n');
+                         }
+                         this.dump_node ( buffer, level + 1, cur, "", false);
+
+                         if ((i + 1) != array_len) {
+                               buffer.append_c( ',');
+                        }
+                         if (pretty) {
+                               buffer.append_c( '\n');
+                       } 
+                 }
+
+                 if (pretty) {
+                         for (var i = 0; i < (level * this.indent); i++) {
+                               buffer.append_c(this.indent_char);
+                        }
+                 }
+
+                 buffer.append_c( ']');
+               }
+
+                void dump_object (
+                       GLib.StringBuilder buffer,
+                       int           level,
+                       Json.Object     object)
+               {
+
+
+                 var  pretty = this.pretty;
+                 var  indent = this.indent;
+
+
+                 buffer.append_c('{');
+                 buffer.append_c(  '\n');
+                 var members = object.get_members();
+                 members.sort(GLib.strcmp);
+                 
+                       var mi = -1;
+                       members.foreach ( (member_name) => {
+                               mi++;
+
+                               var cur = object.get_member( member_name);
+
+                               //if (mi > 0 && pretty) {
+                               //      buffer.append_c(  '\n');
+                               //}
+
+                               dump_node (buffer, level + 1, cur,  member_name, true);
+
+                               if (mi < members.length()-1) {
+                                       buffer.append_c(  ',');
+                               }
+                               if (pretty) {
+                                       buffer.append_c(  '\n');
+                               }
+                       });
+
+                       if (pretty)
+                       {
+                               for (var i = 0; i < (level * this.indent); i++) {
+                                       buffer.append_c( this.indent_char);
+                               }
+                       }
+
+                buffer.append_c(  '}');
+               }
+
+
+    }                                  
+                                       
+}
+
+
+/*
+compile : 
+
+valac --pkg json-glib-1.0 -D JSON_TESTCODE Json.vala
+*/
+
+#if JSON_TESTCODE
+void main (string[] args) {
+
+       var testjson = """
+       {"quiz":{"sport":{"q1":{"question":"Which one is correct team name in NBA?","options":["New York Bulls",
+       "Los Angeles Kings","Golden State Warriros","Huston Rocket"],"answer":"Huston Rocket"}},"maths":
+       {"q1":{"question":"5 + 7 = ?","options":["10","11","12","13"],"answer":"12"},"q2":
+       {"question":"12 - 8 = ?","options":["1","2","3","4"],"answer":"4"}}}}
+       """;
+       var parser =   new Json.Parser ();
+       parser.load_from_data(testjson);
+       
+       var node = parser.get_root ();
+
+       var js = new JsRender.JsonGen(node);
+       print("OUT: %s", js.to_data());
+       
+       
+       
+}
+
+
+
+
+
+
+
+