2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <json-glib/json-glib.h>
24 #define PATH_DELIM '.'
25 #define GVAR_VALUES "values"
26 #define GVAR_TYPES "types"
28 static double string_to_double(const char* in)
30 IF_FAIL_RETURN_TAG(in, 0, _E, "Parameter NULL");
32 // Locale-independent string-to-double conversion
34 std::istringstream istr(in);
35 istr.imbue(std::locale("C"));
40 static std::string double_to_string(double in, int prec)
42 // Locale-independent double-to-string conversion
43 std::ostringstream ostr;
44 ostr.imbue(std::locale("C"));
45 ostr << std::setprecision(prec) << std::fixed << in;
51 JsonObject *obj = json_object_new();
52 IF_FAIL_VOID_TAG(obj, _E, "Json object construction failed");
54 json_node = json_node_new(JSON_NODE_OBJECT);
56 json_object_unref(obj);
57 _E("Json object construction failed");
60 json_node_set_object(json_node, obj);
61 json_object_unref(obj);
64 ctx::json::json(const json& j)
66 json_node = json_node_copy(j.json_node);
67 IF_FAIL_VOID_TAG(json_node, _E, "Json object construction failed");
70 ctx::json::json(const char* s)
75 parse(EMPTY_JSON_OBJECT);
79 ctx::json::json(const std::string& s)
82 parse(EMPTY_JSON_OBJECT);
93 void ctx::json::parse(const char* s)
96 JsonParser *parser = NULL;
97 JsonNode *root = NULL;
99 parser = json_parser_new();
100 IF_FAIL_VOID_TAG(parser, _E, "Memory allocation failed");
102 result = json_parser_load_from_data(parser, s, -1, NULL);
103 IF_FAIL_CATCH_TAG(result, _E, "Parsing failed");
105 root = json_parser_get_root(parser);
106 IF_FAIL_CATCH_TAG(root, _E, "Getting root failed");
108 json_node = json_node_copy(root);
109 IF_FAIL_CATCH_TAG(json_node, _E, "Copying failed");
113 g_object_unref(parser);
116 void ctx::json::release()
119 json_node_free(json_node);
124 ctx::json& ctx::json::operator=(const json& j)
127 json_node = json_node_copy(j.json_node);
129 _E("Json object copy failed");
134 ctx::json& ctx::json::operator=(const char* s)
140 parse(EMPTY_JSON_OBJECT);
145 ctx::json& ctx::json::operator=(const std::string& s)
149 parse(EMPTY_JSON_OBJECT);
156 bool ctx::json::operator==(const json& rhs)
158 return node_equals(json_node, rhs.json_node);
161 bool ctx::json::operator!=(const json& rhs)
163 return !operator==(rhs);
167 bool ctx::json::contains(const json& subset) const
173 char* ctx::json::dup_cstr()
175 IF_FAIL_RETURN_TAG(json_node, NULL, _E, "Json object not initialized");
177 JsonGenerator *jgen = NULL;
180 jgen = json_generator_new();
183 json_generator_set_root(jgen, json_node);
184 output = json_generator_to_data(jgen, NULL);
185 IF_FAIL_CATCH(output);
187 g_object_unref(jgen);
192 g_object_unref(jgen);
195 _E("Memory allocation failed");
199 std::string ctx::json::str()
202 char *_s = dup_cstr();
203 IF_FAIL_RETURN(_s, output = EMPTY_JSON_OBJECT);
211 static char** tokenize_path(const char* path, int* length)
213 //TODO: Re-implement this tokenizer using C++ stuff
221 if (path == NULL || strlen(path) == 0) {
228 for (pch = path; *pch != '\0'; pch++) {
229 if (*pch == PATH_DELIM) {
230 *length = *length + 1;
234 tokens = static_cast<char**>(g_malloc((*length) * sizeof(char*)));
235 IF_FAIL_RETURN_TAG(tokens, NULL, _E, "Memory allocation failed");
240 for (pch = path; ; pch++) {
241 if (*pch == PATH_DELIM || *pch == '\0') {
243 tokens[i] = static_cast<char*>(g_malloc((len+1) * sizeof(char)));
244 IF_FAIL_CATCH_TAG(tokens[i], _E, "Memory allocation failed");
245 strncpy(tokens[i], begin, len);
246 tokens[i][len] = '\0';
259 for (j=0; j<i; j++) {
266 static void free_tokenized_path(int length, char** tokens)
270 for (i=0; i<length; i++) {
277 static JsonObject* traverse(JsonNode* jnode, const char* path, bool force)
279 IF_FAIL_RETURN_TAG(jnode, NULL, _E, "Invalid parameter");
283 char **path_token = NULL;
284 JsonObject *jobj = NULL;
285 JsonObject *child_obj = NULL;
286 JsonNode *child_node = NULL;
288 jobj = json_node_get_object(jnode);
289 IF_FAIL_RETURN(jobj, NULL);
292 path_token = tokenize_path(path, &length);
293 IF_FAIL_RETURN_TAG(path_token, NULL, _E, "Invalid path");
296 for (depth=0; depth<length; depth++) {
297 if (!json_object_has_member(jobj, path_token[depth])) {
299 child_obj = json_object_new();
300 IF_FAIL_CATCH_TAG(child_obj, _E, "Memory allocation failed");
301 json_object_set_object_member(jobj, path_token[depth], child_obj);
306 child_node = json_object_get_member(jobj, path_token[depth]);
307 IF_FAIL_CATCH(child_node && json_node_get_node_type(child_node) == JSON_NODE_OBJECT);
309 jobj = json_node_get_object(child_node);
313 free_tokenized_path(length, path_token);
317 free_tokenized_path(length, path_token);
321 bool ctx::json::set(const char* path, const char* key, json& val)
323 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
324 IF_FAIL_RETURN_TAG(key && val.json_node, false, _E, "Invalid parameter");
326 JsonObject *jobj = traverse(json_node, path, true);
327 IF_FAIL_RETURN(jobj, false);
329 if (json_object_has_member(jobj, key))
330 json_object_remove_member(jobj, key);
332 json_object_set_member(jobj, key, val.json_node);
333 val.json_node = NULL;
339 bool ctx::json::set(const char* path, const char* key, int val)
341 return set(path, key, static_cast<int64_t>(val));
344 bool ctx::json::set(const char* path, const char* key, int64_t val)
346 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
347 IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
349 JsonObject *jobj = traverse(json_node, path, true);
350 IF_FAIL_RETURN(jobj, false);
352 if (json_object_has_member(jobj, key))
353 json_object_remove_member(jobj, key);
355 json_object_set_int_member(jobj, key, val);
359 bool ctx::json::set(const char* path, const char* key, double val, int prec)
361 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
362 IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
364 JsonObject *jobj = traverse(json_node, path, true);
365 IF_FAIL_RETURN(jobj, false);
367 if (json_object_has_member(jobj, key)) {
368 json_object_remove_member(jobj, key);
371 //NOTE: json-glib causes a precision issue while handling double values
372 json_object_set_string_member(jobj, key, double_to_string(val, prec).c_str());
376 bool ctx::json::set(const char* path, const char* key, std::string val)
378 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
379 IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
381 JsonObject *jobj = traverse(json_node, path, true);
382 IF_FAIL_RETURN(jobj, false);
384 if (json_object_has_member(jobj, key)) {
385 json_object_remove_member(jobj, key);
388 json_object_set_string_member(jobj, key, val.c_str());
392 bool ctx::json::set(const char* path, const char* key, GVariant *val)
394 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
395 IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
397 const gchar *type_str = g_variant_get_type_string(val);
398 IF_FAIL_RETURN_TAG(type_str, false, _E, "GVariant manipulation failed");
400 json_node_t *node = json_gvariant_serialize(val);
401 IF_FAIL_RETURN_TAG(node, false, _E, "GVariant manipulation failed");
404 gvar_json.set(NULL, GVAR_TYPES, type_str);
405 json_object_set_member(json_node_get_object(gvar_json.json_node), GVAR_VALUES, node);
407 return set(path, key, gvar_json);
410 bool ctx::json::get(const char* path, const char* key, json* val)
412 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
413 IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
415 JsonObject *jobj = NULL;
416 JsonNode *node = NULL;
418 jobj = traverse(json_node, path, false);
419 IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), false);
421 node = json_object_dup_member(jobj, key);
422 IF_FAIL_RETURN_TAG(node, false, _E, "Memory allocation failed");
424 if (val->json_node) {
425 json_node_free(val->json_node);
427 val->json_node = node;
432 static JsonNode* search_value_node(JsonNode* jnode, const char* path, const char* key)
434 JsonNode *node = NULL;
435 JsonObject *jobj = NULL;
438 jobj = traverse(jnode, path, false);
439 IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), NULL);
441 node = json_object_get_member(jobj, key);
442 ntype = json_node_get_node_type(node);
443 IF_FAIL_RETURN(ntype == JSON_NODE_VALUE, NULL);
448 bool ctx::json::get(const char* path, const char* key, int* val)
450 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
451 IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
455 if (get(path, key, &v)) {
463 bool ctx::json::get(const char* path, const char* key, int64_t* val)
465 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
466 IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
468 JsonNode *node = search_value_node(json_node, path, key);
469 IF_FAIL_RETURN(node, false);
471 GType vtype = json_node_get_value_type(node);
472 if (vtype == G_TYPE_INT64) {
473 *val = json_node_get_int(node);
474 } else if (vtype == G_TYPE_STRING) {
475 //TODO: if the string is not a number?
476 *val = static_cast<int64_t>(string_to_double(json_node_get_string(node)));
484 bool ctx::json::get(const char* path, const char* key, double* val)
486 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
487 IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
489 JsonNode *node = search_value_node(json_node, path, key);
490 IF_FAIL_RETURN(node, false);
492 GType vtype = json_node_get_value_type(node);
493 if (vtype == G_TYPE_DOUBLE) {
494 *val = json_node_get_double(node);
495 } else if (vtype == G_TYPE_INT64) {
496 *val = json_node_get_int(node);
497 } else if (vtype == G_TYPE_STRING) {
498 //NOTE: json-glib causes a precision issue while handling double values
499 *val = string_to_double(json_node_get_string(node));
507 bool ctx::json::get(const char* path, const char* key, std::string* val)
509 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
510 IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
512 JsonNode *node = search_value_node(json_node, path, key);
513 IF_FAIL_RETURN(node, false);
515 GType vtype = json_node_get_value_type(node);
516 IF_FAIL_RETURN(vtype == G_TYPE_STRING, false);
518 const char *str_val = json_node_get_string(node);
519 IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
525 bool ctx::json::get(const char* path, const char* key, GVariant **val)
527 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
528 IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
532 ret = get(path, key, &gvar_json);
533 IF_FAIL_RETURN(ret, false);
535 std::string gvar_types;
536 ret = gvar_json.get(NULL, GVAR_TYPES, &gvar_types);
537 IF_FAIL_RETURN(ret, false);
540 ret = gvar_json.get(NULL, GVAR_VALUES, &gvar_values);
541 IF_FAIL_RETURN(ret, false);
544 *val = json_gvariant_deserialize(gvar_values.json_node, gvar_types.c_str(), &gerr);
546 IF_FAIL_RETURN(*val, false);
551 static JsonArray* search_array(JsonNode* jnode, const char* path, const char* key, bool force)
553 JsonNode *node = NULL;
554 JsonArray *arr = NULL;
555 JsonObject *jobj = NULL;
557 jobj = traverse(jnode, path, force);
558 IF_FAIL_RETURN(jobj, NULL);
560 if (!json_object_has_member(jobj, key)) {
562 arr = json_array_new();
563 IF_FAIL_RETURN_TAG(arr, NULL, _E, "Memory allocation failed");
564 json_object_set_array_member(jobj, key, arr);
569 node = json_object_get_member(jobj, key);
570 IF_FAIL_RETURN_TAG(node && json_node_get_node_type(node) == JSON_NODE_ARRAY,
571 NULL, _W, "Type mismatched: %s", key);
573 return json_node_get_array(node);
576 int ctx::json::array_get_size(const char* path, const char* key)
578 IF_FAIL_RETURN_TAG(this->json_node, -1, _E, "Json object not initialized");
579 IF_FAIL_RETURN_TAG(key, -1, _E, "Invalid parameter");
581 JsonArray *jarr = search_array(json_node, path, key, false);
582 IF_FAIL_RETURN_TAG(jarr, -1, _D, "Mismatched data type");
584 return json_array_get_length(jarr);
587 bool ctx::json::array_append(const char* path, const char* key, json& val)
589 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
590 IF_FAIL_RETURN_TAG(key && val.json_node, false, _E, "Invalid parameter");
592 JsonArray *arr = search_array(json_node, path, key, true);
593 IF_FAIL_RETURN(arr, false);
595 json_array_add_element(arr, val.json_node);
596 val.json_node = NULL;
602 bool ctx::json::array_append(const char* path, const char* key, int val)
604 return array_append(path, key, static_cast<int64_t>(val));
607 bool ctx::json::array_append(const char* path, const char* key, int64_t val)
609 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
610 IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
612 JsonArray *arr = search_array(json_node, path, key, true);
613 IF_FAIL_RETURN(arr, false);
615 json_array_add_int_element(arr, val);
619 bool ctx::json::array_append(const char* path, const char* key, double val, int prec)
621 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
622 IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
624 JsonArray *arr = search_array(json_node, path, key, true);
625 IF_FAIL_RETURN(arr, false);
627 //NOTE: json-glib causes a precision issue while handling double values
628 json_array_add_string_element(arr, double_to_string(val, prec).c_str());
632 bool ctx::json::array_append(const char* path, const char* key, std::string val)
634 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
635 IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
637 JsonArray *arr = search_array(json_node, path, key, true);
638 IF_FAIL_RETURN(arr, false);
640 json_array_add_string_element(arr, val.c_str());
644 static JsonNode* search_array_elem(JsonNode* jnode, const char* path, const char* key, int index)
646 JsonArray *jarr = search_array(jnode, path, key, false);
647 IF_FAIL_RETURN_TAG(jarr, NULL, _W, "Mismatched data type");
649 int size = json_array_get_length(jarr);
650 IF_FAIL_RETURN(size > index, NULL);
652 JsonNode *node = json_array_get_element(jarr, index);
653 IF_FAIL_RETURN_TAG(node, NULL, _E, "Failed to get an array element");
658 bool ctx::json::array_set_at(const char* path, const char* key, int index, json& val)
660 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
661 IF_FAIL_RETURN_TAG(val.json_node && key && index >= 0, false, _E, "Invalid parameter");
663 JsonNode *node = search_array_elem(json_node, path, key, index);
664 IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
665 IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_OBJECT, false, _E, "Type mismatched: %s[%d]", key, index);
667 JsonObject *obj = json_node_get_object(val.json_node);
668 IF_FAIL_RETURN_TAG(obj, false, _E, "Getting object failed");
670 json_node_set_object(node, obj);
671 json_node_free(val.json_node);
672 val.json_node = NULL;
678 bool ctx::json::array_set_at(const char* path, const char* key, int index, int val)
680 return array_set_at(path, key, index, static_cast<int64_t>(val));
683 bool ctx::json::array_set_at(const char* path, const char* key, int index, int64_t val)
685 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
686 IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
688 JsonNode *node = search_array_elem(json_node, path, key, index);
689 IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
690 IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
691 IF_FAIL_RETURN_TAG(json_node_get_value_type(node) == G_TYPE_INT64, false, _E, "Type mismatched: %s[%d]", key, index);
693 json_node_set_int(node, val);
697 bool ctx::json::array_set_at(const char* path, const char* key, int index, double val, int prec)
699 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
700 IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
702 JsonNode *node = search_array_elem(json_node, path, key, index);
703 IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
704 IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
705 IF_FAIL_RETURN_TAG(json_node_get_value_type(node) == G_TYPE_STRING, false, _E, "Type mismatched: %s[%d]", key, index);
707 json_node_set_string(node, double_to_string(val, prec).c_str());
711 bool ctx::json::array_set_at(const char* path, const char* key, int index, std::string val)
713 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
714 IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
716 JsonNode *node = search_array_elem(json_node, path, key, index);
717 IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
718 IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
719 IF_FAIL_RETURN_TAG(json_node_get_value_type(node) == G_TYPE_STRING, false, _E, "Type mismatched: %s[%d]", key, index);
721 json_node_set_string(node, val.c_str());
725 bool ctx::json::get_array_elem(const char* path, const char* key, int index, json* val)
727 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
728 IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
730 JsonNode *node = search_array_elem(json_node, path, key, index);
731 IF_FAIL_RETURN(node, false);
733 JsonNode *node_copy = json_node_copy(node);
734 IF_FAIL_RETURN_TAG(node_copy, false, _E, "Memory allocation failed");
736 if (val->json_node) {
737 json_node_free(val->json_node);
739 val->json_node = node_copy;
744 bool ctx::json::get_array_elem(const char* path, const char* key, int index, int* val)
746 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
747 IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
750 if (get_array_elem(path, key, index, &v)) {
758 bool ctx::json::get_array_elem(const char* path, const char* key, int index, int64_t* val)
760 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
761 IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
763 JsonNode *node = search_array_elem(json_node, path, key, index);
764 IF_FAIL_RETURN(node, false);
766 JsonNodeType ntype = json_node_get_node_type(node);
767 IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
769 GType vtype = json_node_get_value_type(node);
770 if (vtype == G_TYPE_INT64) {
771 *val = json_node_get_int(node);
772 } else if (vtype == G_TYPE_STRING) {
773 *val = static_cast<int64_t>(string_to_double(json_node_get_string(node)));
775 _E("Type mismatched: %s", key);
782 bool ctx::json::get_array_elem(const char* path, const char* key, int index, double* val)
784 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
785 IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
787 JsonNode *node = search_array_elem(json_node, path, key, index);
788 IF_FAIL_RETURN(node, false);
790 JsonNodeType ntype = json_node_get_node_type(node);
791 IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
793 GType vtype = json_node_get_value_type(node);
794 if (vtype == G_TYPE_DOUBLE) {
795 *val = json_node_get_double(node);
796 } else if (vtype == G_TYPE_INT64) {
797 *val = json_node_get_int(node);
798 } else if (vtype == G_TYPE_STRING) {
799 //NOTE: json-glib causes a precision issue while handling double values
800 *val = string_to_double(json_node_get_string(node));
802 _E("Type mismatched: %s", key);
809 bool ctx::json::get_array_elem(const char* path, const char* key, int index, std::string* val)
811 IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
812 IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
814 JsonNode *node = search_array_elem(json_node, path, key, index);
815 IF_FAIL_RETURN(node, false);
817 JsonNodeType ntype = json_node_get_node_type(node);
818 IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
820 GType vtype = json_node_get_value_type(node);
821 IF_FAIL_RETURN_TAG(vtype == G_TYPE_STRING, false, _E, "Type mismatched: %s", key);
823 const char *str_val = json_node_get_string(node);
824 IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
830 bool ctx::json::get_member_list(json_node_t* node, std::list<std::string>& list)
832 IF_FAIL_RETURN(node, false);
835 JsonObject *jobj = json_node_get_object(node);
836 IF_FAIL_RETURN_TAG(jobj, false, _E, "Getting json object failed");
838 GList *members = json_object_get_members(jobj);
839 IF_FAIL_RETURN(members, true);
841 for (GList *it = g_list_first(members); it; it = g_list_next(it)) {
842 const char *key = static_cast<const char*>(it->data);
845 g_list_free(members);
846 _E("Member list extraction failed");
853 g_list_free(members);
857 bool ctx::json::get_keys(std::list<std::string>* list)
859 IF_FAIL_RETURN_TAG(list, false, _E, "Invalid parameter");
860 return get_member_list(json_node, *list);
863 bool ctx::json::node_equals(json_node_t* lhs, json_node_t* rhs)
865 IF_FAIL_RETURN(lhs && rhs, false);
867 JsonNodeType ltype = json_node_get_node_type(lhs);
868 JsonNodeType rtype = json_node_get_node_type(rhs);
869 IF_FAIL_RETURN(ltype == rtype, false);
872 case JSON_NODE_VALUE:
873 IF_FAIL_RETURN(value_equals(lhs, rhs), false);
875 case JSON_NODE_OBJECT:
876 IF_FAIL_RETURN(object_equals(lhs, rhs), false);
878 case JSON_NODE_ARRAY:
879 IF_FAIL_RETURN(array_equals(lhs, rhs), false);
882 _W("Unsupported type");
889 bool ctx::json::value_equals(json_node_t* lhs, json_node_t* rhs)
891 GType ltype = json_node_get_value_type(lhs);
892 GType rtype = json_node_get_value_type(rhs);
893 IF_FAIL_RETURN(ltype == rtype, false);
897 return json_node_get_int(lhs) == json_node_get_int(rhs);
899 return json_node_get_double(lhs) == json_node_get_double(rhs);
901 return STR_EQ(json_node_get_string(lhs), json_node_get_string(rhs));
903 _W("Unsupported type");
908 bool ctx::json::object_equals(json_node_t* lhs, json_node_t* rhs)
910 std::list<std::string> lm, rm;
911 IF_FAIL_RETURN(get_member_list(lhs, lm), false);
912 IF_FAIL_RETURN(get_member_list(rhs, rm), false);
913 IF_FAIL_RETURN(lm.size() == rm.size(), false);
918 std::list<std::string>::iterator lit, rit;
922 while (lit != lm.end()) {
923 IF_FAIL_RETURN(*lit == *rit, false);
925 json_node_t *lhs_child = json_object_get_member(json_node_get_object(lhs), (*lit).c_str());
926 json_node_t *rhs_child = json_object_get_member(json_node_get_object(rhs), (*rit).c_str());
927 IF_FAIL_RETURN(node_equals(lhs_child, rhs_child), false);
936 bool ctx::json::array_equals(json_node_t* lhs, json_node_t* rhs)
938 JsonArray *larr = json_node_get_array(lhs);
939 JsonArray *rarr = json_node_get_array(rhs);
941 int size = json_array_get_length(larr);
942 IF_FAIL_RETURN(size == static_cast<int>(json_array_get_length(rarr)), false);
944 for (int i=0; i<size; ++i) {
945 json_node_t *lhs_child = json_array_get_element(larr, i);
946 json_node_t *rhs_child = json_array_get_element(rarr, i);
947 IF_FAIL_RETURN(node_equals(lhs_child, rhs_child), false);