diff options
author | Doohwan Kim <dh8210.kim@samsung.com> | 2015-02-26 17:39:16 +0900 |
---|---|---|
committer | Doohwan Kim <dh8210.kim@samsung.com> | 2015-02-26 17:39:45 +0900 |
commit | da07ee69267b4557028357eae802d2a7a57c34e7 (patch) | |
tree | 02a5d7590fc35cd3ad08aa8894ca5f32947a1da1 /src/common/json.c | |
parent | 34c41c0eecd122a3dd92b30f30267ea4d951343a (diff) | |
download | murphy-accepted/tizen_3.0.2015.q1_common.tar.gz murphy-accepted/tizen_3.0.2015.q1_common.tar.bz2 murphy-accepted/tizen_3.0.2015.q1_common.zip |
Initialize Tizen 3.0submit/tizen_3.0.2015.q1_common/20150320.000000submit/tizen/20150313.025220accepted/tizen/wearable/20150313.084641accepted/tizen/tv/20150313.084515accepted/tizen/mobile/20150313.084815accepted/tizen/common/20150313.083743accepted/tizen/3.0.2015.q1/common/20150323.084221tizen_3.0.2015.q2_commontizen_3.0.2015.q1_commonaccepted/tizen_3.0.2015.q1_common
Signed-off-by: Doohwan Kim <dh8210.kim@samsung.com>
Change-Id: I2ad7e23e121506673a724f512fea429489928451
Diffstat (limited to 'src/common/json.c')
-rw-r--r-- | src/common/json.c | 599 |
1 files changed, 599 insertions, 0 deletions
diff --git a/src/common/json.c b/src/common/json.c new file mode 100644 index 0000000..c275330 --- /dev/null +++ b/src/common/json.c @@ -0,0 +1,599 @@ +/* + * Copyright (c) 2012, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <errno.h> +#include <stdarg.h> +#include <string.h> + +#include "murphy/config.h" +#include <murphy/common/macros.h> +#include <murphy/common/log.h> +#include <murphy/common/debug.h> +#include <murphy/common/json.h> + +/** Type for a JSON parser. */ +typedef struct json_tokener mrp_json_parser_t; + +static mrp_json_parser_t *parser; + +mrp_json_t *mrp_json_create(mrp_json_type_t type, ...) +{ + mrp_json_t *o; + const char *s; + bool b; + int i, l; + double d; + va_list ap; + + va_start(ap, type); + switch (type) { + case MRP_JSON_STRING: + s = va_arg(ap, const char *); + l = va_arg(ap, int); + if (l < 0) + o = json_object_new_string(s); + else + o = json_object_new_string_len(s, l); + break; + case MRP_JSON_BOOLEAN: + b = va_arg(ap, int); + o = json_object_new_boolean(b); + break; + case MRP_JSON_INTEGER: + i = va_arg(ap, int); + o = json_object_new_int(i); + break; + case MRP_JSON_DOUBLE: + d = va_arg(ap, double); + o = json_object_new_double(d); + break; + case MRP_JSON_OBJECT: + o = json_object_new_object(); + break; + case MRP_JSON_ARRAY: + o = json_object_new_array(); + break; + default: + o = NULL; + } + va_end(ap); + + return o; +} + + +mrp_json_t *mrp_json_clone(mrp_json_t *o) +{ + if (o != NULL) + return mrp_json_string_to_object(mrp_json_object_to_string(o), -1); + else + return NULL; +} + + +mrp_json_t *mrp_json_string_to_object(const char *s, int len) +{ + if (parser == NULL) { + parser = json_tokener_new(); + + if (parser == NULL) + return NULL; + } + else + json_tokener_reset(parser); + + if (len < 0) + len = strlen(s); + + return json_tokener_parse_ex(parser, s, len); +} + + +const char *mrp_json_object_to_string(mrp_json_t *o) +{ + if (o != NULL) + return json_object_to_json_string(o); + else + return "{}"; +} + + +mrp_json_t *mrp_json_ref(mrp_json_t *o) +{ + return json_object_get(o); +} + + +void mrp_json_unref(mrp_json_t *o) +{ + json_object_put(o); +} + + +mrp_json_type_t mrp_json_get_type(mrp_json_t *o) +{ + return json_object_get_type(o); +} + + +int mrp_json_is_type(mrp_json_t *o, mrp_json_type_t type) +{ + return json_object_is_type(o, type); +} + + +void mrp_json_add(mrp_json_t *o, const char *key, mrp_json_t *m) +{ + json_object_object_add(o, key, m); +} + + +mrp_json_t *mrp_json_add_member(mrp_json_t *o, const char *key, + mrp_json_type_t type, ...) +{ + mrp_json_t *m; + const char *s; + bool b; + int i, l; + double d; + va_list ap; + + va_start(ap, type); + switch (type) { + case MRP_JSON_STRING: + s = va_arg(ap, const char *); + l = va_arg(ap, int); + if (l < 0) + m = json_object_new_string(s); + else + m = json_object_new_string_len(s, l); + break; + case MRP_JSON_BOOLEAN: + b = va_arg(ap, int); + m = json_object_new_boolean(b); + break; + case MRP_JSON_INTEGER: + i = va_arg(ap, int); + m = json_object_new_int(i); + break; + case MRP_JSON_DOUBLE: + d = va_arg(ap, double); + m = json_object_new_double(d); + break; + case MRP_JSON_OBJECT: + m = json_object_new_object(); + break; + case MRP_JSON_ARRAY: + m = json_object_new_array(); + break; + default: + m = NULL; + errno = EINVAL; + } + va_end(ap); + + if (m != NULL) + json_object_object_add(o, key, m); + + return m; +} + + +mrp_json_t *mrp_json_add_array(mrp_json_t *o, const char *key, + mrp_json_type_t type, ...) +{ + va_list ap; + void *arr; + size_t cnt, i; + mrp_json_t *a; + + va_start(ap, type); + arr = va_arg(ap, void *); + cnt = va_arg(ap, size_t); + a = mrp_json_create(MRP_JSON_ARRAY); + + if (a == NULL) + goto fail; + + switch (type) { + case MRP_JSON_STRING: + for (i = 0; i < cnt; i++) { + if (!mrp_json_array_append_string(a, ((char **)arr)[i])) + goto fail; + } + break; + + case MRP_JSON_INTEGER: + for (i = 0; i < cnt; i++) { + if (!mrp_json_array_append_integer(a, ((int *)arr)[i])) + goto fail; + } + break; + + case MRP_JSON_DOUBLE: + for (i = 0; i < cnt; i++) { + if (!mrp_json_array_append_double(a, ((double *)arr)[i])) + goto fail; + } + break; + + case MRP_JSON_BOOLEAN: + for (i = 0; i < cnt; i++) { + if (!mrp_json_array_append_boolean(a, ((bool *)arr)[i])) + goto fail; + } + break; + + default: + goto fail; + + } + + va_end(ap); + + mrp_json_add(o, key, a); + return a; + + fail: + va_end(ap); + mrp_json_unref(a); + + return NULL; +} + + +mrp_json_t *mrp_json_get(mrp_json_t *o, const char *key) +{ + mrp_json_iter_t it; + const char *k; + mrp_json_t *v; + + mrp_json_foreach_member(o, k, v, it) { + if (!strcmp(k, key)) + return v; + } + + return NULL; +} + + +int mrp_json_get_member(mrp_json_t *o, const char *key, + mrp_json_type_t type, ...) +{ + const char **s; + bool *b; + int *i; + double *d; + mrp_json_t *m, **mp; + int success; + va_list ap; + + success = FALSE; + va_start(ap, type); + + m = mrp_json_get(o, key); + + if (m != NULL) { + if (json_object_is_type(m, type)) { + success = TRUE; + switch (type) { + case MRP_JSON_STRING: + s = va_arg(ap, const char **); + *s = json_object_get_string(m); + break; + case MRP_JSON_BOOLEAN: + b = va_arg(ap, bool *); + *b = json_object_get_boolean(m); + break; + case MRP_JSON_INTEGER: + i = va_arg(ap, int *); + *i = json_object_get_int(m); + break; + case MRP_JSON_DOUBLE: + d = va_arg(ap, double *); + *d = json_object_get_double(m); + break; + case MRP_JSON_OBJECT: + mp = va_arg(ap, mrp_json_t **); + *mp = m; + break; + case MRP_JSON_ARRAY: + mp = va_arg(ap, mrp_json_t **); + *mp = m; + break; + default: + success = FALSE; + } + } + else + errno = EINVAL; + } + else { + errno = ENOENT; + success = FALSE; + } + + va_end(ap); + + return success; +} + + +void mrp_json_del_member(mrp_json_t *o, const char *key) +{ + json_object_object_del(o, key); +} + + +int mrp_json_array_length(mrp_json_t *a) +{ + return json_object_array_length(a); +} + + +int mrp_json_array_append(mrp_json_t *a, mrp_json_t *v) +{ + return json_object_array_add(a, v) == 0; +} + + +mrp_json_t *mrp_json_array_append_item(mrp_json_t *a, mrp_json_type_t type, ...) +{ + mrp_json_t *v; + const char *s; + bool b; + int i, l; + double d; + va_list ap; + + va_start(ap, type); + switch (type) { + case MRP_JSON_STRING: + s = va_arg(ap, const char *); + l = va_arg(ap, int); + if (l < 0) + v = json_object_new_string(s); + else + v = json_object_new_string_len(s, l); + break; + case MRP_JSON_BOOLEAN: + b = va_arg(ap, int); + v = json_object_new_boolean(b); + break; + case MRP_JSON_INTEGER: + i = va_arg(ap, int); + v = json_object_new_int(i); + break; + case MRP_JSON_DOUBLE: + d = va_arg(ap, double); + v = json_object_new_double(d); + break; + case MRP_JSON_OBJECT: + v = va_arg(ap, mrp_json_t *); + break; + case MRP_JSON_ARRAY: + v = va_arg(ap, mrp_json_t *); + break; + default: + v = NULL; + errno = EINVAL; + } + va_end(ap); + + if (v != NULL) { + if (json_object_array_add(a, v) == 0) + return v; + else { + mrp_json_unref(v); + errno = ENOMEM; + } + } + + return NULL; +} + + +int mrp_json_array_set(mrp_json_t *a, int idx, mrp_json_t *v) +{ + return json_object_array_put_idx(a, idx, v); +} + + +int mrp_json_array_set_item(mrp_json_t *a, int idx, mrp_json_type_t type, ...) +{ + mrp_json_t *v; + const char *s; + bool b; + int i, l; + double d; + va_list ap; + + va_start(ap, type); + switch (type) { + case MRP_JSON_STRING: + s = va_arg(ap, const char *); + l = va_arg(ap, int); + if (l < 0) + v = json_object_new_string(s); + else + v = json_object_new_string_len(s, l); + break; + case MRP_JSON_BOOLEAN: + b = va_arg(ap, int); + v = json_object_new_boolean(b); + break; + case MRP_JSON_INTEGER: + i = va_arg(ap, int); + v = json_object_new_int(i); + break; + case MRP_JSON_DOUBLE: + d = va_arg(ap, double); + v = json_object_new_double(d); + break; + case MRP_JSON_OBJECT: + v = va_arg(ap, mrp_json_t *); + break; + case MRP_JSON_ARRAY: + v = va_arg(ap, mrp_json_t *); + break; + default: + v = NULL; + errno = EINVAL; + } + va_end(ap); + + if (v != NULL) + return json_object_array_put_idx(a, idx, v); + else { + errno = ENOMEM; + return FALSE; + } +} + + +mrp_json_t *mrp_json_array_get(mrp_json_t *a, int idx) +{ + return json_object_array_get_idx(a, idx); +} + + +int mrp_json_array_get_item(mrp_json_t *a, int idx, mrp_json_type_t type, ...) +{ + const char **s; + bool *b; + int *i; + double *d; + mrp_json_t *v, **vp; + int success; + va_list ap; + + success = FALSE; + va_start(ap, type); + + v = json_object_array_get_idx(a, idx); + + if (v != NULL) { + if (json_object_is_type(v, type)) { + success = TRUE; + switch (type) { + case MRP_JSON_STRING: + s = va_arg(ap, const char **); + *s = json_object_get_string(v); + break; + case MRP_JSON_BOOLEAN: + b = va_arg(ap, bool *); + *b = json_object_get_boolean(v); + break; + case MRP_JSON_INTEGER: + i = va_arg(ap, int *); + *i = json_object_get_int(v); + break; + case MRP_JSON_DOUBLE: + d = va_arg(ap, double *); + *d = json_object_get_double(v); + break; + case MRP_JSON_OBJECT: + vp = va_arg(ap, mrp_json_t **); + *vp = v; + break; + case MRP_JSON_ARRAY: + vp = va_arg(ap, mrp_json_t **); + *vp = v; + break; + default: + success = FALSE; + errno = EINVAL; + } + } + else + errno = EINVAL; + } + else + errno = ENOENT; + + va_end(ap); + + return success; +} + + +int mrp_json_parse_object(char **strp, int *lenp, mrp_json_t **op) +{ + char *str; + int len; + mrp_json_t *o = NULL; + json_tokener *tok = NULL; + int res = -1; + + if (strp == NULL || *strp == NULL) { + *op = NULL; + if (lenp != NULL) + *lenp = 0; + + return 0; + } + + str = *strp; + len = lenp ? *lenp : 0; + + if (len <= 0) + len = strlen(str); + + tok = json_tokener_new(); + + if (tok != NULL) { + o = json_tokener_parse_ex(tok, str, len); + + if (o != NULL) { + *strp += tok->char_offset; + if (lenp != NULL) + *lenp -= tok->char_offset; + + res = 0; + } + else { +#ifdef HAVE_JSON_TOKENER_GET_ERROR + if (json_tokener_get_error(tok) != json_tokener_success) + errno = EINVAL; +#else + if (tok->err != json_tokener_success) + errno = EINVAL; +#endif + else + res = 0; + } + + json_tokener_free(tok); + } + else + errno = ENOMEM; + + *op = o; + return res; +} |