da23d86d583dd3642b0d9341c47b8fe3e9b6514d
[roobuilder] / src / JsRender / JsonGen.vala
1
2 /**
3
4 based on...
5 https://gitlab.gnome.org/GNOME/json-glib/-/blob/master/json-glib/json-generator.c
6
7 note - that could probably be fixed by just adding the sort method on members List..
8
9 */
10 namespace JsRender {
11  
12         public class JsonGen : Object 
13         {
14  
15                 Json.Generator generator;
16                 Json.Node node;
17                 public bool pretty = true;
18                 public int indent = 1;
19                 public char indent_char = ' ';
20                 public JsonGen( Json.Node node )
21                 {
22                          
23                         this.generator = new Json.Generator ();
24                         this.generator.indent = this.indent;
25                         this.generator.pretty = this.pretty;
26                         this.node = node;
27                 }
28                  
29                 
30                 public string to_data()
31                 {
32                         var buffer = new GLib.StringBuilder();
33                         dump_node(buffer,0, this.node, "", false);
34                         return buffer.str;
35                 }
36                 
37                 
38
39                 void dump_node (
40                                 GLib.StringBuilder buffer,
41                                 int                     level,
42                        Json.Node        node,
43                        string           name,
44                        bool                     has_name
45                        )
46                 {
47                 
48                         
49                           if (this.pretty) {
50
51                                   for (var i = 0; i < (level * this.indent); i++) {
52                                                 buffer.append_c(this.indent_char);
53                                   }
54                           }
55
56                           if (has_name){
57                                         // fixme...
58                                         // initiate a node as a string... then output it..
59                                         //buffer.append_c( '"'); // might not be needed..
60                                         var k = new Json.Node(Json.NodeType.VALUE);
61                                         k.init_string(name);
62                                         dump_value(buffer,k);
63                                         
64                                         //buffer.append_c( '"');
65                         
66                                   if (this.pretty) {
67                                         buffer.append( " : ");
68                                   } else {
69                                         buffer.append_c( ':');
70                                 }
71                 }
72
73                         switch (node.get_node_type()) {
74                                 case Json.NodeType.NULL:
75                                   buffer.append( "null");
76                                   break;
77
78                                 case Json.NodeType.VALUE:
79                                   size_t sl;
80                                   this.generator.set_root(node);
81                                    var str = this.generator.to_data(out sl);
82                   buffer.append( str );
83  
84                                   break;
85
86                                 case Json.NodeType.ARRAY:
87                                   this.dump_array ( buffer, level, node.get_array());
88                                   break;
89
90                                 case Json.NodeType.OBJECT:
91                                   this.dump_object (buffer, level, node.get_object());
92                                   break;
93                         }
94                 }
95                 
96                 void dump_value (GLib.StringBuilder buffer, Json.Node node)
97                 {
98                         size_t slen;
99                         this.generator.set_root(node);
100                         buffer.append( this.generator.to_data(out slen) );
101                 }
102                 
103                 void dump_array (
104            GLib.StringBuilder buffer,
105             int           level,
106             Json.Array     array)
107                 {
108
109
110                   var array_len = array.get_length();
111                   
112                   var pretty = this.pretty;
113  
114
115                   buffer.append_c( '[');
116
117                   if (array_len == 0) {
118                            buffer.append_c( ']');
119                            return;
120                   }
121
122                   for (var i = 0; i < array_len; i++) {
123                           var cur = array.get_element ( i);
124
125                           if (i == 0 && pretty) {
126                                 buffer.append_c('\n');
127                           }
128                           this.dump_node ( buffer, level + 1, cur, "", false);
129
130                           if ((i + 1) != array_len) {
131                                 buffer.append_c( ',');
132                          }
133                           if (pretty) {
134                                 buffer.append_c( '\n');
135                         } 
136                   }
137
138                   if (pretty) {
139                           for (var i = 0; i < (level * this.indent); i++) {
140                                 buffer.append_c(this.indent_char);
141                          }
142                   }
143
144                   buffer.append_c( ']');
145                 }
146
147                  void dump_object (
148                         GLib.StringBuilder buffer,
149                         int           level,
150                         Json.Object     object)
151                 {
152
153
154                   var  pretty = this.pretty;
155
156
157
158                   buffer.append_c('{');
159                   buffer.append_c(  '\n');
160                   var members = object.get_members();
161                   members.sort(GLib.strcmp);
162                   
163                         var mi = -1;
164                         members.foreach ( (member_name) => {
165                                 mi++;
166
167                                 var cur = object.get_member( member_name);
168
169                                 //if (mi > 0 && pretty) {
170                                 //      buffer.append_c(  '\n');
171                                 //}
172
173                                 dump_node (buffer, level + 1, cur,  member_name, true);
174
175                                 if (mi < members.length()-1) {
176                                         buffer.append_c(  ',');
177                                 }
178                                 if (pretty) {
179                                         buffer.append_c(  '\n');
180                                 }
181                         });
182
183                         if (pretty)
184                         {
185                                 for (var i = 0; i < (level * this.indent); i++) {
186                                         buffer.append_c( this.indent_char);
187                                 }
188                         }
189
190                  buffer.append_c(  '}');
191                 }
192
193
194     }                                   
195                                         
196 }
197
198
199 /*
200 compile : 
201
202 valac --pkg json-glib-1.0 -D JSON_TESTCODE Json.vala
203 */
204
205 #if JSON_TESTCODE
206 void main (string[] args) {
207
208         var testjson = """
209         {"quiz":{"sport":{"q1":{"question":"Which one is correct team name in NBA?","options":["New York Bulls",
210         "Los Angeles Kings","Golden State Warriros","Huston Rocket"],"answer":"Huston Rocket"}},"maths":
211         {"q1":{"question":"5 + 7 = ?","options":["10","11","12","13"],"answer":"12"},"q2":
212         {"question":"12 - 8 = ?","options":["1","2","3","4"],"answer":"4"}}}}
213         """;
214         var parser =   new Json.Parser ();
215         parser.load_from_data(testjson);
216         
217         var node = parser.get_root ();
218
219         var js = new JsRender.JsonGen(node);
220         print("OUT: %s", js.to_data());
221         
222         
223         
224 }
225
226
227
228
229
230
231
232