1171 lines
33 KiB
Python
1171 lines
33 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
Description: commom source file
|
|
Interface: None
|
|
History: 2019-06-17
|
|
'''
|
|
# - Copyright (C) Huawei Technologies., Ltd. 2018-2019. All rights reserved.
|
|
# - lcr licensed under the Mulan PSL v1.
|
|
# - You can use this software according to the terms and conditions of the Mulan PSL v1.
|
|
# - You may obtain a copy of Mulan PSL v1 at:
|
|
# - http://license.coscl.org.cn/MulanPSL
|
|
# - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
|
# - IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
|
# - PURPOSE.
|
|
# - See the Mulan PSL v1 for more details.
|
|
# - Description: generate json
|
|
# - Author: tanyifeng
|
|
# - Create: 2018-04-25
|
|
#!/usr/bin/python -Es
|
|
|
|
CODE = '''// Auto generated file. Do not edit!
|
|
# define _GNU_SOURCE
|
|
# include <stdio.h>
|
|
# include <errno.h>
|
|
# include <limits.h>
|
|
# include "json_common.h"
|
|
|
|
# define MAX_NUM_STR_LEN 21
|
|
|
|
|
|
|
|
yajl_gen_status map_uint(void *ctx, long long unsigned int num) {
|
|
char numstr[MAX_NUM_STR_LEN];
|
|
int ret;
|
|
|
|
ret = snprintf(numstr, sizeof(numstr), "%llu", num);
|
|
if (ret < 0 || (size_t)ret >= sizeof(numstr)) {
|
|
return yajl_gen_in_error_state;
|
|
}
|
|
return yajl_gen_number((yajl_gen)ctx, (const char *)numstr, strlen(numstr));
|
|
}
|
|
|
|
yajl_gen_status map_int(void *ctx, long long int num) {
|
|
char numstr[MAX_NUM_STR_LEN];
|
|
int ret;
|
|
|
|
ret = snprintf(numstr, sizeof(numstr), "%lld", num);
|
|
if (ret < 0 || (size_t)ret >= sizeof(numstr)) {
|
|
return yajl_gen_in_error_state;
|
|
}
|
|
return yajl_gen_number((yajl_gen)ctx, (const char *)numstr, strlen(numstr));
|
|
}
|
|
|
|
|
|
bool json_gen_init(yajl_gen *g, const struct parser_context *ctx) {
|
|
*g = yajl_gen_alloc(NULL);
|
|
if (NULL == *g) {
|
|
return false;
|
|
|
|
}
|
|
yajl_gen_config(*g, yajl_gen_beautify, (int)(!(ctx->options & OPT_GEN_SIMPLIFY)));
|
|
yajl_gen_config(*g, yajl_gen_validate_utf8, (int)(!(ctx->options & OPT_GEN_NO_VALIDATE_UTF8)));
|
|
return true;
|
|
}
|
|
|
|
yajl_val get_val(yajl_val tree, const char *name, yajl_type type) {
|
|
const char *path[] = { name, NULL };
|
|
return yajl_tree_get(tree, path, type);
|
|
}
|
|
|
|
void *safe_malloc(size_t size) {
|
|
void *ret = NULL;
|
|
if (size == 0) {
|
|
abort();
|
|
}
|
|
ret = calloc(1, size);
|
|
if (ret == NULL) {
|
|
abort();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int common_safe_double(const char *numstr, double *converted) {
|
|
char *err_str = NULL;
|
|
double d;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
d = strtod(numstr, &err_str);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err_str == NULL || err_str == numstr || *err_str != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
*converted = d;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_uint8(const char *numstr, uint8_t *converted) {
|
|
char *err = NULL;
|
|
unsigned long int uli;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
uli = strtoul(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (uli > UINT8_MAX) {
|
|
return -ERANGE;
|
|
}
|
|
|
|
*converted = (uint8_t)uli;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_uint16(const char *numstr, uint16_t *converted) {
|
|
char *err = NULL;
|
|
unsigned long int uli;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
uli = strtoul(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (uli > UINT16_MAX) {
|
|
return -ERANGE;
|
|
}
|
|
|
|
*converted = (uint16_t)uli;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_uint32(const char *numstr, uint32_t *converted) {
|
|
char *err = NULL;
|
|
unsigned long long int ull;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
ull = strtoull(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (ull > UINT32_MAX) {
|
|
return -ERANGE;
|
|
}
|
|
|
|
*converted = (uint32_t)ull;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_uint64(const char *numstr, uint64_t *converted) {
|
|
char *err = NULL;
|
|
unsigned long long int ull;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
ull = strtoull(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
*converted = (uint64_t)ull;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_uint(const char *numstr, unsigned int *converted) {
|
|
char *err = NULL;
|
|
unsigned long long int ull;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
ull = strtoull(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (ull > UINT_MAX) {
|
|
return -ERANGE;
|
|
}
|
|
|
|
*converted = (unsigned int)ull;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_int8(const char *numstr, int8_t *converted) {
|
|
char *err = NULL;
|
|
long int li;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
li = strtol(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (li > INT8_MAX || li < INT8_MIN) {
|
|
return -ERANGE;
|
|
}
|
|
|
|
*converted = (int8_t)li;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_int16(const char *numstr, int16_t *converted) {
|
|
char *err = NULL;
|
|
long int li;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
li = strtol(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (li > INT16_MAX || li < INT16_MIN) {
|
|
return -ERANGE;
|
|
}
|
|
|
|
*converted = (int16_t)li;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_int32(const char *numstr, int32_t *converted) {
|
|
char *err = NULL;
|
|
long long int lli;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
lli = strtol(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (lli > INT32_MAX || lli < INT32_MIN) {
|
|
return -ERANGE;
|
|
}
|
|
|
|
*converted = (int32_t)lli;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_int64(const char *numstr, int64_t *converted) {
|
|
char *err = NULL;
|
|
long long int lli;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
lli = strtoll(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
*converted = (int64_t)lli;
|
|
return 0;
|
|
}
|
|
|
|
int common_safe_int(const char *numstr, int *converted) {
|
|
char *err = NULL;
|
|
long long int lli;
|
|
|
|
if (numstr == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
errno = 0;
|
|
lli = strtol(numstr, &err, 0);
|
|
if (errno > 0) {
|
|
return -errno;
|
|
}
|
|
|
|
if (err == NULL || err == numstr || *err != '\\0') {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (lli > INT_MAX || lli < INT_MIN) {
|
|
return -ERANGE;
|
|
}
|
|
|
|
*converted = (int)lli;
|
|
return 0;
|
|
}
|
|
|
|
char *safe_strdup(const char *src)
|
|
{
|
|
char *dst = NULL;
|
|
|
|
if (src == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
dst = strdup(src);
|
|
if (dst == NULL) {
|
|
abort();
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
|
|
yajl_gen_status gen_json_map_int_int(void *ctx, const json_map_int_int *map, const struct parser_context *ptx, parser_error *err) {
|
|
yajl_gen_status stat = yajl_gen_status_ok;
|
|
yajl_gen g = (yajl_gen) ctx;
|
|
size_t len = 0, i = 0;
|
|
if (map != NULL) {
|
|
len = map->len;
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 0);
|
|
}
|
|
stat = yajl_gen_map_open((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
|
|
}
|
|
for (i = 0; i < len; i++) {
|
|
char numstr[MAX_NUM_STR_LEN];
|
|
int nret;
|
|
nret = snprintf(numstr, sizeof(numstr), "%lld", (long long int)map->keys[i]);
|
|
if (nret < 0 || (size_t)nret >= sizeof(numstr)) {
|
|
if (!*err && asprintf(err, "Error to print string") < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
return yajl_gen_in_error_state;
|
|
}
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)numstr, strlen(numstr));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
stat = map_int(g, map->values[i]);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
}
|
|
|
|
stat = yajl_gen_map_close((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 1);
|
|
}
|
|
return yajl_gen_status_ok;
|
|
}
|
|
|
|
void free_json_map_int_int(json_map_int_int *map) {
|
|
if (map != NULL) {
|
|
free(map->keys);
|
|
map->keys = NULL;
|
|
free(map->values);
|
|
map->values = NULL;
|
|
free(map);
|
|
}
|
|
}
|
|
json_map_int_int *make_json_map_int_int(yajl_val src, const struct parser_context *ctx, parser_error *err) {
|
|
json_map_int_int *ret = NULL;
|
|
if (src != NULL && YAJL_GET_OBJECT(src) != NULL) {
|
|
size_t i;
|
|
size_t len = YAJL_GET_OBJECT(src)->len;
|
|
ret = safe_malloc(sizeof(*ret));
|
|
ret->len = len;
|
|
ret->keys = safe_malloc((len + 1) * sizeof(int));
|
|
ret->values = safe_malloc((len + 1) * sizeof(int));
|
|
for (i = 0; i < len; i++) {
|
|
const char *srckey = YAJL_GET_OBJECT(src)->keys[i];
|
|
yajl_val srcval = YAJL_GET_OBJECT(src)->values[i];
|
|
|
|
if (srckey != NULL) {
|
|
int invalid;
|
|
invalid = common_safe_int(srckey, &(ret->keys[i]));
|
|
if (invalid) {
|
|
if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_int_int(ret);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (srcval != NULL) {
|
|
int invalid;
|
|
if (!YAJL_IS_NUMBER(srcval)) {
|
|
if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_int_int(ret);
|
|
return NULL;
|
|
}
|
|
invalid = common_safe_int(YAJL_GET_NUMBER(srcval), &(ret->values[i]));
|
|
if (invalid) {
|
|
if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_int_int(ret);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int append_json_map_int_int(json_map_int_int *map, int key, int val) {
|
|
size_t len;
|
|
int *keys = NULL;
|
|
int *vals = NULL;
|
|
|
|
if (map == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
if ((SIZE_MAX / sizeof(int) - 1) < map->len) {
|
|
return -1;
|
|
}
|
|
|
|
len = map->len + 1;
|
|
keys = safe_malloc(len * sizeof(int));
|
|
vals = safe_malloc(len * sizeof(int));
|
|
|
|
if (map->len) {
|
|
(void)memcpy(keys, map->keys, map->len * sizeof(int));
|
|
(void)memcpy(vals, map->values, map->len * sizeof(int));
|
|
}
|
|
free(map->keys);
|
|
map->keys = keys;
|
|
free(map->values);
|
|
map->values = vals;
|
|
map->keys[map->len] = key;
|
|
map->values[map->len] = val;
|
|
|
|
map->len++;
|
|
return 0;
|
|
}
|
|
|
|
yajl_gen_status gen_json_map_int_bool(void *ctx, const json_map_int_bool *map, const struct parser_context *ptx, parser_error *err) {
|
|
yajl_gen_status stat = yajl_gen_status_ok;
|
|
yajl_gen g = (yajl_gen) ctx;
|
|
size_t len = 0, i = 0;
|
|
if (map != NULL) {
|
|
len = map->len;
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 0);
|
|
}
|
|
stat = yajl_gen_map_open((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
|
|
}
|
|
for (i = 0; i < len; i++) {
|
|
char numstr[MAX_NUM_STR_LEN];
|
|
int nret;
|
|
nret = snprintf(numstr, sizeof(numstr), "%lld", (long long int)map->keys[i]);
|
|
if (nret < 0 || (size_t)nret >= sizeof(numstr)) {
|
|
if (!*err && asprintf(err, "Error to print string") < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
return yajl_gen_in_error_state;
|
|
}
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)numstr, strlen(numstr));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
stat = yajl_gen_bool((yajl_gen)g, (int)(map->values[i]));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
}
|
|
|
|
stat = yajl_gen_map_close((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 1);
|
|
}
|
|
return yajl_gen_status_ok;
|
|
}
|
|
|
|
void free_json_map_int_bool(json_map_int_bool *map) {
|
|
if (map != NULL) {
|
|
size_t i;
|
|
for (i = 0; i < map->len; i++) {
|
|
// No need to free key for type int
|
|
// No need to free value for type bool
|
|
}
|
|
free(map->keys);
|
|
map->keys = NULL;
|
|
free(map->values);
|
|
map->values = NULL;
|
|
free(map);
|
|
}
|
|
}
|
|
json_map_int_bool *make_json_map_int_bool(yajl_val src, const struct parser_context *ctx, parser_error *err) {
|
|
json_map_int_bool *ret = NULL;
|
|
if (src != NULL && YAJL_GET_OBJECT(src) != NULL) {
|
|
size_t i;
|
|
size_t len = YAJL_GET_OBJECT(src)->len;
|
|
ret = safe_malloc(sizeof(*ret));
|
|
ret->len = len;
|
|
ret->keys = safe_malloc((len + 1) * sizeof(int));
|
|
ret->values = safe_malloc((len + 1) * sizeof(bool));
|
|
for (i = 0; i < len; i++) {
|
|
const char *srckey = YAJL_GET_OBJECT(src)->keys[i];
|
|
yajl_val srcval = YAJL_GET_OBJECT(src)->values[i];
|
|
|
|
if (srckey != NULL) {
|
|
int invalid;
|
|
invalid = common_safe_int(srckey, &(ret->keys[i]));
|
|
if (invalid) {
|
|
if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_int_bool(ret);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (srcval != NULL) {
|
|
if (YAJL_IS_TRUE(srcval)) {
|
|
ret->values[i] = true;
|
|
} else if (YAJL_IS_FALSE(srcval)) {
|
|
ret->values[i] = false;
|
|
} else {
|
|
if (*err == NULL && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_int_bool(ret);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int append_json_map_int_bool(json_map_int_bool *map, int key, bool val) {
|
|
size_t len;
|
|
int *keys = NULL;
|
|
bool *vals = NULL;
|
|
|
|
if (map == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
if ((SIZE_MAX / sizeof(int) - 1) < map->len || (SIZE_MAX / sizeof(bool) - 1) < map->len) {
|
|
return -1;
|
|
}
|
|
|
|
len = map->len + 1;
|
|
keys = safe_malloc(len * sizeof(int));
|
|
vals = safe_malloc(len * sizeof(bool));
|
|
|
|
if (map->len) {
|
|
(void)memcpy(keys, map->keys, map->len * sizeof(int));
|
|
(void)memcpy(vals, map->values, map->len * sizeof(bool));
|
|
}
|
|
free(map->keys);
|
|
map->keys = keys;
|
|
free(map->values);
|
|
map->values = vals;
|
|
map->keys[map->len] = key;
|
|
map->values[map->len] = val;
|
|
|
|
map->len++;
|
|
return 0;
|
|
}
|
|
|
|
yajl_gen_status gen_json_map_int_string(void *ctx, const json_map_int_string *map, const struct parser_context *ptx, parser_error *err) {
|
|
yajl_gen_status stat = yajl_gen_status_ok;
|
|
yajl_gen g = (yajl_gen) ctx;
|
|
size_t len = 0, i = 0;
|
|
if (map != NULL) {
|
|
len = map->len;
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 0);
|
|
}
|
|
stat = yajl_gen_map_open((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
|
|
}
|
|
for (i = 0; i < len; i++) {
|
|
char numstr[MAX_NUM_STR_LEN];
|
|
int nret;
|
|
nret = snprintf(numstr, sizeof(numstr), "%lld", (long long int)map->keys[i]);
|
|
if (nret < 0 || (size_t)nret >= sizeof(numstr)) {
|
|
if (!*err && asprintf(err, "Error to print string") < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
return yajl_gen_in_error_state;
|
|
}
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)numstr, strlen(numstr));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)(map->values[i]), strlen(map->values[i]));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
}
|
|
|
|
stat = yajl_gen_map_close((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 1);
|
|
}
|
|
return yajl_gen_status_ok;
|
|
}
|
|
|
|
void free_json_map_int_string(json_map_int_string *map) {
|
|
if (map != NULL) {
|
|
size_t i;
|
|
for (i = 0; i < map->len; i++) {
|
|
// No need to free key for type int
|
|
free(map->values[i]);
|
|
map->values[i] = NULL;
|
|
}
|
|
free(map->keys);
|
|
map->keys = NULL;
|
|
free(map->values);
|
|
map->values = NULL;
|
|
free(map);
|
|
}
|
|
}
|
|
json_map_int_string *make_json_map_int_string(yajl_val src, const struct parser_context *ctx, parser_error *err) {
|
|
json_map_int_string *ret = NULL;
|
|
if (src != NULL && YAJL_GET_OBJECT(src) != NULL) {
|
|
size_t i;
|
|
size_t len = YAJL_GET_OBJECT(src)->len;
|
|
ret = safe_malloc(sizeof(*ret));
|
|
ret->len = len;
|
|
ret->keys = safe_malloc((len + 1) * sizeof(int));
|
|
ret->values = safe_malloc((len + 1) * sizeof(char *));
|
|
for (i = 0; i < len; i++) {
|
|
const char *srckey = YAJL_GET_OBJECT(src)->keys[i];
|
|
yajl_val srcval = YAJL_GET_OBJECT(src)->values[i];
|
|
|
|
if (srckey != NULL) {
|
|
int invalid;
|
|
invalid = common_safe_int(srckey, &(ret->keys[i]));
|
|
if (invalid) {
|
|
if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_int_string(ret);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (srcval != NULL) {
|
|
if (!YAJL_IS_STRING(srcval)) {
|
|
if (*err == NULL && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_int_string(ret);
|
|
return NULL;
|
|
}
|
|
char *str = YAJL_GET_STRING(srcval);
|
|
ret->values[i] = safe_strdup(str ? str : "");
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int append_json_map_int_string(json_map_int_string *map, int key, const char *val) {
|
|
size_t len;
|
|
int *keys = NULL;
|
|
char **vals = NULL;
|
|
|
|
if (map == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
if ((SIZE_MAX / sizeof(int) - 1) < map->len || (SIZE_MAX / sizeof(char *) - 1) < map->len) {
|
|
return -1;
|
|
}
|
|
|
|
len = map->len + 1;
|
|
keys = safe_malloc(len * sizeof(int));
|
|
vals = safe_malloc(len * sizeof(char *));
|
|
|
|
if (map->len) {
|
|
(void)memcpy(keys, map->keys, map->len * sizeof(int));
|
|
(void)memcpy(vals, map->values, map->len * sizeof(char *));
|
|
}
|
|
free(map->keys);
|
|
map->keys = keys;
|
|
free(map->values);
|
|
map->values = vals;
|
|
map->keys[map->len] = key;
|
|
map->values[map->len] = safe_strdup(val ? val : "");
|
|
|
|
map->len++;
|
|
return 0;
|
|
}
|
|
|
|
yajl_gen_status gen_json_map_string_int(void *ctx, const json_map_string_int *map, const struct parser_context *ptx, parser_error *err) {
|
|
yajl_gen_status stat = yajl_gen_status_ok;
|
|
yajl_gen g = (yajl_gen) ctx;
|
|
size_t len = 0, i = 0;
|
|
if (map != NULL) {
|
|
len = map->len;
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 0);
|
|
}
|
|
stat = yajl_gen_map_open((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
|
|
}
|
|
for (i = 0; i < len; i++) {
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)(map->keys[i]), strlen(map->keys[i]));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
stat = map_int(g, map->values[i]);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
}
|
|
|
|
stat = yajl_gen_map_close((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 1);
|
|
}
|
|
return yajl_gen_status_ok;
|
|
}
|
|
|
|
void free_json_map_string_int(json_map_string_int *map) {
|
|
if (map != NULL) {
|
|
size_t i;
|
|
for (i = 0; i < map->len; i++) {
|
|
free(map->keys[i]);
|
|
map->keys[i] = NULL;
|
|
}
|
|
free(map->keys);
|
|
map->keys = NULL;
|
|
free(map->values);
|
|
map->values = NULL;
|
|
free(map);
|
|
}
|
|
}
|
|
json_map_string_int *make_json_map_string_int(yajl_val src, const struct parser_context *ctx, parser_error *err) {
|
|
json_map_string_int *ret = NULL;
|
|
if (src != NULL && YAJL_GET_OBJECT(src) != NULL) {
|
|
size_t i;
|
|
size_t len = YAJL_GET_OBJECT(src)->len;
|
|
ret = safe_malloc(sizeof(*ret));
|
|
ret->len = len;
|
|
ret->keys = safe_malloc((len + 1) * sizeof(char *));
|
|
ret->values = safe_malloc((len + 1) * sizeof(int));
|
|
for (i = 0; i < len; i++) {
|
|
const char *srckey = YAJL_GET_OBJECT(src)->keys[i];
|
|
yajl_val srcval = YAJL_GET_OBJECT(src)->values[i];
|
|
ret->keys[i] = safe_strdup(srckey ? srckey : "");
|
|
|
|
if (srcval != NULL) {
|
|
int invalid;
|
|
if (!YAJL_IS_NUMBER(srcval)) {
|
|
if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_string_int(ret);
|
|
return NULL;
|
|
}
|
|
invalid = common_safe_int(YAJL_GET_NUMBER(srcval), &(ret->values[i]));
|
|
if (invalid) {
|
|
if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_string_int(ret);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int append_json_map_string_int(json_map_string_int *map, const char *key, int val) {
|
|
size_t len;
|
|
char **keys = NULL;
|
|
int *vals = NULL;
|
|
|
|
if (map == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
if ((SIZE_MAX / sizeof(char *) - 1) < map->len || (SIZE_MAX / sizeof(int) - 1) < map->len) {
|
|
return -1;
|
|
}
|
|
|
|
len = map->len + 1;
|
|
keys = safe_malloc(len * sizeof(char *));
|
|
vals = safe_malloc(len * sizeof(int));
|
|
|
|
if (map->len) {
|
|
(void)memcpy(keys, map->keys, map->len * sizeof(char *));
|
|
(void)memcpy(vals, map->values, map->len * sizeof(int));
|
|
}
|
|
free(map->keys);
|
|
map->keys = keys;
|
|
free(map->values);
|
|
map->values = vals;
|
|
map->keys[map->len] = safe_strdup(key ? key : "");
|
|
map->values[map->len] = val;
|
|
|
|
map->len++;
|
|
return 0;
|
|
}
|
|
|
|
yajl_gen_status gen_json_map_string_bool(void *ctx, const json_map_string_bool *map, const struct parser_context *ptx, parser_error *err) {
|
|
yajl_gen_status stat = yajl_gen_status_ok;
|
|
yajl_gen g = (yajl_gen) ctx;
|
|
size_t len = 0, i = 0;
|
|
if (map != NULL) {
|
|
len = map->len;
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 0);
|
|
}
|
|
stat = yajl_gen_map_open((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
|
|
}
|
|
for (i = 0; i < len; i++) {
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)(map->keys[i]), strlen(map->keys[i]));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
stat = yajl_gen_bool((yajl_gen)g, (int)(map->values[i]));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
}
|
|
|
|
stat = yajl_gen_map_close((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 1);
|
|
}
|
|
return yajl_gen_status_ok;
|
|
}
|
|
|
|
void free_json_map_string_bool(json_map_string_bool *map) {
|
|
if (map != NULL) {
|
|
size_t i;
|
|
for (i = 0; i < map->len; i++) {
|
|
free(map->keys[i]);
|
|
map->keys[i] = NULL;
|
|
// No need to free value for type bool
|
|
}
|
|
free(map->keys);
|
|
map->keys = NULL;
|
|
free(map->values);
|
|
map->values = NULL;
|
|
free(map);
|
|
}
|
|
}
|
|
json_map_string_bool *make_json_map_string_bool(yajl_val src, const struct parser_context *ctx, parser_error *err) {
|
|
json_map_string_bool *ret = NULL;
|
|
if (src != NULL && YAJL_GET_OBJECT(src) != NULL) {
|
|
size_t i;
|
|
size_t len = YAJL_GET_OBJECT(src)->len;
|
|
ret = safe_malloc(sizeof(*ret));
|
|
ret->len = len;
|
|
ret->keys = safe_malloc((len + 1) * sizeof(char *));
|
|
ret->values = safe_malloc((len + 1) * sizeof(bool));
|
|
for (i = 0; i < len; i++) {
|
|
const char *srckey = YAJL_GET_OBJECT(src)->keys[i];
|
|
yajl_val srcval = YAJL_GET_OBJECT(src)->values[i];
|
|
ret->keys[i] = safe_strdup(srckey ? srckey : "");
|
|
|
|
if (srcval != NULL) {
|
|
if (YAJL_IS_TRUE(srcval)) {
|
|
ret->values[i] = true;
|
|
} else if (YAJL_IS_FALSE(srcval)) {
|
|
ret->values[i] = false;
|
|
} else {
|
|
if (*err == NULL && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_string_bool(ret);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool val) {
|
|
size_t len;
|
|
char **keys = NULL;
|
|
bool *vals = NULL;
|
|
|
|
if (map == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
if ((SIZE_MAX / sizeof(char *) - 1) < map->len || (SIZE_MAX / sizeof(bool) - 1) < map->len) {
|
|
return -1;
|
|
}
|
|
|
|
len = map->len + 1;
|
|
keys = safe_malloc(len * sizeof(char *));
|
|
vals = safe_malloc(len * sizeof(bool));
|
|
|
|
if (map->len) {
|
|
(void)memcpy(keys, map->keys, map->len * sizeof(char *));
|
|
(void)memcpy(vals, map->values, map->len * sizeof(bool));
|
|
}
|
|
free(map->keys);
|
|
map->keys = keys;
|
|
free(map->values);
|
|
map->values = vals;
|
|
map->keys[map->len] = safe_strdup(key ? key : "");
|
|
map->values[map->len] = val;
|
|
|
|
map->len++;
|
|
return 0;
|
|
}
|
|
|
|
yajl_gen_status gen_json_map_string_string(void *ctx, const json_map_string_string *map, const struct parser_context *ptx, parser_error *err) {
|
|
yajl_gen_status stat = yajl_gen_status_ok;
|
|
yajl_gen g = (yajl_gen) ctx;
|
|
size_t len = 0, i = 0;
|
|
if (map != NULL) {
|
|
len = map->len;
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 0);
|
|
}
|
|
stat = yajl_gen_map_open((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
|
|
}
|
|
for (i = 0; i < len; i++) {
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)(map->keys[i]), strlen(map->keys[i]));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)(map->values[i]), strlen(map->values[i]));
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
}
|
|
|
|
stat = yajl_gen_map_close((yajl_gen)g);
|
|
if (yajl_gen_status_ok != stat) {
|
|
GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
}
|
|
if (!len && !(ptx->options & OPT_GEN_SIMPLIFY)) {
|
|
yajl_gen_config(g, yajl_gen_beautify, 1);
|
|
}
|
|
return yajl_gen_status_ok;
|
|
}
|
|
|
|
void free_json_map_string_string(json_map_string_string *map) {
|
|
if (map != NULL) {
|
|
size_t i;
|
|
for (i = 0; i < map->len; i++) {
|
|
free(map->keys[i]);
|
|
map->keys[i] = NULL;
|
|
free(map->values[i]);
|
|
map->values[i] = NULL;
|
|
}
|
|
free(map->keys);
|
|
map->keys = NULL;
|
|
free(map->values);
|
|
map->values = NULL;
|
|
free(map);
|
|
}
|
|
}
|
|
json_map_string_string *make_json_map_string_string(yajl_val src, const struct parser_context *ctx, parser_error *err) {
|
|
json_map_string_string *ret = NULL;
|
|
if (src != NULL && YAJL_GET_OBJECT(src) != NULL) {
|
|
size_t i;
|
|
size_t len = YAJL_GET_OBJECT(src)->len;
|
|
ret = safe_malloc(sizeof(*ret));
|
|
ret->len = len;
|
|
ret->keys = safe_malloc((len + 1) * sizeof(char *));
|
|
ret->values = safe_malloc((len + 1) * sizeof(char *));
|
|
for (i = 0; i < len; i++) {
|
|
const char *srckey = YAJL_GET_OBJECT(src)->keys[i];
|
|
yajl_val srcval = YAJL_GET_OBJECT(src)->values[i];
|
|
ret->keys[i] = safe_strdup(srckey ? srckey : "");
|
|
|
|
if (srcval != NULL) {
|
|
if (!YAJL_IS_STRING(srcval)) {
|
|
if (*err == NULL && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) {
|
|
*(err) = safe_strdup("error allocating memory");
|
|
}
|
|
free_json_map_string_string(ret);
|
|
return NULL;
|
|
}
|
|
char *str = YAJL_GET_STRING(srcval);
|
|
ret->values[i] = safe_strdup(str ? str : "");
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int append_json_map_string_string(json_map_string_string *map, const char *key, const char *val) {
|
|
size_t len, i;
|
|
char **keys = NULL;
|
|
char **vals = NULL;
|
|
|
|
if (map == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < map->len; i++) {
|
|
if (strcmp(map->keys[i], key) == 0) {
|
|
free(map->values[i]);
|
|
map->values[i] = safe_strdup(val ? val : "");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if ((SIZE_MAX / sizeof(char *) - 1) < map->len) {
|
|
return -1;
|
|
}
|
|
|
|
len = map->len + 1;
|
|
keys = safe_malloc(len * sizeof(char *));
|
|
vals = safe_malloc(len * sizeof(char *));
|
|
|
|
if (map->len) {
|
|
(void)memcpy(keys, map->keys, map->len * sizeof(char *));
|
|
(void)memcpy(vals, map->values, map->len * sizeof(char *));
|
|
}
|
|
free(map->keys);
|
|
map->keys = keys;
|
|
free(map->values);
|
|
map->values = vals;
|
|
map->keys[map->len] = safe_strdup(key ? key : "");
|
|
map->values[map->len] = safe_strdup(val ? val : "");
|
|
|
|
map->len++;
|
|
return 0;
|
|
}
|
|
|
|
char *json_marshal_string(const char *str, size_t strlen, const struct parser_context *ctx, parser_error *err)
|
|
{
|
|
yajl_gen g = NULL;
|
|
struct parser_context tmp_ctx = { 0 };
|
|
const unsigned char *gen_buf = NULL;
|
|
char *json_buf = NULL;
|
|
size_t gen_len = 0;
|
|
yajl_gen_status stat;
|
|
|
|
if (str == NULL || err == NULL)
|
|
return NULL;
|
|
|
|
*err = NULL;
|
|
if (ctx == NULL) {
|
|
ctx = (const struct parser_context *)(&tmp_ctx);
|
|
}
|
|
|
|
if (!json_gen_init(&g, ctx)) {
|
|
*err = safe_strdup("Json_gen init failed");
|
|
goto out;
|
|
}
|
|
stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)str, strlen);
|
|
if (yajl_gen_status_ok != stat) {
|
|
if (asprintf(err, "error generating json, errcode: %d", (int)stat) < 0) {
|
|
*err = safe_strdup("error allocating memory");
|
|
}
|
|
goto free_out;
|
|
}
|
|
yajl_gen_get_buf(g, &gen_buf, &gen_len);
|
|
if (gen_buf == NULL) {
|
|
*err = safe_strdup("Error to get generated json");
|
|
goto free_out;
|
|
}
|
|
|
|
json_buf = safe_malloc(gen_len + 1);
|
|
(void)memcpy(json_buf, gen_buf, gen_len);
|
|
json_buf[gen_len] = '\\0';
|
|
|
|
free_out:
|
|
yajl_gen_clear(g);
|
|
yajl_gen_free(g);
|
|
out:
|
|
return json_buf;
|
|
}
|
|
|
|
'''
|