diff options
author | thegeorg <[email protected]> | 2022-05-11 12:12:06 +0300 |
---|---|---|
committer | thegeorg <[email protected]> | 2022-05-11 12:12:06 +0300 |
commit | 62f93da087b2fec0f89979fd11ac4d754ca36253 (patch) | |
tree | 67bf8ceb55e2d079f3575f9a7373584ad407d2a5 /contrib/restricted/aws/aws-c-common/source/json.c | |
parent | 8d55620139d4309265409767f873ba83fe046418 (diff) |
Update aws-c-common and aws-c-io
* Update `contrib/restricted/aws/aws-c-io` to 0.11.0
* Backport cJSON symbol renaming logic from aws-sdk-cpp upstream
ref:396829235a01ed34888651ee38ebd76c95510d6b
Diffstat (limited to 'contrib/restricted/aws/aws-c-common/source/json.c')
-rw-r--r-- | contrib/restricted/aws/aws-c-common/source/json.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/contrib/restricted/aws/aws-c-common/source/json.c b/contrib/restricted/aws/aws-c-common/source/json.c new file mode 100644 index 00000000000..0f1b810be56 --- /dev/null +++ b/contrib/restricted/aws/aws-c-common/source/json.c @@ -0,0 +1,344 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/common/byte_buf.h> +#include <aws/common/string.h> + +#include <aws/common/json.h> + +#include <aws/common/external/cJSON.h> + +static struct aws_allocator *s_aws_json_module_allocator = NULL; +static bool s_aws_json_module_initialized = false; + +struct aws_json_value *aws_json_value_new_string(struct aws_allocator *allocator, struct aws_byte_cursor string) { + struct aws_string *tmp = aws_string_new_from_cursor((struct aws_allocator *)allocator, &string); + void *ret_val = cJSON_CreateString(aws_string_c_str(tmp)); + aws_string_destroy_secure(tmp); + return ret_val; +} + +struct aws_json_value *aws_json_value_new_number(struct aws_allocator *allocator, double number) { + (void)allocator; // prevent warnings over unused parameter + return (void *)cJSON_CreateNumber(number); +} + +struct aws_json_value *aws_json_value_new_array(struct aws_allocator *allocator) { + (void)allocator; // prevent warnings over unused parameter + return (void *)cJSON_CreateArray(); +} + +struct aws_json_value *aws_json_value_new_boolean(struct aws_allocator *allocator, bool boolean) { + (void)allocator; // prevent warnings over unused parameter + return (void *)cJSON_CreateBool(boolean); +} + +struct aws_json_value *aws_json_value_new_null(struct aws_allocator *allocator) { + (void)allocator; // prevent warnings over unused parameter + return (void *)cJSON_CreateNull(); +} + +struct aws_json_value *aws_json_value_new_object(struct aws_allocator *allocator) { + (void)allocator; // prevent warnings over unused parameter + return (void *)cJSON_CreateObject(); +} + +int aws_json_value_get_string(const struct aws_json_value *value, struct aws_byte_cursor *output) { + struct cJSON *cjson = (struct cJSON *)value; + if (!cJSON_IsString(cjson)) { + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + *output = aws_byte_cursor_from_c_str(cJSON_GetStringValue(cjson)); + return AWS_OP_SUCCESS; +} + +int aws_json_value_get_number(const struct aws_json_value *value, double *output) { + struct cJSON *cjson = (struct cJSON *)value; + if (!cJSON_IsNumber(cjson)) { + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + *output = cjson->valuedouble; + return AWS_OP_SUCCESS; +} + +int aws_json_value_get_boolean(const struct aws_json_value *value, bool *output) { + struct cJSON *cjson = (struct cJSON *)value; + if (!cJSON_IsBool(cjson)) { + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + *output = cjson->type == cJSON_True; + return AWS_OP_SUCCESS; +} + +int aws_json_value_add_to_object( + struct aws_json_value *object, + struct aws_byte_cursor key, + struct aws_json_value *value) { + + int result = AWS_OP_ERR; + struct aws_string *tmp = aws_string_new_from_cursor(s_aws_json_module_allocator, &key); + + struct cJSON *cjson = (struct cJSON *)object; + if (!cJSON_IsObject(cjson)) { + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + goto done; + } + + struct cJSON *cjson_value = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson_value)) { + result = aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + goto done; + } + if (cJSON_HasObjectItem(cjson, aws_string_c_str(tmp))) { + goto done; + } + + cJSON_AddItemToObject(cjson, aws_string_c_str(tmp), cjson_value); + result = AWS_OP_SUCCESS; + +done: + aws_string_destroy_secure(tmp); + return result; +} + +struct aws_json_value *aws_json_value_get_from_object(const struct aws_json_value *object, struct aws_byte_cursor key) { + + void *return_value = NULL; + struct aws_string *tmp = aws_string_new_from_cursor(s_aws_json_module_allocator, &key); + + struct cJSON *cjson = (struct cJSON *)object; + if (!cJSON_IsObject(cjson)) { + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + goto done; + } + if (!cJSON_HasObjectItem(cjson, aws_string_c_str(tmp))) { + goto done; + } + + return_value = (void *)cJSON_GetObjectItem(cjson, aws_string_c_str(tmp)); + +done: + aws_string_destroy_secure(tmp); + return return_value; +} + +bool aws_json_value_has_key(const struct aws_json_value *object, struct aws_byte_cursor key) { + + struct aws_string *tmp = aws_string_new_from_cursor(s_aws_json_module_allocator, &key); + bool result = false; + + struct cJSON *cjson = (struct cJSON *)object; + if (!cJSON_IsObject(cjson)) { + goto done; + } + if (!cJSON_HasObjectItem(cjson, aws_string_c_str(tmp))) { + goto done; + } + result = true; + +done: + aws_string_destroy_secure(tmp); + return result; +} + +int aws_json_value_remove_from_object(struct aws_json_value *object, struct aws_byte_cursor key) { + + int result = AWS_OP_ERR; + struct aws_string *tmp = aws_string_new_from_cursor(s_aws_json_module_allocator, &key); + + struct cJSON *cjson = (struct cJSON *)object; + if (!cJSON_IsObject(cjson)) { + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + goto done; + } + if (!cJSON_HasObjectItem(cjson, aws_string_c_str(tmp))) { + goto done; + } + + cJSON_DeleteItemFromObject(cjson, aws_string_c_str(tmp)); + result = AWS_OP_SUCCESS; + +done: + aws_string_destroy_secure(tmp); + return result; +} + +int aws_json_value_add_array_element(struct aws_json_value *array, const struct aws_json_value *value) { + + struct cJSON *cjson = (struct cJSON *)array; + if (!cJSON_IsArray(cjson)) { + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + + struct cJSON *cjson_value = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson_value)) { + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + + cJSON_AddItemToArray(cjson, cjson_value); + return AWS_OP_SUCCESS; +} + +struct aws_json_value *aws_json_get_array_element(const struct aws_json_value *array, size_t index) { + + struct cJSON *cjson = (struct cJSON *)array; + if (!cJSON_IsArray(cjson)) { + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + return NULL; + } + + if (index > (size_t)cJSON_GetArraySize(cjson)) { + aws_raise_error(AWS_ERROR_INVALID_INDEX); + return NULL; + } + + return (void *)cJSON_GetArrayItem(cjson, (int)index); +} + +size_t aws_json_get_array_size(const struct aws_json_value *array) { + struct cJSON *cjson = (struct cJSON *)array; + if (!cJSON_IsArray(cjson)) { + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + return 0; + } + return cJSON_GetArraySize(cjson); +} + +int aws_json_value_remove_array_element(struct aws_json_value *array, size_t index) { + + struct cJSON *cjson = (struct cJSON *)array; + if (!cJSON_IsArray(cjson)) { + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + + if (index > (size_t)cJSON_GetArraySize(cjson)) { + return aws_raise_error(AWS_ERROR_INVALID_INDEX); + } + + cJSON_DeleteItemFromArray(cjson, (int)index); + return AWS_OP_SUCCESS; +} + +bool aws_json_value_is_string(const struct aws_json_value *value) { + struct cJSON *cjson = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson)) { + return false; + } + return cJSON_IsString(cjson); +} + +bool aws_json_value_is_number(const struct aws_json_value *value) { + struct cJSON *cjson = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson)) { + return false; + } + return cJSON_IsNumber(cjson); +} + +bool aws_json_value_is_array(const struct aws_json_value *value) { + struct cJSON *cjson = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson)) { + return false; + } + return cJSON_IsArray(cjson); +} + +bool aws_json_value_is_boolean(const struct aws_json_value *value) { + struct cJSON *cjson = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson)) { + return false; + } + return cJSON_IsBool(cjson); +} + +bool aws_json_value_is_null(const struct aws_json_value *value) { + struct cJSON *cjson = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson)) { + return false; + } + return cJSON_IsNull(cjson); +} + +bool aws_json_value_is_object(const struct aws_json_value *value) { + struct cJSON *cjson = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson)) { + return false; + } + return cJSON_IsObject(cjson); +} + +static void *s_aws_cJSON_alloc(size_t sz) { + return aws_mem_acquire(s_aws_json_module_allocator, sz); +} + +static void s_aws_cJSON_free(void *ptr) { + aws_mem_release(s_aws_json_module_allocator, ptr); +} + +void aws_json_module_init(struct aws_allocator *allocator) { + if (!s_aws_json_module_initialized) { + s_aws_json_module_allocator = allocator; + struct cJSON_Hooks allocation_hooks = {.malloc_fn = s_aws_cJSON_alloc, .free_fn = s_aws_cJSON_free}; + cJSON_InitHooks(&allocation_hooks); + s_aws_json_module_initialized = true; + } +} + +void aws_json_module_cleanup(void) { + if (s_aws_json_module_initialized) { + s_aws_json_module_allocator = NULL; + s_aws_json_module_initialized = false; + } +} + +void aws_json_value_destroy(struct aws_json_value *value) { + struct cJSON *cjson = (struct cJSON *)value; + if (!cJSON_IsInvalid(cjson)) { + cJSON_Delete(cjson); + } +} + +int aws_byte_buf_append_json_string(const struct aws_json_value *value, struct aws_byte_buf *output) { + struct cJSON *cjson = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson)) { + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + + char *tmp = cJSON_PrintUnformatted(cjson); + if (tmp == NULL) { + return AWS_OP_ERR; + } + + // Append the text to the byte buffer + struct aws_byte_cursor tmp_cursor = aws_byte_cursor_from_c_str(tmp); + int return_val = aws_byte_buf_append_dynamic_secure(output, &tmp_cursor); + s_aws_cJSON_free(tmp); // free the char* now that we do not need it + return return_val; +} + +int aws_byte_buf_append_json_string_formatted(const struct aws_json_value *value, struct aws_byte_buf *output) { + struct cJSON *cjson = (struct cJSON *)value; + if (cJSON_IsInvalid(cjson)) { + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + + char *tmp = cJSON_Print(cjson); + if (tmp == NULL) { + return AWS_OP_ERR; + } + + // Append the text to the byte buffer + struct aws_byte_cursor tmp_cursor = aws_byte_cursor_from_c_str(tmp); + int return_val = aws_byte_buf_append_dynamic_secure(output, &tmp_cursor); + s_aws_cJSON_free(tmp); // free the char* now that we do not need it + return return_val; +} + +struct aws_json_value *aws_json_value_new_from_string(struct aws_allocator *allocator, struct aws_byte_cursor string) { + struct aws_string *tmp = aws_string_new_from_cursor((struct aws_allocator *)allocator, &string); + struct cJSON *cjson = cJSON_Parse(aws_string_c_str(tmp)); + aws_string_destroy_secure(tmp); + return (void *)cjson; +} |