Add new internal API for json 11/56411/16 accepted/tizen/mobile/20160108.070011 accepted/tizen/tv/20160108.070119 accepted/tizen/wearable/20160108.070243 submit/tizen/20160108.043346
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 7 Jan 2016 11:51:47 +0000 (20:51 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 8 Jan 2016 03:13:12 +0000 (12:13 +0900)
- Add bundle_to_json()
- Add bundle_from_json()

Change-Id: Iee21b1d17b00bb51b926f2a5410b18b4d7c76894
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
CMakeLists.txt
include/bundle_internal.h
packaging/bundle.spec
src/bundle_json.c [new file with mode: 0644]

index e2df7b4..c8f3ce7 100644 (file)
@@ -11,7 +11,7 @@ ENDIF()
 
 ### Required packages
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED glib-2.0 dlog capi-base-common)
+pkg_check_modules(pkgs REQUIRED glib-2.0 dlog capi-base-common json-glib-1.0)
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
@@ -22,8 +22,9 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 include_directories(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src)
 
 ### Build
-add_library(bundle SHARED 
+add_library(bundle SHARED
                src/bundle.c
+               src/bundle_json.c
                src/keyval_type.c
                src/keyval.c
                src/keyval_array.c
index 06df09e..975c54b 100755 (executable)
@@ -438,6 +438,59 @@ API int bundle_set_byte_array_element(bundle *b, const char *key, const unsigned
  */
 API int bundle_get_byte_array(bundle *b, const char *key, void ***byte_array, unsigned int *len, unsigned int **array_element_size);
 
+/**
+ * @brief Creates a json data from bundle.
+ * @since_tizen 3.0
+ * @remarks             This API only supports the string type and the string array type.
+ * @param[in]   b       The bundle object
+ * @param[out]  json    The new created json data
+ * @return              The operation result
+ * @retval      BUNDLE_ERROR_NONE       Success
+ * @retval      BUNDLE_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval      BUNDLE_ERROR_OUT_OF_MEMORY      Out of memory
+ * @pre                 @a b must be a valid bundle object.
+ @code
+ #include <bundle_internal.h>
+ bundle *b = bundle_create();
+ char *json;
+ int ret;
+
+ bundle_add_str(b, "foo", "bar");
+ ret = bundle_to_json(b, &json);
+ if (ret != BUNDLE_ERROR_NONE) {
+ bundle_free(b);
+ return;
+ }
+ // json = "{"foo":"bar"}"
+ bundle_free(b);
+ free(json);
+ @endcode
+ */
+API int bundle_to_json(bundle *b, char **json);
+
+/**
+ * @breif Creates a bundle object from json.
+ * @since_tizen 3.0
+ * @remarks             This API only supports the string type and the string array type.
+ * @param[in]   json    The json data
+ * @param[out]  b       The bundle object
+ * @return              The operation result
+ * @retval      BUNDLE_ERROR_NONE       Success
+ * @retval      BUNDLE_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval      BUNDLE_ERROR_OUT_OF_MEMORY      Out of memory
+ @code
+ #include <bundle_internal.h>
+ bundle *b;
+ char *json = "{"foo":"bar"}";
+ int ret;
+
+ ret =  bundle_from_json(json, &b);
+ if (ret != BUNDLE_ERROR_NONE)
+ return;
+ bundle_free(b);
+ @endcode
+ */
+API int bundle_from_json(const char *json, bundle **b);
 
 #ifdef __cplusplus
 }
index 76702c3..c2a4e69 100644 (file)
@@ -10,6 +10,7 @@ BuildRequires:  cmake
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(capi-base-common)
+BuildRequires:  pkgconfig(json-glib-1.0)
 %description
 Simple string key-val dictionary ADT
 
diff --git a/src/bundle_json.c b/src/bundle_json.c
new file mode 100644 (file)
index 0000000..f8601ba
--- /dev/null
@@ -0,0 +1,197 @@
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <json-glib/json-glib.h>
+
+#include "bundle.h"
+#include "bundle_internal.h"
+
+static void __add_json_data_from_bundle(const char *key,
+               const int type,
+               const bundle_keyval_t *kv,
+               void *user_data)
+{
+       void *basic_val = NULL;
+       size_t basic_size = 0;
+       void **array_val = NULL;
+       unsigned int array_len = 0;
+       size_t *array_elem_size = 0;
+       JsonObject *json_obj = (JsonObject *)user_data;
+       JsonArray *json_arr;
+       unsigned int i;
+       int ret;
+
+       if (json_obj == NULL)
+               return;
+
+       if (bundle_keyval_type_is_array((bundle_keyval_t *)kv)) {
+               ret = bundle_keyval_get_array_val((bundle_keyval_t *)kv,
+                               &array_val, &array_len, &array_elem_size);
+               if (ret != BUNDLE_ERROR_NONE)
+                       return;
+
+               json_arr = json_array_new();
+               if (json_arr == NULL)
+                       return;
+
+               for (i = 0; i < array_len; i++)
+                       json_array_add_string_element(json_arr, array_val[i]);
+
+               json_object_set_array_member(json_obj, key, json_arr);
+       } else {
+               ret = bundle_keyval_get_basic_val((bundle_keyval_t *)kv,
+                               &basic_val, &basic_size);
+               if (ret != BUNDLE_ERROR_NONE)
+                       return;
+
+               json_object_set_string_member(json_obj, key, basic_val);
+       }
+}
+
+int bundle_to_json(bundle *b, char **json)
+{
+       JsonObject *object;
+       JsonNode *node;
+       JsonGenerator *generator = NULL;
+       gchar *new_json = NULL;
+       gsize length;
+       int ret = BUNDLE_ERROR_NONE;
+
+       if (b == NULL || json == NULL)
+               return BUNDLE_ERROR_INVALID_PARAMETER;
+
+       object = json_object_new();
+       if (object == NULL)
+               return BUNDLE_ERROR_OUT_OF_MEMORY;
+
+       bundle_foreach(b, __add_json_data_from_bundle, object);
+
+       node = json_node_new(JSON_NODE_OBJECT);
+       if (node == NULL) {
+               ret = BUNDLE_ERROR_OUT_OF_MEMORY;
+               goto exception;
+       }
+
+       json_node_set_object(node, object);
+
+       generator = json_generator_new();
+       if (generator == NULL) {
+               ret = BUNDLE_ERROR_OUT_OF_MEMORY;
+               goto exception;
+       }
+
+       json_generator_set_root(generator, node);
+
+       new_json = json_generator_to_data(generator, &length);
+       if (new_json == NULL) {
+               ret = BUNDLE_ERROR_OUT_OF_MEMORY;
+               goto exception;
+       }
+
+       *json = (char *)new_json;
+
+exception:
+       if (generator)
+               g_object_unref(generator);
+       if (node)
+               json_node_free(node);
+       if (object)
+               json_object_unref(object);
+
+       return ret;
+}
+
+static void __add_bundle_data_from_json(JsonObject *object,
+               const char *key,
+               JsonNode *node,
+               gpointer user_data)
+{
+       bundle *b = (bundle *)user_data;
+       JsonNodeType node_type;
+       JsonArray *json_arr;
+       const gchar *val;
+       guint len;
+       guint i;
+       char **arr_val;
+
+       if (key == NULL || node == NULL)
+               return;
+
+       node_type = JSON_NODE_TYPE(node);
+       if (node_type == JSON_NODE_ARRAY) {
+               json_arr = json_node_get_array(node);
+               len = json_array_get_length(json_arr);
+
+               arr_val = (char **)calloc(1, sizeof(char *) * len);
+               if (arr_val == NULL)
+                       return;
+
+               for (i = 0; i < len; i++)
+                       arr_val[i] = strdup(json_array_get_string_element
+                                       (json_arr, i));
+
+               bundle_add_str_array(b, key, (const char **)arr_val, len);
+
+               for (i = 0; i < len; i++)
+                       free(arr_val[i]);
+               free(arr_val);
+       } else if (node_type == JSON_NODE_VALUE) {
+               val = json_node_get_string(node);
+               if (val)
+                       bundle_add_str(b, key, (const char *)val);
+       }
+}
+
+int bundle_from_json(const char *json, bundle **b)
+{
+       GError *error = NULL;
+       JsonParser *parser;
+       JsonNode *root;
+       JsonObject *root_obj;
+       bundle *new_b;
+       int ret = BUNDLE_ERROR_NONE;
+
+       if (json == NULL || b == NULL)
+               return BUNDLE_ERROR_INVALID_PARAMETER;
+
+       parser = json_parser_new();
+       if (parser == NULL)
+               return BUNDLE_ERROR_OUT_OF_MEMORY;
+
+       json_parser_load_from_data(parser, json, strlen(json), &error);
+       if (error) {
+               ret = BUNDLE_ERROR_INVALID_PARAMETER;
+               goto exception;
+       }
+
+       root = json_parser_get_root(parser);
+       if (root == NULL) {
+               ret = BUNDLE_ERROR_INVALID_PARAMETER;
+               goto exception;
+       }
+
+       root_obj = json_node_get_object(root);
+       if (root_obj == NULL) {
+               ret = BUNDLE_ERROR_INVALID_PARAMETER;
+               goto exception;
+       }
+
+       new_b = bundle_create();
+       if (new_b == NULL) {
+               ret = BUNDLE_ERROR_OUT_OF_MEMORY;
+               goto exception;
+       }
+
+       json_object_foreach_member(root_obj,
+                       __add_bundle_data_from_json, new_b);
+
+       *b = new_b;
+
+exception:
+       if (error)
+               g_error_free(error);
+       if (parser)
+               g_object_unref(parser);
+
+       return ret;
+}