diff options
Diffstat (limited to 'fluent-bit/lib/avro/src/datum_value.c')
-rw-r--r-- | fluent-bit/lib/avro/src/datum_value.c | 784 |
1 files changed, 784 insertions, 0 deletions
diff --git a/fluent-bit/lib/avro/src/datum_value.c b/fluent-bit/lib/avro/src/datum_value.c new file mode 100644 index 000000000..a4fa55a0c --- /dev/null +++ b/fluent-bit/lib/avro/src/datum_value.c @@ -0,0 +1,784 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include <avro/platform.h> +#include <stdlib.h> +#include <string.h> + +#include "avro/allocation.h" +#include "avro/basics.h" +#include "avro/errors.h" +#include "avro/legacy.h" +#include "avro/refcount.h" +#include "avro/schema.h" +#include "avro/value.h" +#include "avro_private.h" + +extern avro_value_iface_t AVRO_DATUM_VALUE_CLASS; + +avro_value_iface_t * +avro_datum_class(void) +{ + return &AVRO_DATUM_VALUE_CLASS; +} + +int +avro_datum_as_value(avro_value_t *value, avro_datum_t src) +{ + value->iface = &AVRO_DATUM_VALUE_CLASS; + value->self = avro_datum_incref(src); + return 0; +} + +static int +avro_datum_as_child_value(avro_value_t *value, avro_datum_t src) +{ + value->iface = &AVRO_DATUM_VALUE_CLASS; + value->self = src; + return 0; +} + +static void +avro_datum_value_incref(avro_value_t *value) +{ + avro_datum_t self = (avro_datum_t) value->self; + avro_datum_incref(self); +} + +static void +avro_datum_value_decref(avro_value_t *value) +{ + avro_datum_t self = (avro_datum_t) value->self; + avro_datum_decref(self); +} + +static int +avro_datum_value_reset(const avro_value_iface_t *iface, void *vself) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_datum_reset(self); +} + +static avro_type_t +avro_datum_value_get_type(const avro_value_iface_t *iface, const void *vself) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; +#ifdef _WIN32 +#pragma message("#warning: Bug: EINVAL is not of type avro_type_t.") +#else +#warning "Bug: EINVAL is not of type avro_type_t." +#endif + /* We shouldn't use EINVAL as the return value to + * check_param(), because EINVAL (= 22) is not a valid enum + * avro_type_t. This is a structural issue -- we would need a + * different interface on all the get_type functions to fix + * this. For now, suppressing the error by casting EINVAL to + * (avro_type_t) so the code compiles under C++. + */ + check_param((avro_type_t) EINVAL, self, "datum instance"); + return avro_typeof(self); +} + +static avro_schema_t +avro_datum_value_get_schema(const avro_value_iface_t *iface, const void *vself) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(NULL, self, "datum instance"); + return avro_datum_get_schema(self); +} + + +static int +avro_datum_value_get_boolean(const avro_value_iface_t *iface, + const void *vself, int *out) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + int8_t value; + check(rval, avro_boolean_get(self, &value)); + *out = value; + return 0; +} + +static int +avro_datum_value_get_bytes(const avro_value_iface_t *iface, + const void *vself, const void **buf, size_t *size) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + char *bytes; + int64_t sz; + check(rval, avro_bytes_get(self, &bytes, &sz)); + if (buf != NULL) { + *buf = (const void *) bytes; + } + if (size != NULL) { + *size = sz; + } + return 0; +} + +static int +avro_datum_value_grab_bytes(const avro_value_iface_t *iface, + const void *vself, avro_wrapped_buffer_t *dest) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + char *bytes; + int64_t sz; + check(rval, avro_bytes_get(self, &bytes, &sz)); + + /* nothing clever, just make a copy */ + return avro_wrapped_buffer_new_copy(dest, bytes, sz); +} + +static int +avro_datum_value_get_double(const avro_value_iface_t *iface, + const void *vself, double *out) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + double value; + check(rval, avro_double_get(self, &value)); + *out = value; + return 0; +} + +static int +avro_datum_value_get_float(const avro_value_iface_t *iface, + const void *vself, float *out) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + float value; + check(rval, avro_float_get(self, &value)); + *out = value; + return 0; +} + +static int +avro_datum_value_get_int(const avro_value_iface_t *iface, + const void *vself, int32_t *out) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + int32_t value; + check(rval, avro_int32_get(self, &value)); + *out = value; + return 0; +} + +static int +avro_datum_value_get_long(const avro_value_iface_t *iface, + const void *vself, int64_t *out) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + int64_t value; + check(rval, avro_int64_get(self, &value)); + *out = value; + return 0; +} + +static int +avro_datum_value_get_null(const avro_value_iface_t *iface, + const void *vself) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, is_avro_null(self), "datum instance"); + return 0; +} + +static int +avro_datum_value_get_string(const avro_value_iface_t *iface, + const void *vself, const char **str, size_t *size) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + char *value; + check(rval, avro_string_get(self, &value)); + if (str != NULL) { + *str = (const char *) value; + } + if (size != NULL) { + *size = strlen(value)+1; + } + return 0; +} + +static int +avro_datum_value_grab_string(const avro_value_iface_t *iface, + const void *vself, avro_wrapped_buffer_t *dest) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + char *str; + size_t sz; + check(rval, avro_string_get(self, &str)); + sz = strlen(str); + + /* nothing clever, just make a copy */ + /* sz doesn't contain NUL terminator */ + return avro_wrapped_buffer_new_copy(dest, str, sz+1); +} + +static int +avro_datum_value_get_enum(const avro_value_iface_t *iface, + const void *vself, int *out) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, is_avro_enum(self), "datum instance"); + *out = avro_enum_get(self); + return 0; +} + +static int +avro_datum_value_get_fixed(const avro_value_iface_t *iface, + const void *vself, const void **buf, size_t *size) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + char *bytes; + int64_t sz; + check(rval, avro_fixed_get(self, &bytes, &sz)); + if (buf != NULL) { + *buf = (const void *) bytes; + } + if (size != NULL) { + *size = sz; + } + return 0; +} + +static int +avro_datum_value_grab_fixed(const avro_value_iface_t *iface, + const void *vself, avro_wrapped_buffer_t *dest) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + char *bytes; + int64_t sz; + check(rval, avro_fixed_get(self, &bytes, &sz)); + + /* nothing clever, just make a copy */ + return avro_wrapped_buffer_new_copy(dest, bytes, sz); +} + + +static int +avro_datum_value_set_boolean(const avro_value_iface_t *iface, + void *vself, int val) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_boolean_set(self, val); +} + +static int +avro_datum_value_set_bytes(const avro_value_iface_t *iface, + void *vself, void *buf, size_t size) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_bytes_set(self, (const char *) buf, size); +} + +static int +avro_datum_value_give_bytes(const avro_value_iface_t *iface, + void *vself, avro_wrapped_buffer_t *buf) +{ + /* + * We actually can't use avro_givebytes_set, since it can't + * handle the extra free_ud parameter. Ah well, this is + * deprecated, so go ahead and make a copy. + */ + + int rval = avro_datum_value_set_bytes + (iface, vself, (void *) buf->buf, buf->size); + avro_wrapped_buffer_free(buf); + return rval; +} + +static int +avro_datum_value_set_double(const avro_value_iface_t *iface, + void *vself, double val) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_double_set(self, val); +} + +static int +avro_datum_value_set_float(const avro_value_iface_t *iface, + void *vself, float val) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_float_set(self, val); +} + +static int +avro_datum_value_set_int(const avro_value_iface_t *iface, + void *vself, int32_t val) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_int32_set(self, val); +} + +static int +avro_datum_value_set_long(const avro_value_iface_t *iface, + void *vself, int64_t val) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_int64_set(self, val); +} + +static int +avro_datum_value_set_null(const avro_value_iface_t *iface, void *vself) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, is_avro_null(self), "datum instance"); + return 0; +} + +static int +avro_datum_value_set_string(const avro_value_iface_t *iface, + void *vself, const char *str) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_string_set(self, str); +} + +static int +avro_datum_value_set_string_len(const avro_value_iface_t *iface, + void *vself, const char *str, size_t size) +{ + AVRO_UNUSED(iface); + AVRO_UNUSED(size); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_string_set(self, str); +} + +static int +avro_datum_value_give_string_len(const avro_value_iface_t *iface, + void *vself, avro_wrapped_buffer_t *buf) +{ + /* + * We actually can't use avro_givestring_set, since it can't + * handle the extra free_ud parameter. Ah well, this is + * deprecated, so go ahead and make a copy. + */ + + int rval = avro_datum_value_set_string_len + (iface, vself, (char *) buf->buf, buf->size-1); + avro_wrapped_buffer_free(buf); + return rval; +} + +static int +avro_datum_value_set_enum(const avro_value_iface_t *iface, + void *vself, int val) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_enum_set(self, val); +} + +static int +avro_datum_value_set_fixed(const avro_value_iface_t *iface, + void *vself, void *buf, size_t size) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + return avro_fixed_set(self, (const char *) buf, size); +} + +static int +avro_datum_value_give_fixed(const avro_value_iface_t *iface, + void *vself, avro_wrapped_buffer_t *buf) +{ + /* + * We actually can't use avro_givefixed_set, since it can't + * handle the extra free_ud parameter. Ah well, this is + * deprecated, so go ahead and make a copy. + */ + + int rval = avro_datum_value_set_fixed + (iface, vself, (void *) buf->buf, buf->size); + avro_wrapped_buffer_free(buf); + return rval; +} + + +static int +avro_datum_value_get_size(const avro_value_iface_t *iface, + const void *vself, size_t *size) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + if (is_avro_array(self)) { + *size = avro_array_size(self); + return 0; + } + + if (is_avro_map(self)) { + *size = avro_map_size(self); + return 0; + } + + if (is_avro_record(self)) { + avro_schema_t schema = avro_datum_get_schema(self); + *size = avro_schema_record_size(schema); + return 0; + } + + avro_set_error("Can only get size of array, map, or record, %d", avro_typeof(self)); + return EINVAL; +} + +static int +avro_datum_value_get_by_index(const avro_value_iface_t *iface, + const void *vself, size_t index, + avro_value_t *child, const char **name) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + avro_datum_t child_datum; + + if (is_avro_array(self)) { + check(rval, avro_array_get(self, index, &child_datum)); + return avro_datum_as_child_value(child, child_datum); + } + + if (is_avro_map(self)) { + const char *real_key; + check(rval, avro_map_get_key(self, index, &real_key)); + if (name != NULL) { + *name = real_key; + } + check(rval, avro_map_get(self, real_key, &child_datum)); + return avro_datum_as_child_value(child, child_datum); + } + + if (is_avro_record(self)) { + avro_schema_t schema = avro_datum_get_schema(self); + const char *field_name = + avro_schema_record_field_name(schema, index); + if (field_name == NULL) { + return EINVAL; + } + if (name != NULL) { + *name = field_name; + } + check(rval, avro_record_get(self, field_name, &child_datum)); + return avro_datum_as_child_value(child, child_datum); + } + + avro_set_error("Can only get by index from array, map, or record"); + return EINVAL; +} + +static int +avro_datum_value_get_by_name(const avro_value_iface_t *iface, + const void *vself, const char *name, + avro_value_t *child, size_t *index) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + int rval; + avro_datum_t child_datum; + + if (is_avro_map(self)) { + if (index != NULL) { + int real_index; + check(rval, avro_map_get_index(self, name, &real_index)); + *index = real_index; + } + + check(rval, avro_map_get(self, name, &child_datum)); + return avro_datum_as_child_value(child, child_datum); + } + + if (is_avro_record(self)) { + if (index != NULL) { + avro_schema_t schema = avro_datum_get_schema(self); + *index = avro_schema_record_field_get_index(schema, name); + } + + check(rval, avro_record_get(self, name, &child_datum)); + return avro_datum_as_child_value(child, child_datum); + } + + avro_set_error("Can only get by name from map or record"); + return EINVAL; +} + +static int +avro_datum_value_get_discriminant(const avro_value_iface_t *iface, + const void *vself, int *out) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + if (!is_avro_union(self)) { + avro_set_error("Can only get discriminant of union"); + return EINVAL; + } + + *out = avro_union_discriminant(self); + return 0; +} + +static int +avro_datum_value_get_current_branch(const avro_value_iface_t *iface, + const void *vself, avro_value_t *branch) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + if (!is_avro_union(self)) { + avro_set_error("Can only get current branch of union"); + return EINVAL; + } + + avro_datum_t child_datum = avro_union_current_branch(self); + return avro_datum_as_child_value(branch, child_datum); +} + + +static int +avro_datum_value_append(const avro_value_iface_t *iface, + void *vself, avro_value_t *child_out, size_t *new_index) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + if (!is_avro_array(self)) { + avro_set_error("Can only append to array"); + return EINVAL; + } + + int rval; + + avro_schema_t array_schema = avro_datum_get_schema(self); + avro_schema_t child_schema = avro_schema_array_items(array_schema); + avro_datum_t child_datum = avro_datum_from_schema(child_schema); + if (child_datum == NULL) { + return ENOMEM; + } + + rval = avro_array_append_datum(self, child_datum); + avro_datum_decref(child_datum); + if (rval != 0) { + return rval; + } + + if (new_index != NULL) { + *new_index = avro_array_size(self) - 1; + } + return avro_datum_as_child_value(child_out, child_datum); +} + +static int +avro_datum_value_add(const avro_value_iface_t *iface, + void *vself, const char *key, + avro_value_t *child, size_t *index, int *is_new) +{ + AVRO_UNUSED(iface); + avro_datum_t self = (avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + if (!is_avro_map(self)) { + avro_set_error("Can only add to map"); + return EINVAL; + } + + int rval; + avro_datum_t child_datum; + + if (avro_map_get(self, key, &child_datum) == 0) { + /* key already exists */ + if (is_new != NULL) { + *is_new = 0; + } + if (index != NULL) { + int real_index; + avro_map_get_index(self, key, &real_index); + *index = real_index; + } + return avro_datum_as_child_value(child, child_datum); + } + + /* key is new */ + avro_schema_t map_schema = avro_datum_get_schema(self); + avro_schema_t child_schema = avro_schema_map_values(map_schema); + child_datum = avro_datum_from_schema(child_schema); + if (child_datum == NULL) { + return ENOMEM; + } + + rval = avro_map_set(self, key, child_datum); + avro_datum_decref(child_datum); + if (rval != 0) { + return rval; + } + + if (is_new != NULL) { + *is_new = 1; + } + if (index != NULL) { + *index = avro_map_size(self) - 1; + } + + return avro_datum_as_child_value(child, child_datum); +} + +static int +avro_datum_value_set_branch(const avro_value_iface_t *iface, + void *vself, int discriminant, + avro_value_t *branch) +{ + AVRO_UNUSED(iface); + const avro_datum_t self = (const avro_datum_t) vself; + check_param(EINVAL, self, "datum instance"); + + if (!is_avro_union(self)) { + avro_set_error("Can only set branch of union"); + return EINVAL; + } + + int rval; + avro_datum_t child_datum; + check(rval, avro_union_set_discriminant(self, discriminant, &child_datum)); + return avro_datum_as_child_value(branch, child_datum); +} + + +avro_value_iface_t AVRO_DATUM_VALUE_CLASS = +{ + /* "class" methods */ + NULL, /* incref */ + NULL, /* decref */ + /* general "instance" methods */ + avro_datum_value_incref, + avro_datum_value_decref, + avro_datum_value_reset, + avro_datum_value_get_type, + avro_datum_value_get_schema, + /* primitive getters */ + avro_datum_value_get_boolean, + avro_datum_value_get_bytes, + avro_datum_value_grab_bytes, + avro_datum_value_get_double, + avro_datum_value_get_float, + avro_datum_value_get_int, + avro_datum_value_get_long, + avro_datum_value_get_null, + avro_datum_value_get_string, + avro_datum_value_grab_string, + avro_datum_value_get_enum, + avro_datum_value_get_fixed, + avro_datum_value_grab_fixed, + /* primitive setters */ + avro_datum_value_set_boolean, + avro_datum_value_set_bytes, + avro_datum_value_give_bytes, + avro_datum_value_set_double, + avro_datum_value_set_float, + avro_datum_value_set_int, + avro_datum_value_set_long, + avro_datum_value_set_null, + avro_datum_value_set_string, + avro_datum_value_set_string_len, + avro_datum_value_give_string_len, + avro_datum_value_set_enum, + avro_datum_value_set_fixed, + avro_datum_value_give_fixed, + /* compound getters */ + avro_datum_value_get_size, + avro_datum_value_get_by_index, + avro_datum_value_get_by_name, + avro_datum_value_get_discriminant, + avro_datum_value_get_current_branch, + /* compound setters */ + avro_datum_value_append, + avro_datum_value_add, + avro_datum_value_set_branch +}; |