Check return value
[platform/core/base/bundle.git] / src / bundle_json.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
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 <stdlib.h>
18 #include <string.h>
19 #include <glib.h>
20 #include <json-glib/json-glib.h>
21
22 #include "bundle.h"
23 #include "bundle_internal.h"
24
25 static void __add_json_data_from_bundle(const char *key,
26                 const int type,
27                 const bundle_keyval_t *kv,
28                 void *user_data)
29 {
30         void *basic_val = NULL;
31         size_t basic_size = 0;
32         void **array_val = NULL;
33         unsigned int array_len = 0;
34         size_t *array_elem_size = 0;
35         JsonObject *json_obj = (JsonObject *)user_data;
36         JsonArray *json_arr;
37         unsigned int i;
38         int ret;
39
40         if (json_obj == NULL)
41                 return;
42
43         if (bundle_keyval_type_is_array((bundle_keyval_t *)kv)) {
44                 ret = bundle_keyval_get_array_val((bundle_keyval_t *)kv,
45                                 &array_val, &array_len, &array_elem_size);
46                 if (ret != BUNDLE_ERROR_NONE)
47                         return;
48
49                 json_arr = json_array_new();
50                 if (json_arr == NULL)
51                         return;
52
53                 for (i = 0; i < array_len; i++)
54                         json_array_add_string_element(json_arr, array_val[i]);
55
56                 json_object_set_array_member(json_obj, key, json_arr);
57         } else {
58                 ret = bundle_keyval_get_basic_val((bundle_keyval_t *)kv,
59                                 &basic_val, &basic_size);
60                 if (ret != BUNDLE_ERROR_NONE)
61                         return;
62
63                 json_object_set_string_member(json_obj, key, basic_val);
64         }
65 }
66
67 int bundle_to_json(bundle *b, char **json)
68 {
69         JsonObject *object;
70         JsonNode *node;
71         JsonGenerator *generator = NULL;
72         gchar *new_json = NULL;
73         gsize length;
74         int ret = BUNDLE_ERROR_NONE;
75
76         if (b == NULL || json == NULL)
77                 return BUNDLE_ERROR_INVALID_PARAMETER;
78
79         object = json_object_new();
80         if (object == NULL)
81                 return BUNDLE_ERROR_OUT_OF_MEMORY;
82
83         bundle_foreach(b, __add_json_data_from_bundle, object);
84
85         node = json_node_new(JSON_NODE_OBJECT);
86         if (node == NULL) {
87                 ret = BUNDLE_ERROR_OUT_OF_MEMORY;
88                 goto exception;
89         }
90
91         json_node_set_object(node, object);
92
93         generator = json_generator_new();
94         if (generator == NULL) {
95                 ret = BUNDLE_ERROR_OUT_OF_MEMORY;
96                 goto exception;
97         }
98
99         json_generator_set_root(generator, node);
100
101         new_json = json_generator_to_data(generator, &length);
102         if (new_json == NULL) {
103                 ret = BUNDLE_ERROR_OUT_OF_MEMORY;
104                 goto exception;
105         }
106
107         *json = (char *)new_json;
108
109 exception:
110         if (generator)
111                 g_object_unref(generator);
112         if (node)
113                 json_node_free(node);
114         if (object)
115                 json_object_unref(object);
116
117         return ret;
118 }
119
120 static void __add_bundle_data_from_json(JsonObject *object,
121                 const char *key,
122                 JsonNode *node,
123                 gpointer user_data)
124 {
125         bundle *b = (bundle *)user_data;
126         JsonNodeType node_type;
127         JsonArray *json_arr;
128         const gchar *val;
129         guint len;
130         guint i;
131         char **arr_val;
132
133         if (key == NULL || node == NULL)
134                 return;
135
136         node_type = JSON_NODE_TYPE(node);
137         if (node_type == JSON_NODE_ARRAY) {
138                 json_arr = json_node_get_array(node);
139                 if (json_arr == NULL)
140                         return;
141
142                 len = json_array_get_length(json_arr);
143
144                 arr_val = (char **)calloc(1, sizeof(char *) * len);
145                 if (arr_val == NULL)
146                         return;
147
148                 for (i = 0; i < len; i++)
149                         arr_val[i] = strdup(json_array_get_string_element
150                                         (json_arr, i));
151
152                 bundle_add_str_array(b, key, (const char **)arr_val, len);
153
154                 for (i = 0; i < len; i++)
155                         free(arr_val[i]);
156                 free(arr_val);
157         } else if (node_type == JSON_NODE_VALUE) {
158                 val = json_node_get_string(node);
159                 if (val)
160                         bundle_add_str(b, key, (const char *)val);
161         }
162 }
163
164 int bundle_from_json(const char *json, bundle **b)
165 {
166         GError *error = NULL;
167         JsonParser *parser;
168         JsonNode *root;
169         JsonObject *root_obj;
170         bundle *new_b;
171         int ret = BUNDLE_ERROR_NONE;
172
173         if (json == NULL || b == NULL)
174                 return BUNDLE_ERROR_INVALID_PARAMETER;
175
176         parser = json_parser_new();
177         if (parser == NULL)
178                 return BUNDLE_ERROR_OUT_OF_MEMORY;
179
180         json_parser_load_from_data(parser, json, strlen(json), &error);
181         if (error) {
182                 ret = BUNDLE_ERROR_INVALID_PARAMETER;
183                 goto exception;
184         }
185
186         root = json_parser_get_root(parser);
187         if (root == NULL) {
188                 ret = BUNDLE_ERROR_INVALID_PARAMETER;
189                 goto exception;
190         }
191
192         root_obj = json_node_get_object(root);
193         if (root_obj == NULL) {
194                 ret = BUNDLE_ERROR_INVALID_PARAMETER;
195                 goto exception;
196         }
197
198         new_b = bundle_create();
199         if (new_b == NULL) {
200                 ret = BUNDLE_ERROR_OUT_OF_MEMORY;
201                 goto exception;
202         }
203
204         json_object_foreach_member(root_obj,
205                         __add_bundle_data_from_json, new_b);
206
207         *b = new_b;
208
209 exception:
210         if (error)
211                 g_error_free(error);
212         if (parser)
213                 g_object_unref(parser);
214
215         return ret;
216 }