3f11e3b93160749bf4cdf29c6626123220ebe3a2
[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                 len = json_array_get_length(json_arr);
140
141                 arr_val = (char **)calloc(1, sizeof(char *) * len);
142                 if (arr_val == NULL)
143                         return;
144
145                 for (i = 0; i < len; i++)
146                         arr_val[i] = strdup(json_array_get_string_element
147                                         (json_arr, i));
148
149                 bundle_add_str_array(b, key, (const char **)arr_val, len);
150
151                 for (i = 0; i < len; i++)
152                         free(arr_val[i]);
153                 free(arr_val);
154         } else if (node_type == JSON_NODE_VALUE) {
155                 val = json_node_get_string(node);
156                 if (val)
157                         bundle_add_str(b, key, (const char *)val);
158         }
159 }
160
161 int bundle_from_json(const char *json, bundle **b)
162 {
163         GError *error = NULL;
164         JsonParser *parser;
165         JsonNode *root;
166         JsonObject *root_obj;
167         bundle *new_b;
168         int ret = BUNDLE_ERROR_NONE;
169
170         if (json == NULL || b == NULL)
171                 return BUNDLE_ERROR_INVALID_PARAMETER;
172
173         parser = json_parser_new();
174         if (parser == NULL)
175                 return BUNDLE_ERROR_OUT_OF_MEMORY;
176
177         json_parser_load_from_data(parser, json, strlen(json), &error);
178         if (error) {
179                 ret = BUNDLE_ERROR_INVALID_PARAMETER;
180                 goto exception;
181         }
182
183         root = json_parser_get_root(parser);
184         if (root == NULL) {
185                 ret = BUNDLE_ERROR_INVALID_PARAMETER;
186                 goto exception;
187         }
188
189         root_obj = json_node_get_object(root);
190         if (root_obj == NULL) {
191                 ret = BUNDLE_ERROR_INVALID_PARAMETER;
192                 goto exception;
193         }
194
195         new_b = bundle_create();
196         if (new_b == NULL) {
197                 ret = BUNDLE_ERROR_OUT_OF_MEMORY;
198                 goto exception;
199         }
200
201         json_object_foreach_member(root_obj,
202                         __add_bundle_data_from_json, new_b);
203
204         *b = new_b;
205
206 exception:
207         if (error)
208                 g_error_free(error);
209         if (parser)
210                 g_object_unref(parser);
211
212         return ret;
213 }