2f8a1b8c96f05eb509836e1eff834c55c5d5d3d5
[platform/core/context/context-provider.git] / common / shared / Json.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <cstdio>
18 #include <string>
19 #include <vector>
20 #include <sstream>
21 #include <locale>
22 #include <iomanip>
23 #include <json-glib/json-glib.h>
24 #include <Types.h>
25 #include <Json.h>
26
27 #define PATH_DELIM      '.'
28 #define MAX_PRECISION 15
29 #define GVAR_VALUES     "values"
30 #define GVAR_TYPES      "types"
31
32 using namespace ctx;
33
34 static std::string __double_to_string(double in)
35 {
36         /* Locale-independent double-to-string conversion */
37         int prec = MAX_PRECISION;
38         std::string out;
39         std::ostringstream ostr;
40
41         ostr.imbue(std::locale("C"));
42         ostr << std::setprecision(prec) << in;
43         out = ostr.str();
44
45         if (out.find('e') == std::string::npos)
46                 return out;
47
48         /* If 'out' is in scientific notation */
49         ostr.clear();
50         ostr.str(std::string());
51         ostr.imbue(std::locale("C"));
52
53         /* Get the number of fraction digits to precisely print the number */
54         double number = in * 10;
55         while (static_cast<int>(number) == 0) {
56                 number *= 10;
57                 ++prec;
58         }
59
60         ostr << std::fixed << std::setprecision(prec) << in;
61         out = ostr.str();
62
63         /* Remove trailing '0' */
64         std::size_t found = out.find_last_not_of("0");
65         if (found != std::string::npos)
66                 out.erase(found + 1);
67
68         /* If 'out' ends with '.' */
69         if (out.back() == '.')
70                 out.erase(out.end() - 1);
71
72         return out;
73 }
74
75 static double __string_to_double(const char* in)
76 {
77         IF_FAIL_RETURN_TAG(in, 0, _E, "Parameter NULL");
78
79         double out;
80
81         /* Locale-independent string-to-double conversion */
82         std::istringstream istr(in);
83         istr.imbue(std::locale("C"));
84         istr >> out;
85
86         return out;
87 }
88
89 SO_EXPORT Json::Json() :
90         __jsonNode(NULL)
91 {
92         JsonObject *obj = json_object_new();
93         IF_FAIL_VOID_TAG(obj, _E, "Json object construction failed");
94
95         __jsonNode = json_node_new(JSON_NODE_OBJECT);
96         if (!__jsonNode) {
97                 json_object_unref(obj);
98                 _E("Json object construction failed");
99         }
100
101         json_node_set_object(__jsonNode, obj);
102         json_object_unref(obj);
103 }
104
105 SO_EXPORT Json::Json(const Json &j)
106         : __jsonNode(NULL)
107 {
108         __jsonNode = json_node_copy(j.__jsonNode);
109         IF_FAIL_VOID_TAG(__jsonNode, _E, "Json object construction failed");
110 }
111
112 SO_EXPORT Json::Json(const char *s)
113         : __jsonNode(NULL)
114 {
115         if (s) {
116                 __parse(s);
117         } else {
118                 __parse(EMPTY_JSON_OBJECT);
119         }
120 }
121
122 SO_EXPORT Json::Json(const std::string &s)
123         : __jsonNode(NULL)
124 {
125         if (s.empty()) {
126                 __parse(EMPTY_JSON_OBJECT);
127         } else {
128                 __parse(s.c_str());
129         }
130 }
131
132 SO_EXPORT Json::~Json()
133 {
134         __release();
135 }
136
137 void Json::__parse(const char *s)
138 {
139         gboolean result;
140         JsonParser *parser = NULL;
141         JsonNode *root = NULL;
142
143         parser = json_parser_new();
144         IF_FAIL_VOID_TAG(parser, _E, "Memory allocation failed");
145
146         result = json_parser_load_from_data(parser, s, -1, NULL);
147         IF_FAIL_CATCH_TAG(result, _E, "Parsing failed");
148
149         root = json_parser_get_root(parser);
150         IF_FAIL_CATCH_TAG(root, _E, "Getting root failed");
151
152         __jsonNode = json_node_copy(root);
153         IF_FAIL_CATCH_TAG(__jsonNode, _E, "Copying failed");
154
155 CATCH:
156         if (parser)
157                 g_object_unref(parser);
158 }
159
160 void Json::__release()
161 {
162         if (__jsonNode) {
163                 json_node_free(__jsonNode);
164                 __jsonNode = NULL;
165         }
166 }
167
168 SO_EXPORT bool Json::valid()
169 {
170         return (__jsonNode != NULL);
171 }
172
173 SO_EXPORT Json& Json::operator=(const Json &j)
174 {
175         __release();
176         __jsonNode = json_node_copy(j.__jsonNode);
177         if (!__jsonNode) {
178                 _E("Json object copy failed");
179         }
180         return *this;
181 }
182
183 SO_EXPORT Json& Json::operator=(const char *s)
184 {
185         __release();
186         if (s) {
187                 __parse(s);
188         } else {
189                 __parse(EMPTY_JSON_OBJECT);
190         }
191         return *this;
192 }
193
194 SO_EXPORT Json& Json::operator=(const std::string &s)
195 {
196         __release();
197         if (s.empty()) {
198                 __parse(EMPTY_JSON_OBJECT);
199         } else {
200                 __parse(s.c_str());
201         }
202         return *this;
203 }
204
205 SO_EXPORT bool Json::operator==(const Json &rhs)
206 {
207         return __nodeEq(__jsonNode, rhs.__jsonNode);
208 }
209
210 SO_EXPORT bool Json::operator!=(const Json &rhs)
211 {
212         return !operator==(rhs);
213 }
214
215 char* Json::__strDup()
216 {
217         IF_FAIL_RETURN_TAG(__jsonNode, NULL, _E, "Json object not initialized");
218
219         JsonGenerator *jgen = NULL;
220         char *output = NULL;
221
222         jgen = json_generator_new();
223         IF_FAIL_CATCH(jgen);
224
225         json_generator_set_root(jgen, __jsonNode);
226         output = json_generator_to_data(jgen, NULL);
227         IF_FAIL_CATCH(output);
228
229         g_object_unref(jgen);
230         return output;
231
232 CATCH:
233         if (jgen) {
234                 g_object_unref(jgen);
235         }
236
237         _E("Memory allocation failed");
238         return NULL;
239 }
240
241 SO_EXPORT std::string Json::str()
242 {
243         std::string output;
244         char *_s = __strDup();
245         IF_FAIL_RETURN(_s, output = EMPTY_JSON_OBJECT);
246
247         output = _s;
248         g_free(_s);
249
250         return output;
251 }
252
253 static std::vector<std::string> __tokenize_path(std::string path)
254 {
255         std::vector<std::string> tokens;
256         std::size_t begin = 0;
257         std::size_t end = path.find(PATH_DELIM, 0);
258
259         while (end != std::string::npos) {
260                 tokens.push_back(path.substr(begin, end - begin));
261                 begin = end + 1;
262                 end = path.find(PATH_DELIM, begin);
263         }
264
265         tokens.push_back(path.substr(begin));
266         return tokens;
267 }
268
269 static JsonObject* __traverse(JsonNode *jnode, const char *path, bool force)
270 {
271         IF_FAIL_RETURN_TAG(jnode, NULL, _E, "Invalid parameter");
272
273         unsigned int depth = 0;
274         std::vector<std::string> pathToken;
275         JsonObject *jobj = NULL;
276         JsonObject *childObj = NULL;
277         JsonNode *childNode = NULL;
278
279         jobj = json_node_get_object(jnode);
280         IF_FAIL_RETURN(jobj, NULL);
281
282         if (path)
283                 pathToken = __tokenize_path(path);
284
285         for (depth = 0; depth < pathToken.size(); depth++) {
286                 if (!json_object_has_member(jobj, pathToken[depth].c_str())) {
287                         if (!force) {
288                                 return NULL;
289                         }
290                         childObj = json_object_new();
291                         IF_FAIL_RETURN_TAG(childObj, NULL, _E, "Memory allocation failed");
292                         json_object_set_object_member(jobj, pathToken[depth].c_str(), childObj);
293                 }
294                 childNode = json_object_get_member(jobj, pathToken[depth].c_str());
295                 IF_FAIL_RETURN(childNode && json_node_get_node_type(childNode) == JSON_NODE_OBJECT, NULL);
296
297                 jobj = json_node_get_object(childNode);
298                 IF_FAIL_RETURN(jobj, NULL);
299         }
300
301         return jobj;
302 }
303
304 SO_EXPORT bool Json::set(const char *path, const char *key, Json &val)
305 {
306         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
307         IF_FAIL_RETURN_TAG(key && val.__jsonNode, false, _E, "Invalid parameter");
308
309         JsonObject *jobj = __traverse(__jsonNode, path, true);
310         IF_FAIL_RETURN(jobj, false);
311
312         if (json_object_has_member(jobj, key))
313                 json_object_remove_member(jobj, key);
314
315         json_object_set_member(jobj, key, val.__jsonNode);
316         val.__jsonNode = NULL;
317         val = Json();
318
319         return true;
320 }
321
322 SO_EXPORT bool Json::set(const char *path, const char *key, int val)
323 {
324         return set(path, key, static_cast<int64_t>(val));
325 }
326
327 SO_EXPORT bool Json::set(const char *path, const char *key, int64_t val)
328 {
329         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
330         IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
331
332         JsonObject *jobj = __traverse(__jsonNode, path, true);
333         IF_FAIL_RETURN(jobj, false);
334
335         if (json_object_has_member(jobj, key))
336                 json_object_remove_member(jobj, key);
337
338         json_object_set_int_member(jobj, key, val);
339         return true;
340 }
341
342 SO_EXPORT bool Json::set(const char *path, const char *key, double val)
343 {
344         return set(path, key, __double_to_string(val));
345 }
346
347 SO_EXPORT bool Json::set(const char *path, const char *key, std::string val)
348 {
349         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
350         IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
351
352         JsonObject *jobj = __traverse(__jsonNode, path, true);
353         IF_FAIL_RETURN(jobj, false);
354
355         if (json_object_has_member(jobj, key)) {
356                 json_object_remove_member(jobj, key);
357         }
358
359         json_object_set_string_member(jobj, key, val.c_str());
360         return true;
361 }
362
363 SO_EXPORT bool Json::set(const char *path, const char *key, GVariant *val)
364 {
365 #if JSON_CHECK_VERSION(0, 14, 0)
366         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
367         IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
368
369         const gchar *typeStr = g_variant_get_type_string(val);
370         IF_FAIL_RETURN_TAG(typeStr, false, _E, "GVariant manipulation failed");
371
372         json_node_t *node = json_gvariant_serialize(val);
373         IF_FAIL_RETURN_TAG(node, false, _E, "GVariant manipulation failed");
374
375         Json gvarJson;
376         gvarJson.set(NULL, GVAR_TYPES, std::string(typeStr));
377         json_object_set_member(json_node_get_object(gvarJson.__jsonNode), GVAR_VALUES, node);
378
379         return set(path, key, gvarJson);
380 #else
381         _E("Insufficient version of json-glib(" JSON_VERSION_S ")");
382         return false;
383 #endif
384 }
385
386 SO_EXPORT bool Json::get(const char *path, const char *key, Json *val)
387 {
388         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
389         IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
390
391         JsonObject *jobj = NULL;
392         JsonNode *node = NULL;
393
394         jobj = __traverse(__jsonNode, path, false);
395         IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), false);
396
397         node = json_object_dup_member(jobj, key);
398         IF_FAIL_RETURN_TAG(node, false, _E, "Memory allocation failed");
399
400         if (val->__jsonNode) {
401                 json_node_free(val->__jsonNode);
402         }
403         val->__jsonNode = node;
404
405         return true;
406 }
407
408 static JsonNode* __get_value_node(JsonNode *jnode, const char *path, const char *key)
409 {
410         JsonNode *node = NULL;
411         JsonObject *jobj = NULL;
412         JsonNodeType ntype;
413
414         jobj = __traverse(jnode, path, false);
415         IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), NULL);
416
417         node = json_object_get_member(jobj, key);
418         ntype = json_node_get_node_type(node);
419         IF_FAIL_RETURN(ntype == JSON_NODE_VALUE, NULL);
420
421         return node;
422 }
423
424 SO_EXPORT bool Json::get(const char *path, const char *key, int *val)
425 {
426         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
427         IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
428
429         int64_t v;
430
431         if (get(path, key, &v)) {
432                 *val = v;
433                 return true;
434         }
435
436         return false;
437 }
438
439 SO_EXPORT bool Json::get(const char *path, const char *key, int64_t *val)
440 {
441         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
442         IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
443
444         JsonNode *node = __get_value_node(__jsonNode, path, key);
445         IF_FAIL_RETURN(node, false);
446
447         GType vtype = json_node_get_value_type(node);
448         if (vtype == G_TYPE_INT64) {
449                 *val = json_node_get_int(node);
450         } else if (vtype == G_TYPE_STRING) {
451                 //TODO: if the string is not a number?
452                 *val = static_cast<int64_t>(__string_to_double(json_node_get_string(node)));
453         } else {
454                 return false;
455         }
456
457         return true;
458 }
459
460 SO_EXPORT bool Json::get(const char *path, const char *key, double *val)
461 {
462         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
463         IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
464
465         JsonNode *node = __get_value_node(__jsonNode, path, key);
466         IF_FAIL_RETURN(node, false);
467
468         GType vtype = json_node_get_value_type(node);
469         if (vtype == G_TYPE_DOUBLE) {
470                 *val = json_node_get_double(node);
471         } else if (vtype == G_TYPE_INT64) {
472                 *val = json_node_get_int(node);
473         } else if (vtype == G_TYPE_STRING) {
474                 *val = __string_to_double(json_node_get_string(node));
475         } else {
476                 return false;
477         }
478
479         return true;
480 }
481
482 SO_EXPORT bool Json::get(const char *path, const char *key, std::string *val)
483 {
484         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
485         IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
486
487         JsonNode *node = __get_value_node(__jsonNode, path, key);
488         IF_FAIL_RETURN(node, false);
489
490         GType vtype = json_node_get_value_type(node);
491         IF_FAIL_RETURN(vtype == G_TYPE_STRING, false);
492
493         const char *str_val = json_node_get_string(node);
494         IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
495
496         *val = str_val;
497         return true;
498 }
499
500 SO_EXPORT bool Json::get(const char *path, const char *key, GVariant **val)
501 {
502 #if JSON_CHECK_VERSION(0, 14, 0)
503         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
504         IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
505
506         bool ret;
507         Json gvarJson;
508         ret = get(path, key, &gvarJson);
509         IF_FAIL_RETURN(ret, false);
510
511         std::string gvarTypes;
512         ret = gvarJson.get(NULL, GVAR_TYPES, &gvarTypes);
513         IF_FAIL_RETURN(ret, false);
514
515         Json gvarValues;
516         ret = gvarJson.get(NULL, GVAR_VALUES, &gvarValues);
517         IF_FAIL_RETURN(ret, false);
518
519         GError *gerr = NULL;
520         *val = json_gvariant_deserialize(gvarValues.__jsonNode, gvarTypes.c_str(), &gerr);
521         HANDLE_GERROR(gerr);
522         IF_FAIL_RETURN(*val, false);
523
524         return true;
525 #else
526         _E("Insufficient version of json-glib(" JSON_VERSION_S ")");
527         *val = NULL;
528         return false;
529 #endif
530 }
531
532 SO_EXPORT bool Json::remove(const char *path, const char *key)
533 {
534         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
535         IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
536
537         JsonObject *jobj = __traverse(__jsonNode, path, true);
538         IF_FAIL_RETURN(jobj, false);
539
540         if (json_object_has_member(jobj, key))
541                 json_object_remove_member(jobj, key);
542
543         return true;
544 }
545
546 static JsonArray* __get_array(JsonNode *jnode, const char *path, const char *key, bool force)
547 {
548         JsonNode *node = NULL;
549         JsonArray *arr = NULL;
550         JsonObject *jobj = NULL;
551
552         jobj = __traverse(jnode, path, force);
553         IF_FAIL_RETURN(jobj, NULL);
554
555         if (!json_object_has_member(jobj, key)) {
556                 if (force) {
557                         arr = json_array_new();
558                         IF_FAIL_RETURN_TAG(arr, NULL, _E, "Memory allocation failed");
559                         json_object_set_array_member(jobj, key, arr);
560                 } else {
561                         return NULL;
562                 }
563         }
564         node = json_object_get_member(jobj, key);
565         IF_FAIL_RETURN_TAG(node && json_node_get_node_type(node) == JSON_NODE_ARRAY,
566                         NULL, _W, "Type mismatched: %s", key);
567
568         return json_node_get_array(node);
569 }
570
571 SO_EXPORT int Json::getSize(const char *path, const char *key)
572 {
573         IF_FAIL_RETURN_TAG(this->__jsonNode, -1, _E, "Json object not initialized");
574         IF_FAIL_RETURN_TAG(key, -1, _E, "Invalid parameter");
575
576         JsonArray *jarr = __get_array(__jsonNode, path, key, false);
577         IF_FAIL_RETURN_TAG(jarr, -1, _D, "Mismatched data type");
578
579         return json_array_get_length(jarr);
580 }
581
582 SO_EXPORT bool Json::append(const char *path, const char *key, Json &val)
583 {
584         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
585         IF_FAIL_RETURN_TAG(key && val.__jsonNode, false, _E, "Invalid parameter");
586
587         JsonArray *arr = __get_array(__jsonNode, path, key, true);
588         IF_FAIL_RETURN(arr, false);
589
590         json_array_add_element(arr, val.__jsonNode);
591         val.__jsonNode = NULL;
592         val = Json();
593
594         return true;
595 }
596
597 SO_EXPORT bool Json::append(const char *path, const char *key, int val)
598 {
599         return append(path, key, static_cast<int64_t>(val));
600 }
601
602 SO_EXPORT bool Json::append(const char *path, const char *key, int64_t val)
603 {
604         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
605         IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
606
607         JsonArray *arr = __get_array(__jsonNode, path, key, true);
608         IF_FAIL_RETURN(arr, false);
609
610         json_array_add_int_element(arr, val);
611         return true;
612 }
613
614 SO_EXPORT bool Json::append(const char *path, const char *key, double val)
615 {
616         return append(path, key, __double_to_string(val));
617 }
618
619 SO_EXPORT bool Json::append(const char *path, const char *key, std::string val)
620 {
621         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
622         IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
623
624         JsonArray *arr = __get_array(__jsonNode, path, key, true);
625         IF_FAIL_RETURN(arr, false);
626
627         json_array_add_string_element(arr, val.c_str());
628         return true;
629 }
630
631 static JsonNode* __get_array_elem(JsonNode *jnode, const char *path, const char *key, int index)
632 {
633         JsonArray *jarr = __get_array(jnode, path, key, false);
634         IF_FAIL_RETURN_TAG(jarr, NULL, _W, "Mismatched data type");
635
636         int size = json_array_get_length(jarr);
637         IF_FAIL_RETURN(size > index, NULL);
638
639         JsonNode *node = json_array_get_element(jarr, index);
640         IF_FAIL_RETURN_TAG(node, NULL, _E, "Failed to get an array element");
641
642         return node;
643 }
644
645 SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, Json &val)
646 {
647         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
648         IF_FAIL_RETURN_TAG(val.__jsonNode && key && index >= 0, false, _E, "Invalid parameter");
649
650         JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
651         IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
652
653         JsonObject *obj = json_node_get_object(val.__jsonNode);
654         IF_FAIL_RETURN_TAG(obj, false, _E, "Getting object failed");
655
656         json_node_set_object(node, obj);
657         json_node_free(val.__jsonNode);
658         val.__jsonNode = NULL;
659         val = Json();
660
661         return true;
662 }
663
664 SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, int val)
665 {
666         return setAt(path, key, index, static_cast<int64_t>(val));
667 }
668
669 SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, int64_t val)
670 {
671         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
672         IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
673
674         JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
675         IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
676         IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
677
678         json_node_set_int(node, val);
679         return true;
680 }
681
682 SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, double val)
683 {
684         return setAt(path, key, index, __double_to_string(val));
685 }
686
687 SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, std::string val)
688 {
689         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
690         IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
691
692         JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
693         IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
694         IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
695
696         json_node_set_string(node, val.c_str());
697         return true;
698 }
699
700 SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, Json *val)
701 {
702         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
703         IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
704
705         JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
706         IF_FAIL_RETURN(node, false);
707
708         JsonNode *nodeCopy = json_node_copy(node);
709         IF_FAIL_RETURN_TAG(nodeCopy, false, _E, "Memory allocation failed");
710
711         if (val->__jsonNode) {
712                 json_node_free(val->__jsonNode);
713         }
714         val->__jsonNode = nodeCopy;
715
716         return true;
717 }
718
719 SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, int *val)
720 {
721         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
722         IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
723
724         int64_t v;
725         if (getAt(path, key, index, &v)) {
726                 *val = v;
727                 return true;
728         }
729
730         return false;
731 }
732
733 SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, int64_t *val)
734 {
735         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
736         IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
737
738         JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
739         IF_FAIL_RETURN(node, false);
740
741         JsonNodeType ntype = json_node_get_node_type(node);
742         IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
743
744         GType vtype = json_node_get_value_type(node);
745         if (vtype == G_TYPE_INT64) {
746                 *val = json_node_get_int(node);
747         } else if (vtype == G_TYPE_STRING) {
748                 *val = static_cast<int64_t>(__string_to_double(json_node_get_string(node)));
749         } else {
750                 _E("Type mismatched: %s", key);
751                 return false;
752         }
753
754         return true;
755 }
756
757 SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, double *val)
758 {
759         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
760         IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
761
762         JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
763         IF_FAIL_RETURN(node, false);
764
765         JsonNodeType ntype = json_node_get_node_type(node);
766         IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
767
768         GType vtype = json_node_get_value_type(node);
769         if (vtype == G_TYPE_DOUBLE) {
770                 *val = json_node_get_double(node);
771         } else if (vtype == G_TYPE_INT64) {
772                 *val = json_node_get_int(node);
773         } else if (vtype == G_TYPE_STRING) {
774                 *val = __string_to_double(json_node_get_string(node));
775         } else {
776                 _E("Type mismatched: %s", key);
777                 return false;
778         }
779
780         return true;
781 }
782
783 SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, std::string *val)
784 {
785         IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
786         IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
787
788         JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
789         IF_FAIL_RETURN(node, false);
790
791         JsonNodeType ntype = json_node_get_node_type(node);
792         IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
793
794         GType vtype = json_node_get_value_type(node);
795         IF_FAIL_RETURN_TAG(vtype == G_TYPE_STRING, false, _E, "Type mismatched: %s", key);
796
797         const char *str_val = json_node_get_string(node);
798         IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
799
800         *val = str_val;
801         return true;
802 }
803
804 bool Json::__getMembers(json_node_t *node, std::list<std::string> &list)
805 {
806         IF_FAIL_RETURN(node, false);
807         list.clear();
808
809         JsonObject *jobj = json_node_get_object(node);
810         IF_FAIL_RETURN_TAG(jobj, false, _E, "Getting Json object failed");
811
812         GList *members = json_object_get_members(jobj);
813         IF_FAIL_RETURN(members, true);
814
815         for (GList *it = g_list_first(members); it; it = g_list_next(it)) {
816                 const char *key = static_cast<const char*>(it->data);
817                 if (!key) {
818                         list.clear();
819                         g_list_free(members);
820                         _E("Member list extraction failed");
821                         return false;
822                 }
823
824                 list.push_back(key);
825         }
826
827         g_list_free(members);
828         return true;
829 }
830
831 SO_EXPORT bool Json::getKeys(std::list<std::string>* list)
832 {
833         IF_FAIL_RETURN_TAG(list, false, _E, "Invalid parameter");
834         return __getMembers(__jsonNode, *list);
835 }
836
837 bool Json::__nodeEq(json_node_t *lhs, json_node_t *rhs)
838 {
839         IF_FAIL_RETURN(lhs && rhs, false);
840
841         JsonNodeType ltype = json_node_get_node_type(lhs);
842         JsonNodeType rtype = json_node_get_node_type(rhs);
843         IF_FAIL_RETURN(ltype == rtype, false);
844
845         switch (ltype) {
846         case JSON_NODE_VALUE:
847                 IF_FAIL_RETURN(__valueEq(lhs, rhs), false);
848                 break;
849         case JSON_NODE_OBJECT:
850                 IF_FAIL_RETURN(__objectEq(lhs, rhs), false);
851                 break;
852         case JSON_NODE_ARRAY:
853                 IF_FAIL_RETURN(__arrayEq(lhs, rhs), false);
854                 break;
855         default:
856                 _W("Unsupported type");
857                 return false;
858         }
859
860         return true;
861 }
862
863 bool Json::__valueEq(json_node_t *lhs, json_node_t *rhs)
864 {
865         GType ltype = json_node_get_value_type(lhs);
866         GType rtype = json_node_get_value_type(rhs);
867         IF_FAIL_RETURN(ltype == rtype, false);
868
869         switch (ltype) {
870         case G_TYPE_INT64:
871                 return json_node_get_int(lhs) == json_node_get_int(rhs);
872         case G_TYPE_DOUBLE:
873                 return json_node_get_double(lhs) == json_node_get_double(rhs);
874         case G_TYPE_STRING:
875                 return STR_EQ(json_node_get_string(lhs), json_node_get_string(rhs));
876         default:
877                 _W("Unsupported type");
878                 return false;
879         }
880 }
881
882 bool Json::__objectEq(json_node_t *lhs, json_node_t *rhs)
883 {
884         std::list<std::string> lm, rm;
885         IF_FAIL_RETURN(__getMembers(lhs, lm), false);
886         IF_FAIL_RETURN(__getMembers(rhs, rm), false);
887         IF_FAIL_RETURN(lm.size() == rm.size(), false);
888
889         lm.sort();
890         rm.sort();
891
892         std::list<std::string>::iterator lit, rit;
893         lit = lm.begin();
894         rit = rm.begin();
895
896         while (lit != lm.end()) {
897                 IF_FAIL_RETURN(*lit == *rit, false);
898
899                 json_node_t *lhsChild = json_object_get_member(json_node_get_object(lhs), (*lit).c_str());
900                 json_node_t *rhsChild = json_object_get_member(json_node_get_object(rhs), (*rit).c_str());
901                 IF_FAIL_RETURN(__nodeEq(lhsChild, rhsChild), false);
902
903                 ++lit;
904                 ++rit;
905         }
906
907         return true;
908 }
909
910 bool Json::__arrayEq(json_node_t *lhs, json_node_t *rhs)
911 {
912         JsonArray *larr = json_node_get_array(lhs);
913         JsonArray *rarr = json_node_get_array(rhs);
914
915         int size = json_array_get_length(larr);
916         IF_FAIL_RETURN(size == static_cast<int>(json_array_get_length(rarr)), false);
917
918         for (int i = 0; i < size; ++i) {
919                 json_node_t *lhsChild = json_array_get_element(larr, i);
920                 json_node_t *rhsChild = json_array_get_element(rarr, i);
921                 IF_FAIL_RETURN(__nodeEq(lhsChild, rhsChild), false);
922         }
923
924         return true;
925 }