diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:54:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:54:44 +0000 |
commit | 836b47cb7e99a977c5a23b059ca1d0b5065d310e (patch) | |
tree | 1604da8f482d02effa033c94a84be42bc0c848c3 /fluent-bit/lib/avro/src/generic.c | |
parent | Releasing debian version 1.44.3-2. (diff) | |
download | netdata-836b47cb7e99a977c5a23b059ca1d0b5065d310e.tar.xz netdata-836b47cb7e99a977c5a23b059ca1d0b5065d310e.zip |
Merging upstream version 1.46.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/lib/avro/src/generic.c')
-rw-r--r-- | fluent-bit/lib/avro/src/generic.c | 3707 |
1 files changed, 0 insertions, 3707 deletions
diff --git a/fluent-bit/lib/avro/src/generic.c b/fluent-bit/lib/avro/src/generic.c deleted file mode 100644 index e614eb3f8..000000000 --- a/fluent-bit/lib/avro/src/generic.c +++ /dev/null @@ -1,3707 +0,0 @@ -/* - * 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/data.h" -#include "avro/errors.h" -#include "avro/generic.h" -#include "avro/refcount.h" -#include "avro/schema.h" -#include "avro/value.h" -#include "avro_generic_internal.h" -#include "avro_private.h" - - -/*----------------------------------------------------------------------- - * Forward definitions - */ - -typedef struct avro_generic_link_value_iface avro_generic_link_value_iface_t; - -typedef struct memoize_state_t { - avro_memoize_t mem; - avro_generic_link_value_iface_t *links; -} memoize_state_t; - -static avro_generic_value_iface_t * -avro_generic_class_from_schema_memoized(avro_schema_t schema, - memoize_state_t *state); - - -/*----------------------------------------------------------------------- - * Generic support functions - */ - -int -avro_generic_value_new(avro_value_iface_t *iface, avro_value_t *dest) -{ - int rval; - avro_generic_value_iface_t *giface = - container_of(iface, avro_generic_value_iface_t, parent); - size_t instance_size = avro_value_instance_size(giface); - void *self = avro_malloc(instance_size + sizeof(volatile int)); - if (self == NULL) { - avro_set_error(strerror(ENOMEM)); - dest->iface = NULL; - dest->self = NULL; - return ENOMEM; - } - - volatile int *refcount = (volatile int *) self; - self = (char *) self + sizeof(volatile int); - - *refcount = 1; - rval = avro_value_init(giface, self); - if (rval != 0) { - avro_free(self, instance_size); - dest->iface = NULL; - dest->self = NULL; - return rval; - } - - dest->iface = avro_value_iface_incref(&giface->parent); - dest->self = self; - return 0; -} - -static void -avro_generic_value_free(const avro_value_iface_t *iface, void *self) -{ - if (self != NULL) { - const avro_generic_value_iface_t *giface = - container_of(iface, avro_generic_value_iface_t, parent); - size_t instance_size = avro_value_instance_size(giface); - avro_value_done(giface, self); - self = (char *) self - sizeof(volatile int); - avro_free(self, instance_size + sizeof(volatile int)); - } -} - -static void -avro_generic_value_incref(avro_value_t *value) -{ - /* - * This only works if you pass in the top-level value. - */ - - volatile int *refcount = (volatile int *) ((char *) value->self - sizeof(volatile int)); - avro_refcount_inc(refcount); -} - -static void -avro_generic_value_decref(avro_value_t *value) -{ - /* - * This only works if you pass in the top-level value. - */ - - volatile int *refcount = (volatile int *) ((char *) value->self - sizeof(volatile int)); - if (avro_refcount_dec(refcount)) { - avro_generic_value_free(value->iface, value->self); - } -} - - -/*----------------------------------------------------------------------- - * Recursive schemas - */ - -/* - * Recursive schemas are handled specially; the value implementation for - * an AVRO_LINK schema is simply a wrapper around the value - * implementation for the link's target schema. The value methods all - * delegate to the wrapped implementation. - * - * We don't set the target_iface pointer when the link implementation is - * first created, since we might not have finished creating the - * implementation for the target schema. (We create the implementations - * for child schemas depth-first, so the target schema's implementation - * won't be done until all of its descendants — including the link - * schema — have been instantiated.) - * - * So anyway, we set the target_iface pointer to NULL at first. And - * then in a fix-up stage, once all of the non-link schemas have been - * instantiated, we go through and set the target_iface pointers for any - * link schemas we encountered. - */ - -struct avro_generic_link_value_iface { - avro_generic_value_iface_t parent; - - /** The reference count for this interface. */ - volatile int refcount; - - /** The schema for this interface. */ - avro_schema_t schema; - - /** The target's implementation. */ - avro_generic_value_iface_t *target_giface; - - /** - * A pointer to the “next” link interface that we've had to - * create. We use this as we're creating the overall top-level - * value interface to keep track of which ones we have to fix up - * afterwards. - */ - avro_generic_link_value_iface_t *next; -}; - - -static avro_value_iface_t * -avro_generic_link_incref_iface(avro_value_iface_t *viface) -{ - avro_generic_link_value_iface_t *iface = - container_of(viface, avro_generic_link_value_iface_t, parent); - avro_refcount_inc(&iface->refcount); - return viface; -} - -static void -avro_generic_link_decref_iface(avro_value_iface_t *viface) -{ - avro_generic_link_value_iface_t *iface = - container_of(viface, avro_generic_link_value_iface_t, parent.parent); - - if (avro_refcount_dec(&iface->refcount)) { - /* We don't keep a reference to the target - * implementation, since that would give us a reference - * cycle. */ - /* We do however keep a reference to the target - * schema, which we need to decrement before freeing - * the link */ - avro_schema_decref(iface->schema); - avro_freet(avro_generic_link_value_iface_t, iface); - } -} - - -static int -avro_generic_link_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_reset(self); -} - -static avro_type_t -avro_generic_link_get_type(const avro_value_iface_t *viface, const void *vself) -{ - AVRO_UNUSED(viface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_type(self); -} - -static avro_schema_t -avro_generic_link_get_schema(const avro_value_iface_t *viface, const void *vself) -{ - AVRO_UNUSED(viface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_schema(self); -} - -static int -avro_generic_link_get_boolean(const avro_value_iface_t *iface, - const void *vself, int *out) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_boolean(self, out); -} - -static int -avro_generic_link_get_bytes(const avro_value_iface_t *iface, - const void *vself, const void **buf, size_t *size) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_bytes(self, buf, size); -} - -static int -avro_generic_link_grab_bytes(const avro_value_iface_t *iface, - const void *vself, avro_wrapped_buffer_t *dest) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_grab_bytes(self, dest); -} - -static int -avro_generic_link_get_double(const avro_value_iface_t *iface, - const void *vself, double *out) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_double(self, out); -} - -static int -avro_generic_link_get_float(const avro_value_iface_t *iface, - const void *vself, float *out) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_float(self, out); -} - -static int -avro_generic_link_get_int(const avro_value_iface_t *iface, - const void *vself, int32_t *out) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_int(self, out); -} - -static int -avro_generic_link_get_long(const avro_value_iface_t *iface, - const void *vself, int64_t *out) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_long(self, out); -} - -static int -avro_generic_link_get_null(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_null(self); -} - -static int -avro_generic_link_get_string(const avro_value_iface_t *iface, - const void *vself, const char **str, size_t *size) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_string(self, str, size); -} - -static int -avro_generic_link_grab_string(const avro_value_iface_t *iface, - const void *vself, avro_wrapped_buffer_t *dest) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_grab_string(self, dest); -} - -static int -avro_generic_link_get_enum(const avro_value_iface_t *iface, - const void *vself, int *out) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_enum(self, out); -} - -static int -avro_generic_link_get_fixed(const avro_value_iface_t *iface, - const void *vself, const void **buf, size_t *size) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_fixed(self, buf, size); -} - -static int -avro_generic_link_grab_fixed(const avro_value_iface_t *iface, - const void *vself, avro_wrapped_buffer_t *dest) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_grab_fixed(self, dest); -} - -static int -avro_generic_link_set_boolean(const avro_value_iface_t *iface, - void *vself, int val) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_boolean(self, val); -} - -static int -avro_generic_link_set_bytes(const avro_value_iface_t *iface, - void *vself, void *buf, size_t size) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_bytes(self, buf, size); -} - -static int -avro_generic_link_give_bytes(const avro_value_iface_t *iface, - void *vself, avro_wrapped_buffer_t *buf) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_give_bytes(self, buf); -} - -static int -avro_generic_link_set_double(const avro_value_iface_t *iface, - void *vself, double val) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_double(self, val); -} - -static int -avro_generic_link_set_float(const avro_value_iface_t *iface, - void *vself, float val) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_float(self, val); -} - -static int -avro_generic_link_set_int(const avro_value_iface_t *iface, - void *vself, int32_t val) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_int(self, val); -} - -static int -avro_generic_link_set_long(const avro_value_iface_t *iface, - void *vself, int64_t val) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_long(self, val); -} - -static int -avro_generic_link_set_null(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_null(self); -} - -static int -avro_generic_link_set_string(const avro_value_iface_t *iface, - void *vself, const char *str) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_string(self, str); -} - -static int -avro_generic_link_set_string_len(const avro_value_iface_t *iface, - void *vself, const char *str, size_t size) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_string_len(self, str, size); -} - -static int -avro_generic_link_give_string_len(const avro_value_iface_t *iface, - void *vself, avro_wrapped_buffer_t *buf) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_give_string_len(self, buf); -} - -static int -avro_generic_link_set_enum(const avro_value_iface_t *iface, - void *vself, int val) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_enum(self, val); -} - -static int -avro_generic_link_set_fixed(const avro_value_iface_t *iface, - void *vself, void *buf, size_t size) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_fixed(self, buf, size); -} - -static int -avro_generic_link_give_fixed(const avro_value_iface_t *iface, - void *vself, avro_wrapped_buffer_t *buf) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_give_fixed(self, buf); -} - -static int -avro_generic_link_get_size(const avro_value_iface_t *iface, - const void *vself, size_t *size) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_size(self, size); -} - -static int -avro_generic_link_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_value_t *self = (const avro_value_t *) vself; - return avro_value_get_by_index(self, index, child, name); -} - -static int -avro_generic_link_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_value_t *self = (const avro_value_t *) vself; - return avro_value_get_by_name(self, name, child, index); -} - -static int -avro_generic_link_get_discriminant(const avro_value_iface_t *iface, - const void *vself, int *out) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_discriminant(self, out); -} - -static int -avro_generic_link_get_current_branch(const avro_value_iface_t *iface, - const void *vself, avro_value_t *branch) -{ - AVRO_UNUSED(iface); - const avro_value_t *self = (const avro_value_t *) vself; - return avro_value_get_current_branch(self, branch); -} - -static int -avro_generic_link_append(const avro_value_iface_t *iface, - void *vself, avro_value_t *child_out, - size_t *new_index) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_append(self, child_out, new_index); -} - -static int -avro_generic_link_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_value_t *self = (avro_value_t *) vself; - return avro_value_add(self, key, child, index, is_new); -} - -static int -avro_generic_link_set_branch(const avro_value_iface_t *iface, - void *vself, int discriminant, - avro_value_t *branch) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - return avro_value_set_branch(self, discriminant, branch); -} - -static size_t -avro_generic_link_instance_size(const avro_value_iface_t *viface) -{ - AVRO_UNUSED(viface); - return sizeof(avro_value_t); -} - -static int -avro_generic_link_init(const avro_value_iface_t *viface, void *vself) -{ - int rval; - - avro_generic_link_value_iface_t *iface = - container_of(viface, avro_generic_link_value_iface_t, parent.parent); - - avro_value_t *self = (avro_value_t *) vself; - ssize_t target_instance_size = - avro_value_instance_size(iface->target_giface); - if (target_instance_size < 0) { - return EINVAL; - } - - self->iface = &iface->target_giface->parent; - - if (target_instance_size == 0) { - self->self = NULL; - } else { - self->self = avro_malloc(target_instance_size); - if (self->self == NULL) { - return ENOMEM; - } - } - - rval = avro_value_init(iface->target_giface, self->self); - if (rval != 0) { - avro_free(self->self, target_instance_size); - } - return rval; -} - -static void -avro_generic_link_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_value_t *self = (avro_value_t *) vself; - avro_generic_value_iface_t *target_giface = - container_of(self->iface, avro_generic_value_iface_t, parent); - size_t target_instance_size = avro_value_instance_size(target_giface); - avro_value_done(target_giface, self->self); - avro_free(self->self, target_instance_size); - self->iface = NULL; - self->self = NULL; -} - -static avro_generic_value_iface_t AVRO_GENERIC_LINK_CLASS = -{ - { - /* "class" methods */ - avro_generic_link_incref_iface, - avro_generic_link_decref_iface, - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_link_reset, - avro_generic_link_get_type, - avro_generic_link_get_schema, - /* primitive getters */ - avro_generic_link_get_boolean, - avro_generic_link_get_bytes, - avro_generic_link_grab_bytes, - avro_generic_link_get_double, - avro_generic_link_get_float, - avro_generic_link_get_int, - avro_generic_link_get_long, - avro_generic_link_get_null, - avro_generic_link_get_string, - avro_generic_link_grab_string, - avro_generic_link_get_enum, - avro_generic_link_get_fixed, - avro_generic_link_grab_fixed, - /* primitive setters */ - avro_generic_link_set_boolean, - avro_generic_link_set_bytes, - avro_generic_link_give_bytes, - avro_generic_link_set_double, - avro_generic_link_set_float, - avro_generic_link_set_int, - avro_generic_link_set_long, - avro_generic_link_set_null, - avro_generic_link_set_string, - avro_generic_link_set_string_len, - avro_generic_link_give_string_len, - avro_generic_link_set_enum, - avro_generic_link_set_fixed, - avro_generic_link_give_fixed, - /* compound getters */ - avro_generic_link_get_size, - avro_generic_link_get_by_index, - avro_generic_link_get_by_name, - avro_generic_link_get_discriminant, - avro_generic_link_get_current_branch, - /* compound setters */ - avro_generic_link_append, - avro_generic_link_add, - avro_generic_link_set_branch - }, - avro_generic_link_instance_size, - avro_generic_link_init, - avro_generic_link_done -}; - -static avro_generic_link_value_iface_t * -avro_generic_link_class(avro_schema_t schema) -{ - if (!is_avro_link(schema)) { - avro_set_error("Expected link schema"); - return NULL; - } - - avro_generic_link_value_iface_t *iface = - (avro_generic_link_value_iface_t *) avro_new(avro_generic_link_value_iface_t); - if (iface == NULL) { - return NULL; - } - - iface->parent = AVRO_GENERIC_LINK_CLASS; - iface->refcount = 1; - iface->schema = avro_schema_incref(schema); - iface->next = NULL; - return iface; -} - - -/*----------------------------------------------------------------------- - * boolean - */ - -static int -avro_generic_boolean_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - int *self = (int *) vself; - *self = 0; - return 0; -} - -static avro_type_t -avro_generic_boolean_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_BOOLEAN; -} - -static avro_schema_t -avro_generic_boolean_get_schema(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return avro_schema_boolean(); -} - -static int -avro_generic_boolean_get(const avro_value_iface_t *iface, - const void *vself, int *out) -{ - AVRO_UNUSED(iface); - const int *self = (const int *) vself; - *out = *self; - return 0; -} - -static int -avro_generic_boolean_set(const avro_value_iface_t *iface, - void *vself, int val) -{ - AVRO_UNUSED(iface); - int *self = (int *) vself; - *self = val; - return 0; -} - -static size_t -avro_generic_boolean_instance_size(const avro_value_iface_t *iface) -{ - AVRO_UNUSED(iface); - return sizeof(int); -} - -static int -avro_generic_boolean_init(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - int *self = (int *) vself; - *self = 0; - return 0; -} - -static void -avro_generic_boolean_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); -} - -static avro_generic_value_iface_t AVRO_GENERIC_BOOLEAN_CLASS = -{ - { - /* "class" methods */ - NULL, /* incref_iface */ - NULL, /* decref_iface */ - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_boolean_reset, - avro_generic_boolean_get_type, - avro_generic_boolean_get_schema, - /* primitive getters */ - avro_generic_boolean_get, - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - avro_generic_boolean_set, - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_boolean_instance_size, - avro_generic_boolean_init, - avro_generic_boolean_done -}; - -avro_value_iface_t * -avro_generic_boolean_class(void) -{ - return &AVRO_GENERIC_BOOLEAN_CLASS.parent; -} - -int -avro_generic_boolean_new(avro_value_t *value, int val) -{ - int rval; - check(rval, avro_generic_value_new(&AVRO_GENERIC_BOOLEAN_CLASS.parent, value)); - return avro_generic_boolean_set(value->iface, value->self, val); -} - -/*----------------------------------------------------------------------- - * bytes - */ - -static int -avro_generic_bytes_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_clear(self); - return 0; -} - -static avro_type_t -avro_generic_bytes_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_BYTES; -} - -static avro_schema_t -avro_generic_bytes_get_schema(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return avro_schema_bytes(); -} - -static int -avro_generic_bytes_get(const avro_value_iface_t *iface, - const void *vself, const void **buf, size_t *size) -{ - AVRO_UNUSED(iface); - const avro_raw_string_t *self = (const avro_raw_string_t *) vself; - if (buf != NULL) { - *buf = avro_raw_string_get(self); - } - if (size != NULL) { - *size = avro_raw_string_length(self); - } - return 0; -} - -static int -avro_generic_bytes_grab(const avro_value_iface_t *iface, - const void *vself, avro_wrapped_buffer_t *dest) -{ - AVRO_UNUSED(iface); - const avro_raw_string_t *self = (const avro_raw_string_t *) vself; - return avro_raw_string_grab(self, dest); -} - -static int -avro_generic_bytes_set(const avro_value_iface_t *iface, - void *vself, void *buf, size_t size) -{ - AVRO_UNUSED(iface); - check_param(EINVAL, buf != NULL, "bytes contents"); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_set_length(self, buf, size); - return 0; -} - -static int -avro_generic_bytes_give(const avro_value_iface_t *iface, - void *vself, avro_wrapped_buffer_t *buf) -{ - AVRO_UNUSED(iface); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_give(self, buf); - return 0; -} - -static size_t -avro_generic_bytes_instance_size(const avro_value_iface_t *iface) -{ - AVRO_UNUSED(iface); - return sizeof(avro_raw_string_t); -} - -static int -avro_generic_bytes_init(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_init(self); - return 0; -} - -static void -avro_generic_bytes_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_done(self); -} - -static avro_generic_value_iface_t AVRO_GENERIC_BYTES_CLASS = -{ - { - /* "class" methods */ - NULL, /* incref_iface */ - NULL, /* decref_iface */ - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_bytes_reset, - avro_generic_bytes_get_type, - avro_generic_bytes_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - avro_generic_bytes_get, - avro_generic_bytes_grab, - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - avro_generic_bytes_set, - avro_generic_bytes_give, - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_bytes_instance_size, - avro_generic_bytes_init, - avro_generic_bytes_done -}; - -avro_value_iface_t * -avro_generic_bytes_class(void) -{ - return &AVRO_GENERIC_BYTES_CLASS.parent; -} - -int -avro_generic_bytes_new(avro_value_t *value, void *buf, size_t size) -{ - int rval; - check(rval, avro_generic_value_new(&AVRO_GENERIC_BYTES_CLASS.parent, value)); - return avro_generic_bytes_set(value->iface, value->self, buf, size); -} - -/*----------------------------------------------------------------------- - * double - */ - -static int -avro_generic_double_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - double *self = (double *) vself; - *self = 0.0; - return 0; -} - -static avro_type_t -avro_generic_double_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_DOUBLE; -} - -static avro_schema_t -avro_generic_double_get_schema(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return avro_schema_double(); -} - -static int -avro_generic_double_get(const avro_value_iface_t *iface, - const void *vself, double *out) -{ - AVRO_UNUSED(iface); - const double *self = (const double *) vself; - *out = *self; - return 0; -} - -static int -avro_generic_double_set(const avro_value_iface_t *iface, - void *vself, double val) -{ - AVRO_UNUSED(iface); - double *self = (double *) vself; - *self = val; - return 0; -} - -static size_t -avro_generic_double_instance_size(const avro_value_iface_t *iface) -{ - AVRO_UNUSED(iface); - return sizeof(double); -} - -static int -avro_generic_double_init(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - double *self = (double *) vself; - *self = 0.0; - return 0; -} - -static void -avro_generic_double_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); -} - -static avro_generic_value_iface_t AVRO_GENERIC_DOUBLE_CLASS = -{ - { - /* "class" methods */ - NULL, /* incref_iface */ - NULL, /* decref_iface */ - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_double_reset, - avro_generic_double_get_type, - avro_generic_double_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - avro_generic_double_get, - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - avro_generic_double_set, - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_double_instance_size, - avro_generic_double_init, - avro_generic_double_done -}; - -avro_value_iface_t * -avro_generic_double_class(void) -{ - return &AVRO_GENERIC_DOUBLE_CLASS.parent; -} - -int -avro_generic_double_new(avro_value_t *value, double val) -{ - int rval; - check(rval, avro_generic_value_new(&AVRO_GENERIC_DOUBLE_CLASS.parent, value)); - return avro_generic_double_set(value->iface, value->self, val); -} - -/*----------------------------------------------------------------------- - * float - */ - -static int -avro_generic_float_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - float *self = (float *) vself; - *self = 0.0f; - return 0; -} - -static avro_type_t -avro_generic_float_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_FLOAT; -} - -static avro_schema_t -avro_generic_float_get_schema(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return avro_schema_float(); -} - -static int -avro_generic_float_get(const avro_value_iface_t *iface, - const void *vself, float *out) -{ - AVRO_UNUSED(iface); - const float *self = (const float *) vself; - *out = *self; - return 0; -} - -static int -avro_generic_float_set(const avro_value_iface_t *iface, - void *vself, float val) -{ - AVRO_UNUSED(iface); - float *self = (float *) vself; - *self = val; - return 0; -} - -static size_t -avro_generic_float_instance_size(const avro_value_iface_t *iface) -{ - AVRO_UNUSED(iface); - return sizeof(float); -} - -static int -avro_generic_float_init(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - float *self = (float *) vself; - *self = 0.0f; - return 0; -} - -static void -avro_generic_float_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); -} - -static avro_generic_value_iface_t AVRO_GENERIC_FLOAT_CLASS = -{ - { - /* "class" methods */ - NULL, /* incref_iface */ - NULL, /* decref_iface */ - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_float_reset, - avro_generic_float_get_type, - avro_generic_float_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - avro_generic_float_get, - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - avro_generic_float_set, - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_float_instance_size, - avro_generic_float_init, - avro_generic_float_done -}; - -avro_value_iface_t * -avro_generic_float_class(void) -{ - return &AVRO_GENERIC_FLOAT_CLASS.parent; -} - -int -avro_generic_float_new(avro_value_t *value, float val) -{ - int rval; - check(rval, avro_generic_value_new(&AVRO_GENERIC_FLOAT_CLASS.parent, value)); - return avro_generic_float_set(value->iface, value->self, val); -} - -/*----------------------------------------------------------------------- - * int - */ - -static int -avro_generic_int_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - int32_t *self = (int32_t *) vself; - *self = 0; - return 0; -} - -static avro_type_t -avro_generic_int_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_INT32; -} - -static avro_schema_t -avro_generic_int_get_schema(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return avro_schema_int(); -} - -static int -avro_generic_int_get(const avro_value_iface_t *iface, - const void *vself, int32_t *out) -{ - AVRO_UNUSED(iface); - const int32_t *self = (const int32_t *) vself; - *out = *self; - return 0; -} - -static int -avro_generic_int_set(const avro_value_iface_t *iface, - void *vself, int32_t val) -{ - AVRO_UNUSED(iface); - int32_t *self = (int32_t *) vself; - *self = val; - return 0; -} - -static size_t -avro_generic_int_instance_size(const avro_value_iface_t *iface) -{ - AVRO_UNUSED(iface); - return sizeof(int32_t); -} - -static int -avro_generic_int_init(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - int32_t *self = (int32_t *) vself; - *self = 0; - return 0; -} - -static void -avro_generic_int_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); -} - -static avro_generic_value_iface_t AVRO_GENERIC_INT_CLASS = -{ - { - /* "class" methods */ - NULL, /* incref_iface */ - NULL, /* decref_iface */ - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_int_reset, - avro_generic_int_get_type, - avro_generic_int_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - avro_generic_int_get, - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - avro_generic_int_set, - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_int_instance_size, - avro_generic_int_init, - avro_generic_int_done -}; - -avro_value_iface_t * -avro_generic_int_class(void) -{ - return &AVRO_GENERIC_INT_CLASS.parent; -} - -int -avro_generic_int_new(avro_value_t *value, int32_t val) -{ - int rval; - check(rval, avro_generic_value_new(&AVRO_GENERIC_INT_CLASS.parent, value)); - return avro_generic_int_set(value->iface, value->self, val); -} - -/*----------------------------------------------------------------------- - * long - */ - -static int -avro_generic_long_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - int64_t *self = (int64_t *) vself; - *self = 0; - return 0; -} - -static avro_type_t -avro_generic_long_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_INT64; -} - -static avro_schema_t -avro_generic_long_get_schema(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return avro_schema_long(); -} - -static int -avro_generic_long_get(const avro_value_iface_t *iface, - const void *vself, int64_t *out) -{ - AVRO_UNUSED(iface); - const int64_t *self = (const int64_t *) vself; - *out = *self; - return 0; -} - -static int -avro_generic_long_set(const avro_value_iface_t *iface, - void *vself, int64_t val) -{ - AVRO_UNUSED(iface); - int64_t *self = (int64_t *) vself; - *self = val; - return 0; -} - -static size_t -avro_generic_long_instance_size(const avro_value_iface_t *iface) -{ - AVRO_UNUSED(iface); - return sizeof(int64_t); -} - -static int -avro_generic_long_init(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - int64_t *self = (int64_t *) vself; - *self = 0; - return 0; -} - -static void -avro_generic_long_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); -} - -static avro_generic_value_iface_t AVRO_GENERIC_LONG_CLASS = -{ - { - /* "class" methods */ - NULL, /* incref_iface */ - NULL, /* decref_iface */ - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_long_reset, - avro_generic_long_get_type, - avro_generic_long_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - avro_generic_long_get, - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - avro_generic_long_set, - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_long_instance_size, - avro_generic_long_init, - avro_generic_long_done -}; - -avro_value_iface_t * -avro_generic_long_class(void) -{ - return &AVRO_GENERIC_LONG_CLASS.parent; -} - -int -avro_generic_long_new(avro_value_t *value, int64_t val) -{ - int rval; - check(rval, avro_generic_value_new(&AVRO_GENERIC_LONG_CLASS.parent, value)); - return avro_generic_long_set(value->iface, value->self, val); -} - -/*----------------------------------------------------------------------- - * null - */ - -static int -avro_generic_null_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - int *self = (int *) vself; - *self = 0; - return 0; -} - -static avro_type_t -avro_generic_null_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_NULL; -} - -static avro_schema_t -avro_generic_null_get_schema(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return avro_schema_null(); -} - -static int -avro_generic_null_get(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return 0; -} - -static int -avro_generic_null_set(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return 0; -} - -static size_t -avro_generic_null_instance_size(const avro_value_iface_t *iface) -{ - AVRO_UNUSED(iface); - return sizeof(int); -} - -static int -avro_generic_null_init(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - int *self = (int *) vself; - *self = 0; - return 0; -} - -static void -avro_generic_null_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); -} - -static avro_generic_value_iface_t AVRO_GENERIC_NULL_CLASS = -{ - { - /* "class" methods */ - NULL, /* incref_iface */ - NULL, /* decref_iface */ - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_null_reset, - avro_generic_null_get_type, - avro_generic_null_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - avro_generic_null_get, - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - avro_generic_null_set, - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_null_instance_size, - avro_generic_null_init, - avro_generic_null_done -}; - -avro_value_iface_t * -avro_generic_null_class(void) -{ - return &AVRO_GENERIC_NULL_CLASS.parent; -} - -int -avro_generic_null_new(avro_value_t *value) -{ - return avro_generic_value_new(&AVRO_GENERIC_NULL_CLASS.parent, value); -} - -/*----------------------------------------------------------------------- - * string - */ - -static int -avro_generic_string_reset(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_clear(self); - return 0; -} - -static avro_type_t -avro_generic_string_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_STRING; -} - -static avro_schema_t -avro_generic_string_get_schema(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return avro_schema_string(); -} - -static int -avro_generic_string_get(const avro_value_iface_t *iface, - const void *vself, const char **str, size_t *size) -{ - AVRO_UNUSED(iface); - const avro_raw_string_t *self = (const avro_raw_string_t *) vself; - const char *contents = (const char *) avro_raw_string_get(self); - - if (str != NULL) { - /* - * We can't return a NULL string, we have to return an - * *empty* string - */ - - *str = (contents == NULL)? "": contents; - } - if (size != NULL) { - /* raw_string's length includes the NUL terminator, - * unless it's empty */ - *size = (contents == NULL)? 1: avro_raw_string_length(self); - } - return 0; -} - -static int -avro_generic_string_grab(const avro_value_iface_t *iface, - const void *vself, avro_wrapped_buffer_t *dest) -{ - AVRO_UNUSED(iface); - const avro_raw_string_t *self = (const avro_raw_string_t *) vself; - const char *contents = (const char *) avro_raw_string_get(self); - - if (contents == NULL) { - return avro_wrapped_buffer_new(dest, "", 1); - } else { - return avro_raw_string_grab(self, dest); - } -} - -static int -avro_generic_string_set(const avro_value_iface_t *iface, - void *vself, const char *val) -{ - AVRO_UNUSED(iface); - check_param(EINVAL, val != NULL, "string contents"); - - /* - * This raw_string method ensures that we copy the NUL - * terminator from val, and will include the NUL terminator in - * the raw_string's length, which is what we want. - */ - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_set(self, val); - return 0; -} - -static int -avro_generic_string_set_length(const avro_value_iface_t *iface, - void *vself, const char *val, size_t size) -{ - AVRO_UNUSED(iface); - check_param(EINVAL, val != NULL, "string contents"); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_set_length(self, val, size); - return 0; -} - -static int -avro_generic_string_give_length(const avro_value_iface_t *iface, - void *vself, avro_wrapped_buffer_t *buf) -{ - AVRO_UNUSED(iface); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_give(self, buf); - return 0; -} - -static size_t -avro_generic_string_instance_size(const avro_value_iface_t *iface) -{ - AVRO_UNUSED(iface); - return sizeof(avro_raw_string_t); -} - -static int -avro_generic_string_init(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_init(self); - return 0; -} - -static void -avro_generic_string_done(const avro_value_iface_t *iface, void *vself) -{ - AVRO_UNUSED(iface); - avro_raw_string_t *self = (avro_raw_string_t *) vself; - avro_raw_string_done(self); -} - -static avro_generic_value_iface_t AVRO_GENERIC_STRING_CLASS = -{ - { - /* "class" methods */ - NULL, /* incref_iface */ - NULL, /* decref_iface */ - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_string_reset, - avro_generic_string_get_type, - avro_generic_string_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - avro_generic_string_get, - avro_generic_string_grab, - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - avro_generic_string_set, - avro_generic_string_set_length, - avro_generic_string_give_length, - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_string_instance_size, - avro_generic_string_init, - avro_generic_string_done -}; - -avro_value_iface_t * -avro_generic_string_class(void) -{ - return &AVRO_GENERIC_STRING_CLASS.parent; -} - -int -avro_generic_string_new(avro_value_t *value, const char *str) -{ - int rval; - check(rval, avro_generic_value_new(&AVRO_GENERIC_STRING_CLASS.parent, value)); - return avro_generic_string_set(value->iface, value->self, str); -} - -int -avro_generic_string_new_length(avro_value_t *value, const char *str, size_t size) -{ - int rval; - check(rval, avro_generic_value_new(&AVRO_GENERIC_STRING_CLASS.parent, value)); - return avro_generic_string_set_length(value->iface, value->self, str, size); -} - - -/*----------------------------------------------------------------------- - * array - */ - -/* - * For generic arrays, we need to store the value implementation for the - * array's elements. - */ - -typedef struct avro_generic_array_value_iface { - avro_generic_value_iface_t parent; - volatile int refcount; - avro_schema_t schema; - avro_generic_value_iface_t *child_giface; -} avro_generic_array_value_iface_t; - -typedef struct avro_generic_array { - avro_raw_array_t array; -} avro_generic_array_t; - - -static avro_value_iface_t * -avro_generic_array_incref_iface(avro_value_iface_t *viface) -{ - avro_generic_array_value_iface_t *iface = - container_of(viface, avro_generic_array_value_iface_t, parent); - avro_refcount_inc(&iface->refcount); - return viface; -} - -static void -avro_generic_array_decref_iface(avro_value_iface_t *viface) -{ - avro_generic_array_value_iface_t *iface = - container_of(viface, avro_generic_array_value_iface_t, parent); - if (avro_refcount_dec(&iface->refcount)) { - avro_schema_decref(iface->schema); - avro_value_iface_decref(&iface->child_giface->parent); - avro_freet(avro_generic_array_value_iface_t, iface); - } -} - - -static void -avro_generic_array_free_elements(const avro_generic_value_iface_t *child_giface, - avro_generic_array_t *self) -{ - size_t i; - for (i = 0; i < avro_raw_array_size(&self->array); i++) { - void *child_self = avro_raw_array_get_raw(&self->array, i); - avro_value_done(child_giface, child_self); - } -} - -static int -avro_generic_array_reset(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_array_value_iface_t *iface = - container_of(viface, avro_generic_array_value_iface_t, parent); - avro_generic_array_t *self = (avro_generic_array_t *) vself; - avro_generic_array_free_elements(iface->child_giface, self); - avro_raw_array_clear(&self->array); - return 0; -} - -static avro_type_t -avro_generic_array_get_type(const avro_value_iface_t *viface, const void *vself) -{ - AVRO_UNUSED(viface); - AVRO_UNUSED(vself); - return AVRO_ARRAY; -} - -static avro_schema_t -avro_generic_array_get_schema(const avro_value_iface_t *viface, const void *vself) -{ - const avro_generic_array_value_iface_t *iface = - container_of(viface, avro_generic_array_value_iface_t, parent); - AVRO_UNUSED(vself); - return iface->schema; -} - -static int -avro_generic_array_get_size(const avro_value_iface_t *viface, - const void *vself, size_t *size) -{ - AVRO_UNUSED(viface); - const avro_generic_array_t *self = (const avro_generic_array_t *) vself; - if (size != NULL) { - *size = avro_raw_array_size(&self->array); - } - return 0; -} - -static int -avro_generic_array_get_by_index(const avro_value_iface_t *viface, - const void *vself, size_t index, - avro_value_t *child, const char **name) -{ - const avro_generic_array_value_iface_t *iface = - container_of(viface, avro_generic_array_value_iface_t, parent); - AVRO_UNUSED(name); - const avro_generic_array_t *self = (avro_generic_array_t *) vself; - if (index >= avro_raw_array_size(&self->array)) { - avro_set_error("Array index %" PRIsz " out of range", index); - return EINVAL; - } - child->iface = &iface->child_giface->parent; - child->self = avro_raw_array_get_raw(&self->array, index); - return 0; -} - -static int -avro_generic_array_append(const avro_value_iface_t *viface, - void *vself, avro_value_t *child, - size_t *new_index) -{ - int rval; - const avro_generic_array_value_iface_t *iface = - container_of(viface, avro_generic_array_value_iface_t, parent); - avro_generic_array_t *self = (avro_generic_array_t *) vself; - child->iface = &iface->child_giface->parent; - child->self = avro_raw_array_append(&self->array); - if (child->self == NULL) { - avro_set_error("Couldn't expand array"); - return ENOMEM; - } - check(rval, avro_value_init(iface->child_giface, child->self)); - if (new_index != NULL) { - *new_index = avro_raw_array_size(&self->array) - 1; - } - return 0; -} - -static size_t -avro_generic_array_instance_size(const avro_value_iface_t *viface) -{ - AVRO_UNUSED(viface); - return sizeof(avro_generic_array_t); -} - -static int -avro_generic_array_init(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_array_value_iface_t *iface = - container_of(viface, avro_generic_array_value_iface_t, parent); - avro_generic_array_t *self = (avro_generic_array_t *) vself; - - size_t child_size = avro_value_instance_size(iface->child_giface); - avro_raw_array_init(&self->array, child_size); - return 0; -} - -static void -avro_generic_array_done(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_array_value_iface_t *iface = - container_of(viface, avro_generic_array_value_iface_t, parent); - avro_generic_array_t *self = (avro_generic_array_t *) vself; - avro_generic_array_free_elements(iface->child_giface, self); - avro_raw_array_done(&self->array); -} - -static avro_generic_value_iface_t AVRO_GENERIC_ARRAY_CLASS = -{ -{ - /* "class" methods */ - avro_generic_array_incref_iface, - avro_generic_array_decref_iface, - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_array_reset, - avro_generic_array_get_type, - avro_generic_array_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - avro_generic_array_get_size, - avro_generic_array_get_by_index, - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - avro_generic_array_append, - NULL, /* add */ - NULL /* set_branch */ -}, - avro_generic_array_instance_size, - avro_generic_array_init, - avro_generic_array_done -}; - -static avro_generic_value_iface_t * -avro_generic_array_class(avro_schema_t schema, memoize_state_t *state) -{ - avro_schema_t child_schema = avro_schema_array_items(schema); - avro_generic_value_iface_t *child_giface = - avro_generic_class_from_schema_memoized(child_schema, state); - if (child_giface == NULL) { - return NULL; - } - - ssize_t child_size = avro_value_instance_size(child_giface); - if (child_size < 0) { - avro_set_error("Array item class must provide instance_size"); - avro_value_iface_decref(&child_giface->parent); - return NULL; - } - - avro_generic_array_value_iface_t *iface = - (avro_generic_array_value_iface_t *) avro_new(avro_generic_array_value_iface_t); - if (iface == NULL) { - avro_value_iface_decref(&child_giface->parent); - return NULL; - } - - /* - * TODO: Maybe check that schema.items matches - * child_iface.get_schema? - */ - - iface->parent = AVRO_GENERIC_ARRAY_CLASS; - iface->refcount = 1; - iface->schema = avro_schema_incref(schema); - iface->child_giface = child_giface; - return &iface->parent; -} - - -/*----------------------------------------------------------------------- - * enum - */ - -typedef struct avro_generic_enum_value_iface { - avro_generic_value_iface_t parent; - volatile int refcount; - avro_schema_t schema; -} avro_generic_enum_value_iface_t; - - -static avro_value_iface_t * -avro_generic_enum_incref_iface(avro_value_iface_t *viface) -{ - avro_generic_enum_value_iface_t *iface = - (avro_generic_enum_value_iface_t *) viface; - avro_refcount_inc(&iface->refcount); - return viface; -} - -static void -avro_generic_enum_decref_iface(avro_value_iface_t *viface) -{ - avro_generic_enum_value_iface_t *iface = - (avro_generic_enum_value_iface_t *) viface; - if (avro_refcount_dec(&iface->refcount)) { - avro_schema_decref(iface->schema); - avro_freet(avro_generic_enum_value_iface_t, iface); - } -} - -static int -avro_generic_enum_reset(const avro_value_iface_t *viface, void *vself) -{ - AVRO_UNUSED(viface); - int *self = (int *) vself; - *self = 0; - return 0; -} - -static avro_type_t -avro_generic_enum_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_ENUM; -} - -static avro_schema_t -avro_generic_enum_get_schema(const avro_value_iface_t *viface, const void *vself) -{ - const avro_generic_enum_value_iface_t *iface = - container_of(viface, avro_generic_enum_value_iface_t, parent); - AVRO_UNUSED(vself); - return iface->schema; -} - -static int -avro_generic_enum_get(const avro_value_iface_t *viface, - const void *vself, int *out) -{ - AVRO_UNUSED(viface); - const int *self = (const int *) vself; - *out = *self; - return 0; -} - -static int -avro_generic_enum_set(const avro_value_iface_t *viface, - void *vself, int val) -{ - AVRO_UNUSED(viface); - int *self = (int *) vself; - *self = val; - return 0; -} - -static size_t -avro_generic_enum_instance_size(const avro_value_iface_t *viface) -{ - AVRO_UNUSED(viface); - return sizeof(int); -} - -static int -avro_generic_enum_init(const avro_value_iface_t *viface, void *vself) -{ - AVRO_UNUSED(viface); - int *self = (int *) vself; - *self = 0; - return 0; -} - -static void -avro_generic_enum_done(const avro_value_iface_t *viface, void *vself) -{ - AVRO_UNUSED(viface); - AVRO_UNUSED(vself); -} - -static avro_generic_value_iface_t AVRO_GENERIC_ENUM_CLASS = -{ - { - /* "class" methods */ - avro_generic_enum_incref_iface, - avro_generic_enum_decref_iface, - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_enum_reset, - avro_generic_enum_get_type, - avro_generic_enum_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - avro_generic_enum_get, - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - avro_generic_enum_set, - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_enum_instance_size, - avro_generic_enum_init, - avro_generic_enum_done -}; - -static avro_generic_value_iface_t * -avro_generic_enum_class(avro_schema_t schema) -{ - avro_generic_enum_value_iface_t *iface = - (avro_generic_enum_value_iface_t *) avro_new(avro_generic_enum_value_iface_t); - if (iface == NULL) { - return NULL; - } - - iface->parent = AVRO_GENERIC_ENUM_CLASS; - iface->refcount = 1; - iface->schema = avro_schema_incref(schema); - return &iface->parent; -} - - -/*----------------------------------------------------------------------- - * fixed - */ - -typedef struct avro_generic_fixed_value_iface { - avro_generic_value_iface_t parent; - volatile int refcount; - avro_schema_t schema; - size_t data_size; -} avro_generic_fixed_value_iface_t; - - -static avro_value_iface_t * -avro_generic_fixed_incref_iface(avro_value_iface_t *viface) -{ - avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - avro_refcount_inc(&iface->refcount); - return viface; -} - -static void -avro_generic_fixed_decref_iface(avro_value_iface_t *viface) -{ - avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - if (avro_refcount_dec(&iface->refcount)) { - avro_schema_decref(iface->schema); - avro_freet(avro_generic_fixed_value_iface_t, iface); - } -} - -static int -avro_generic_fixed_reset(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - memset(vself, 0, iface->data_size); - return 0; -} - -static avro_type_t -avro_generic_fixed_get_type(const avro_value_iface_t *iface, const void *vself) -{ - AVRO_UNUSED(iface); - AVRO_UNUSED(vself); - return AVRO_FIXED; -} - -static avro_schema_t -avro_generic_fixed_get_schema(const avro_value_iface_t *viface, const void *vself) -{ - const avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - AVRO_UNUSED(vself); - return iface->schema; -} - -static int -avro_generic_fixed_get(const avro_value_iface_t *viface, - const void *vself, const void **buf, size_t *size) -{ - const avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - if (buf != NULL) { - *buf = vself; - } - if (size != NULL) { - *size = iface->data_size; - } - return 0; -} - -static int -avro_generic_fixed_grab(const avro_value_iface_t *viface, - const void *vself, avro_wrapped_buffer_t *dest) -{ - const avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - return avro_wrapped_buffer_new(dest, vself, iface->data_size); -} - -static int -avro_generic_fixed_set(const avro_value_iface_t *viface, - void *vself, void *buf, size_t size) -{ - check_param(EINVAL, buf != NULL, "fixed contents"); - const avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - if (size != iface->data_size) { - avro_set_error("Invalid data size in set_fixed"); - return EINVAL; - } - memcpy(vself, buf, size); - return 0; -} - -static int -avro_generic_fixed_give(const avro_value_iface_t *viface, - void *vself, avro_wrapped_buffer_t *buf) -{ - int rval = avro_generic_fixed_set - (viface, vself, (void *) buf->buf, buf->size); - avro_wrapped_buffer_free(buf); - return rval; -} - -static size_t -avro_generic_fixed_instance_size(const avro_value_iface_t *viface) -{ - const avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - return iface->data_size; -} - -static int -avro_generic_fixed_init(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_fixed_value_iface_t *iface = - container_of(viface, avro_generic_fixed_value_iface_t, parent); - memset(vself, 0, iface->data_size); - return 0; -} - -static void -avro_generic_fixed_done(const avro_value_iface_t *viface, void *vself) -{ - AVRO_UNUSED(viface); - AVRO_UNUSED(vself); -} - -static avro_generic_value_iface_t AVRO_GENERIC_FIXED_CLASS = -{ - { - /* "class" methods */ - avro_generic_fixed_incref_iface, - avro_generic_fixed_decref_iface, - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_fixed_reset, - avro_generic_fixed_get_type, - avro_generic_fixed_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - avro_generic_fixed_get, - avro_generic_fixed_grab, - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - avro_generic_fixed_set, - avro_generic_fixed_give, - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_fixed_instance_size, - avro_generic_fixed_init, - avro_generic_fixed_done -}; - -static avro_generic_value_iface_t * -avro_generic_fixed_class(avro_schema_t schema) -{ - avro_generic_fixed_value_iface_t *iface = - (avro_generic_fixed_value_iface_t *) avro_new(avro_generic_fixed_value_iface_t); - if (iface == NULL) { - return NULL; - } - - iface->parent = AVRO_GENERIC_FIXED_CLASS; - iface->refcount = 1; - iface->schema = avro_schema_incref(schema); - iface->data_size = avro_schema_fixed_size(schema); - return &iface->parent; -} - - -/*----------------------------------------------------------------------- - * map - */ - -/* - * For generic maps, we need to store the value implementation for the - * map's elements. - */ - -typedef struct avro_generic_map_value_iface { - avro_generic_value_iface_t parent; - volatile int refcount; - avro_schema_t schema; - avro_generic_value_iface_t *child_giface; -} avro_generic_map_value_iface_t; - -typedef struct avro_generic_map { - avro_raw_map_t map; -} avro_generic_map_t; - - -static avro_value_iface_t * -avro_generic_map_incref_iface(avro_value_iface_t *viface) -{ - avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - avro_refcount_inc(&iface->refcount); - return viface; -} - -static void -avro_generic_map_decref_iface(avro_value_iface_t *viface) -{ - avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - if (avro_refcount_dec(&iface->refcount)) { - avro_schema_decref(iface->schema); - avro_value_iface_decref(&iface->child_giface->parent); - avro_freet(avro_generic_map_value_iface_t, iface); - } -} - - -static void -avro_generic_map_free_elements(const avro_generic_value_iface_t *child_giface, - avro_generic_map_t *self) -{ - size_t i; - for (i = 0; i < avro_raw_map_size(&self->map); i++) { - void *child_self = avro_raw_map_get_raw(&self->map, i); - avro_value_done(child_giface, child_self); - } -} - -static int -avro_generic_map_reset(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - avro_generic_map_t *self = (avro_generic_map_t *) vself; - avro_generic_map_free_elements(iface->child_giface, self); - avro_raw_map_clear(&self->map); - return 0; -} - -static avro_type_t -avro_generic_map_get_type(const avro_value_iface_t *viface, const void *vself) -{ - AVRO_UNUSED(viface); - AVRO_UNUSED(vself); - return AVRO_MAP; -} - -static avro_schema_t -avro_generic_map_get_schema(const avro_value_iface_t *viface, const void *vself) -{ - const avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - AVRO_UNUSED(vself); - return iface->schema; -} - -static int -avro_generic_map_get_size(const avro_value_iface_t *viface, - const void *vself, size_t *size) -{ - AVRO_UNUSED(viface); - const avro_generic_map_t *self = (const avro_generic_map_t *) vself; - if (size != NULL) { - *size = avro_raw_map_size(&self->map); - } - return 0; -} - -static int -avro_generic_map_get_by_index(const avro_value_iface_t *viface, - const void *vself, size_t index, - avro_value_t *child, const char **name) -{ - const avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - const avro_generic_map_t *self = (const avro_generic_map_t *) vself; - if (index >= avro_raw_map_size(&self->map)) { - avro_set_error("Map index %" PRIsz " out of range", index); - return EINVAL; - } - child->iface = &iface->child_giface->parent; - child->self = avro_raw_map_get_raw(&self->map, index); - if (name != NULL) { - *name = avro_raw_map_get_key(&self->map, index); - } - return 0; -} - -static int -avro_generic_map_get_by_name(const avro_value_iface_t *viface, - const void *vself, const char *name, - avro_value_t *child, size_t *index) -{ - const avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - const avro_generic_map_t *self = (const avro_generic_map_t *) vself; - child->iface = &iface->child_giface->parent; - child->self = avro_raw_map_get(&self->map, name, index); - if (child->self == NULL) { - avro_set_error("No map element named %s", name); - return EINVAL; - } - return 0; -} - -static int -avro_generic_map_add(const avro_value_iface_t *viface, - void *vself, const char *key, - avro_value_t *child, size_t *index, int *is_new) -{ - const avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - int rval; - avro_generic_map_t *self = (avro_generic_map_t *) vself; - child->iface = &iface->child_giface->parent; - rval = avro_raw_map_get_or_create(&self->map, key, - &child->self, index); - if (rval < 0) { - return -rval; - } - if (is_new != NULL) { - *is_new = rval; - } - if (rval) { - check(rval, avro_value_init(iface->child_giface, child->self)); - } - return 0; -} - -static size_t -avro_generic_map_instance_size(const avro_value_iface_t *viface) -{ - AVRO_UNUSED(viface); - return sizeof(avro_generic_map_t); -} - -static int -avro_generic_map_init(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - avro_generic_map_t *self = (avro_generic_map_t *) vself; - - size_t child_size = avro_value_instance_size(iface->child_giface); - avro_raw_map_init(&self->map, child_size); - return 0; -} - -static void -avro_generic_map_done(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_map_value_iface_t *iface = - container_of(viface, avro_generic_map_value_iface_t, parent); - avro_generic_map_t *self = (avro_generic_map_t *) vself; - avro_generic_map_free_elements(iface->child_giface, self); - avro_raw_map_done(&self->map); -} - -static avro_generic_value_iface_t AVRO_GENERIC_MAP_CLASS = -{ - { - /* "class" methods */ - avro_generic_map_incref_iface, - avro_generic_map_decref_iface, - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_map_reset, - avro_generic_map_get_type, - avro_generic_map_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - avro_generic_map_get_size, - avro_generic_map_get_by_index, - avro_generic_map_get_by_name, - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - avro_generic_map_add, - NULL /* set_branch */ - }, - avro_generic_map_instance_size, - avro_generic_map_init, - avro_generic_map_done -}; - -static avro_generic_value_iface_t * -avro_generic_map_class(avro_schema_t schema, memoize_state_t *state) -{ - avro_schema_t child_schema = avro_schema_array_items(schema); - avro_generic_value_iface_t *child_giface = - avro_generic_class_from_schema_memoized(child_schema, state); - if (child_giface == NULL) { - return NULL; - } - - ssize_t child_size = avro_value_instance_size(child_giface); - if (child_size < 0) { - avro_set_error("Map value class must provide instance_size"); - avro_value_iface_decref(&child_giface->parent); - return NULL; - } - - avro_generic_map_value_iface_t *iface = - (avro_generic_map_value_iface_t *) avro_new(avro_generic_map_value_iface_t); - if (iface == NULL) { - avro_value_iface_decref(&child_giface->parent); - return NULL; - } - - /* - * TODO: Maybe check that schema.items matches - * child_iface.get_schema? - */ - - iface->parent = AVRO_GENERIC_MAP_CLASS; - iface->refcount = 1; - iface->schema = avro_schema_incref(schema); - iface->child_giface = child_giface; - return &iface->parent; -} - - -/*----------------------------------------------------------------------- - * record - */ - -#ifndef DEBUG_FIELD_OFFSETS -#define DEBUG_FIELD_OFFSETS 0 -#endif - -#if DEBUG_FIELD_OFFSETS -#include <stdio.h> -#endif - -/* - * For generic records, we need to store the value implementation for - * each field. We also need to store an offset for each field, since - * we're going to store the contents of each field directly in the - * record, rather than via pointers. - */ - -typedef struct avro_generic_record_value_iface { - avro_generic_value_iface_t parent; - volatile int refcount; - avro_schema_t schema; - - /** The total size of each value struct for this record. */ - size_t instance_size; - - /** The number of fields in this record. Yes, we could get this - * from schema, but this is easier. */ - size_t field_count; - - /** The offset of each field within the record struct. */ - size_t *field_offsets; - - /** The value implementation for each field. */ - avro_generic_value_iface_t **field_ifaces; -} avro_generic_record_value_iface_t; - -typedef struct avro_generic_record { - /* The rest of the struct is taken up by the inline storage - * needed for each field. */ -} avro_generic_record_t; - - -/** Return a pointer to the given field within a record struct. */ -#define avro_generic_record_field(iface, rec, index) \ - (((char *) (rec)) + (iface)->field_offsets[(index)]) - - -static avro_value_iface_t * -avro_generic_record_incref_iface(avro_value_iface_t *viface) -{ - avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - avro_refcount_inc(&iface->refcount); - return viface; -} - -static void -avro_generic_record_decref_iface(avro_value_iface_t *viface) -{ - avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - - if (avro_refcount_dec(&iface->refcount)) { - size_t i; - for (i = 0; i < iface->field_count; i++) { - avro_value_iface_decref(&iface->field_ifaces[i]->parent); - } - - avro_schema_decref(iface->schema); - avro_free(iface->field_offsets, - sizeof(size_t) * iface->field_count); - avro_free(iface->field_ifaces, - sizeof(avro_generic_value_iface_t *) * iface->field_count); - - avro_freet(avro_generic_record_value_iface_t, iface); - } -} - - -static int -avro_generic_record_reset(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - int rval; - avro_generic_record_t *self = (avro_generic_record_t *) vself; - size_t i; - for (i = 0; i < iface->field_count; i++) { - avro_value_t value = { - &iface->field_ifaces[i]->parent, - avro_generic_record_field(iface, self, i) - }; - check(rval, avro_value_reset(&value)); - } - return 0; -} - -static avro_type_t -avro_generic_record_get_type(const avro_value_iface_t *viface, const void *vself) -{ - AVRO_UNUSED(viface); - AVRO_UNUSED(vself); - return AVRO_RECORD; -} - -static avro_schema_t -avro_generic_record_get_schema(const avro_value_iface_t *viface, const void *vself) -{ - const avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - AVRO_UNUSED(vself); - return iface->schema; -} - -static int -avro_generic_record_get_size(const avro_value_iface_t *viface, - const void *vself, size_t *size) -{ - const avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - AVRO_UNUSED(vself); - if (size != NULL) { - *size = iface->field_count; - } - return 0; -} - -static int -avro_generic_record_get_by_index(const avro_value_iface_t *viface, - const void *vself, size_t index, - avro_value_t *child, const char **name) -{ - const avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - const avro_generic_record_t *self = (const avro_generic_record_t *) vself; - if (index >= iface->field_count) { - avro_set_error("Field index %" PRIsz " out of range", index); - return EINVAL; - } - child->iface = &iface->field_ifaces[index]->parent; - child->self = avro_generic_record_field(iface, self, index); - - /* - * Grab the field name from the schema if asked for. - */ - if (name != NULL) { - avro_schema_t schema = iface->schema; - *name = avro_schema_record_field_name(schema, index); - } - - return 0; -} - -static int -avro_generic_record_get_by_name(const avro_value_iface_t *viface, - const void *vself, const char *name, - avro_value_t *child, size_t *index_out) -{ - const avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - const avro_generic_record_t *self = (const avro_generic_record_t *) vself; - - avro_schema_t schema = iface->schema; - int index = avro_schema_record_field_get_index(schema, name); - if (index < 0) { - avro_set_error("Unknown record field %s", name); - return EINVAL; - } - - child->iface = &iface->field_ifaces[index]->parent; - child->self = avro_generic_record_field(iface, self, index); - if (index_out != NULL) { - *index_out = index; - } - return 0; -} - -static size_t -avro_generic_record_instance_size(const avro_value_iface_t *viface) -{ - const avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - return iface->instance_size; -} - -static int -avro_generic_record_init(const avro_value_iface_t *viface, void *vself) -{ - int rval; - const avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - avro_generic_record_t *self = (avro_generic_record_t *) vself; - - /* Initialize each field */ - size_t i; - for (i = 0; i < iface->field_count; i++) { - check(rval, avro_value_init - (iface->field_ifaces[i], - avro_generic_record_field(iface, self, i))); - } - - return 0; -} - -static void -avro_generic_record_done(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_record_value_iface_t *iface = - container_of(viface, avro_generic_record_value_iface_t, parent); - avro_generic_record_t *self = (avro_generic_record_t *) vself; - size_t i; - for (i = 0; i < iface->field_count; i++) { - avro_value_done(iface->field_ifaces[i], - avro_generic_record_field(iface, self, i)); - } -} - -static avro_generic_value_iface_t AVRO_GENERIC_RECORD_CLASS = -{ - { - /* "class" methods */ - avro_generic_record_incref_iface, - avro_generic_record_decref_iface, - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_record_reset, - avro_generic_record_get_type, - avro_generic_record_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - avro_generic_record_get_size, - avro_generic_record_get_by_index, - avro_generic_record_get_by_name, - NULL, /* get_discriminant */ - NULL, /* get_current_branch */ - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - NULL /* set_branch */ - }, - avro_generic_record_instance_size, - avro_generic_record_init, - avro_generic_record_done -}; - -static avro_generic_value_iface_t * -avro_generic_record_class(avro_schema_t schema, memoize_state_t *state) -{ - avro_generic_record_value_iface_t *iface = - (avro_generic_record_value_iface_t *) avro_new(avro_generic_record_value_iface_t); - if (iface == NULL) { - return NULL; - } - - memset(iface, 0, sizeof(avro_generic_record_value_iface_t)); - iface->parent = AVRO_GENERIC_RECORD_CLASS; - iface->refcount = 1; - iface->schema = avro_schema_incref(schema); - - iface->field_count = avro_schema_record_size(schema); - size_t field_offsets_size = - sizeof(size_t) * iface->field_count; - size_t field_ifaces_size = - sizeof(avro_generic_value_iface_t *) * iface->field_count; - - if (iface->field_count == 0) { - iface->field_offsets = NULL; - iface->field_ifaces = NULL; - } else { - iface->field_offsets = (size_t *) avro_malloc(field_offsets_size); - if (iface->field_offsets == NULL) { - goto error; - } - - iface->field_ifaces = (avro_generic_value_iface_t **) avro_malloc(field_ifaces_size); - if (iface->field_ifaces == NULL) { - goto error; - } - } - - size_t next_offset = sizeof(avro_generic_record_t); -#if DEBUG_FIELD_OFFSETS - fprintf(stderr, " Record %s\n Header: Offset 0, size %" PRIsz "\n", - avro_schema_type_name(schema), - sizeof(avro_generic_record_t)); -#endif - size_t i; - for (i = 0; i < iface->field_count; i++) { -#if DEBUG_FIELD_OFFSETS - fprintf(stderr, " Field %" PRIsz ":\n", i); -#endif - avro_schema_t field_schema = - avro_schema_record_field_get_by_index(schema, i); -#if DEBUG_FIELD_OFFSETS - fprintf(stderr, " Schema %s\n", - avro_schema_type_name(field_schema)); -#endif - - iface->field_offsets[i] = next_offset; - - iface->field_ifaces[i] = - avro_generic_class_from_schema_memoized(field_schema, state); - if (iface->field_ifaces[i] == NULL) { - goto error; - } - - ssize_t field_size = - avro_value_instance_size(iface->field_ifaces[i]); - if (field_size < 0) { - avro_set_error("Record field class must provide instance_size"); - goto error; - } - -#if DEBUG_FIELD_OFFSETS - fprintf(stderr, " Offset %" PRIsz ", size %" PRIsz "\n", - next_offset, field_size); -#endif - next_offset += field_size; - } - - iface->instance_size = next_offset; -#if DEBUG_FIELD_OFFSETS - fprintf(stderr, " TOTAL SIZE: %" PRIsz "\n", next_offset); -#endif - - return &iface->parent; - -error: - avro_schema_decref(iface->schema); - if (iface->field_offsets != NULL) { - avro_free(iface->field_offsets, field_offsets_size); - } - if (iface->field_ifaces != NULL) { - for (i = 0; i < iface->field_count; i++) { - if (iface->field_ifaces[i] != NULL) { - avro_value_iface_decref(&iface->field_ifaces[i]->parent); - } - } - avro_free(iface->field_ifaces, field_ifaces_size); - } - avro_freet(avro_generic_record_value_iface_t, iface); - return NULL; -} - - -/*----------------------------------------------------------------------- - * union - */ - -#ifndef DEBUG_BRANCHES_OFFSETS -#define DEBUG_BRANCHES_OFFSETS 0 -#endif - -#if DEBUG_BRANCHES_OFFSETS -#include <stdio.h> -#endif - -/* - * For generic unions, we need to store the value implementation for - * each branch, just like for generic records. However, for unions, we - * can only have one branch active at a time, so we can reuse the space - * in the union struct, just like is done with C unions. - */ - -typedef struct avro_generic_union_value_iface { - avro_generic_value_iface_t parent; - volatile int refcount; - avro_schema_t schema; - - /** The total size of each value struct for this union. */ - size_t instance_size; - - /** The number of branches in this union. Yes, we could get - * this from schema, but this is easier. */ - size_t branch_count; - - /** The value implementation for each branch. */ - avro_generic_value_iface_t **branch_ifaces; -} avro_generic_union_value_iface_t; - -typedef struct avro_generic_union { - /** The currently active branch of the union. -1 if no branch - * is selected. */ - int discriminant; - - /* The rest of the struct is taken up by the inline storage - * needed for the active branch. */ -} avro_generic_union_t; - - -/** Return the child interface for the active branch. */ -#define avro_generic_union_branch_giface(iface, _union) \ - ((iface)->branch_ifaces[(_union)->discriminant]) -#define avro_generic_union_branch_iface(iface, _union) \ - (&(avro_generic_union_branch_giface((iface), (_union)))->parent) - -/** Return a pointer to the active branch within a union struct. */ -#define avro_generic_union_branch(_union) \ - (((char *) (_union)) + sizeof(avro_generic_union_t)) - - -static avro_value_iface_t * -avro_generic_union_incref_iface(avro_value_iface_t *viface) -{ - avro_generic_union_value_iface_t *iface = - container_of(viface, avro_generic_union_value_iface_t, parent); - avro_refcount_inc(&iface->refcount); - return viface; -} - -static void -avro_generic_union_decref_iface(avro_value_iface_t *viface) -{ - avro_generic_union_value_iface_t *iface = - container_of(viface, avro_generic_union_value_iface_t, parent); - - if (avro_refcount_dec(&iface->refcount)) { - size_t i; - for (i = 0; i < iface->branch_count; i++) { - avro_value_iface_decref(&iface->branch_ifaces[i]->parent); - } - - avro_schema_decref(iface->schema); - avro_free(iface->branch_ifaces, - sizeof(avro_generic_value_iface_t *) * iface->branch_count); - - avro_freet(avro_generic_union_value_iface_t, iface); - } -} - - -static int -avro_generic_union_reset(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_union_value_iface_t *iface = - container_of(viface, avro_generic_union_value_iface_t, parent); - avro_generic_union_t *self = (avro_generic_union_t *) vself; - /* Keep the same branch selected, for the common case that we're - * about to reuse it. */ - if (self->discriminant >= 0) { -#if DEBUG_BRANCHES - fprintf(stderr, "Resetting branch %d\n", - self->discriminant); -#endif - avro_value_t value = { - avro_generic_union_branch_iface(iface, self), - avro_generic_union_branch(self) - }; - return avro_value_reset(&value); - } - return 0; -} - -static avro_type_t -avro_generic_union_get_type(const avro_value_iface_t *viface, const void *vself) -{ - AVRO_UNUSED(viface); - AVRO_UNUSED(vself); - return AVRO_UNION; -} - -static avro_schema_t -avro_generic_union_get_schema(const avro_value_iface_t *viface, const void *vself) -{ - const avro_generic_union_value_iface_t *iface = - container_of(viface, avro_generic_union_value_iface_t, parent); - AVRO_UNUSED(vself); - return iface->schema; -} - -static int -avro_generic_union_get_discriminant(const avro_value_iface_t *viface, - const void *vself, int *out) -{ - AVRO_UNUSED(viface); - const avro_generic_union_t *self = (const avro_generic_union_t *) vself; - *out = self->discriminant; - return 0; -} - -static int -avro_generic_union_get_current_branch(const avro_value_iface_t *viface, - const void *vself, avro_value_t *branch) -{ - const avro_generic_union_value_iface_t *iface = - container_of(viface, avro_generic_union_value_iface_t, parent); - const avro_generic_union_t *self = (const avro_generic_union_t *) vself; - if (self->discriminant < 0) { - avro_set_error("Union has no selected branch"); - return EINVAL; - } - branch->iface = avro_generic_union_branch_iface(iface, self); - branch->self = avro_generic_union_branch(self); - return 0; -} - -static int -avro_generic_union_set_branch(const avro_value_iface_t *viface, - void *vself, int discriminant, - avro_value_t *branch) -{ - const avro_generic_union_value_iface_t *iface = - container_of(viface, avro_generic_union_value_iface_t, parent); - int rval; - avro_generic_union_t *self = (avro_generic_union_t *) vself; - -#if DEBUG_BRANCHES - fprintf(stderr, "Selecting branch %d (was %d)\n", - discriminant, self->discriminant); -#endif - - /* - * If the new desired branch is different than the currently - * active one, then finalize the old branch and initialize the - * new one. - */ - if (self->discriminant != discriminant) { - if (self->discriminant >= 0) { -#if DEBUG_BRANCHES - fprintf(stderr, "Finalizing branch %d\n", - self->discriminant); -#endif - avro_value_done - (avro_generic_union_branch_giface(iface, self), - avro_generic_union_branch(self)); - } - self->discriminant = discriminant; - if (discriminant >= 0) { -#if DEBUG_BRANCHES - fprintf(stderr, "Initializing branch %d\n", - self->discriminant); -#endif - check(rval, avro_value_init - (avro_generic_union_branch_giface(iface, self), - avro_generic_union_branch(self))); - } - } - - if (branch != NULL) { - branch->iface = avro_generic_union_branch_iface(iface, self); - branch->self = avro_generic_union_branch(self); - } - - return 0; -} - -static size_t -avro_generic_union_instance_size(const avro_value_iface_t *viface) -{ - const avro_generic_union_value_iface_t *iface = - container_of(viface, avro_generic_union_value_iface_t, parent); - return iface->instance_size; -} - -static int -avro_generic_union_init(const avro_value_iface_t *viface, void *vself) -{ - AVRO_UNUSED(viface); - avro_generic_union_t *self = (avro_generic_union_t *) vself; - self->discriminant = -1; - return 0; -} - -static void -avro_generic_union_done(const avro_value_iface_t *viface, void *vself) -{ - const avro_generic_union_value_iface_t *iface = - container_of(viface, avro_generic_union_value_iface_t, parent); - avro_generic_union_t *self = (avro_generic_union_t *) vself; - if (self->discriminant >= 0) { -#if DEBUG_BRANCHES - fprintf(stderr, "Finalizing branch %d\n", - self->discriminant); -#endif - avro_value_done - (avro_generic_union_branch_giface(iface, self), - avro_generic_union_branch(self)); - self->discriminant = -1; - } -} - -static avro_generic_value_iface_t AVRO_GENERIC_UNION_CLASS = -{ - { - /* "class" methods */ - avro_generic_union_incref_iface, - avro_generic_union_decref_iface, - /* general "instance" methods */ - avro_generic_value_incref, - avro_generic_value_decref, - avro_generic_union_reset, - avro_generic_union_get_type, - avro_generic_union_get_schema, - /* primitive getters */ - NULL, /* get_boolean */ - NULL, /* get_bytes */ - NULL, /* grab_bytes */ - NULL, /* get_double */ - NULL, /* get_float */ - NULL, /* get_int */ - NULL, /* get_long */ - NULL, /* get_null */ - NULL, /* get_string */ - NULL, /* grab_string */ - NULL, /* get_enum */ - NULL, /* get_fixed */ - NULL, /* grab_fixed */ - /* primitive setters */ - NULL, /* set_boolean */ - NULL, /* set_bytes */ - NULL, /* give_bytes */ - NULL, /* set_double */ - NULL, /* set_float */ - NULL, /* set_int */ - NULL, /* set_long */ - NULL, /* set_null */ - NULL, /* set_string */ - NULL, /* set_string_length */ - NULL, /* give_string_length */ - NULL, /* set_enum */ - NULL, /* set_fixed */ - NULL, /* give_fixed */ - /* compound getters */ - NULL, /* get_size */ - NULL, /* get_by_index */ - NULL, /* get_by_name */ - avro_generic_union_get_discriminant, - avro_generic_union_get_current_branch, - /* compound setters */ - NULL, /* append */ - NULL, /* add */ - avro_generic_union_set_branch - }, - avro_generic_union_instance_size, - avro_generic_union_init, - avro_generic_union_done -}; - -static avro_generic_value_iface_t * -avro_generic_union_class(avro_schema_t schema, memoize_state_t *state) -{ - avro_generic_union_value_iface_t *iface = - (avro_generic_union_value_iface_t *) avro_new(avro_generic_union_value_iface_t); - if (iface == NULL) { - return NULL; - } - - memset(iface, 0, sizeof(avro_generic_union_value_iface_t)); - iface->parent = AVRO_GENERIC_UNION_CLASS; - iface->refcount = 1; - iface->schema = avro_schema_incref(schema); - - iface->branch_count = avro_schema_union_size(schema); - size_t branch_ifaces_size = - sizeof(avro_generic_value_iface_t *) * iface->branch_count; - - iface->branch_ifaces = (avro_generic_value_iface_t **) avro_malloc(branch_ifaces_size); - if (iface->branch_ifaces == NULL) { - goto error; - } - - size_t max_branch_size = 0; - size_t i; - for (i = 0; i < iface->branch_count; i++) { - avro_schema_t branch_schema = - avro_schema_union_branch(schema, i); - - iface->branch_ifaces[i] = - avro_generic_class_from_schema_memoized(branch_schema, state); - if (iface->branch_ifaces[i] == NULL) { - goto error; - } - - ssize_t branch_size = - avro_value_instance_size(iface->branch_ifaces[i]); - if (branch_size < 0) { - avro_set_error("Union branch class must provide instance_size"); - goto error; - } - -#if DEBUG_BRANCHES - fprintf(stderr, "Branch %" PRIsz ", size %" PRIsz "\n", - i, branch_size); -#endif - - if ((size_t)branch_size > max_branch_size) { - max_branch_size = (size_t)branch_size; - } - } - - iface->instance_size = - sizeof(avro_generic_union_t) + max_branch_size; -#if DEBUG_BRANCHES - fprintf(stderr, "MAX BRANCH SIZE: %" PRIsz "\n", max_branch_size); -#endif - - return &iface->parent; - -error: - avro_schema_decref(iface->schema); - if (iface->branch_ifaces != NULL) { - for (i = 0; i < iface->branch_count; i++) { - if (iface->branch_ifaces[i] != NULL) { - avro_value_iface_decref(&iface->branch_ifaces[i]->parent); - } - } - avro_free(iface->branch_ifaces, branch_ifaces_size); - } - avro_freet(avro_generic_union_value_iface_t, iface); - return NULL; -} - - -/*----------------------------------------------------------------------- - * Schema type dispatcher - */ - -static avro_generic_value_iface_t * -avro_generic_class_from_schema_memoized(avro_schema_t schema, - memoize_state_t *state) -{ - /* - * If we've already instantiated a value class for this schema, - * just return it. - */ - - avro_generic_value_iface_t *result = NULL; - if (avro_memoize_get(&state->mem, schema, NULL, (void **) &result)) { - avro_value_iface_incref(&result->parent); - return result; - } - - /* - * Otherwise instantiate the value class based on the schema - * type. - */ - - switch (schema->type) { - case AVRO_BOOLEAN: - result = &AVRO_GENERIC_BOOLEAN_CLASS; - break; - case AVRO_BYTES: - result = &AVRO_GENERIC_BYTES_CLASS; - break; - case AVRO_DOUBLE: - result = &AVRO_GENERIC_DOUBLE_CLASS; - break; - case AVRO_FLOAT: - result = &AVRO_GENERIC_FLOAT_CLASS; - break; - case AVRO_INT32: - result = &AVRO_GENERIC_INT_CLASS; - break; - case AVRO_INT64: - result = &AVRO_GENERIC_LONG_CLASS; - break; - case AVRO_NULL: - result = &AVRO_GENERIC_NULL_CLASS; - break; - case AVRO_STRING: - result = &AVRO_GENERIC_STRING_CLASS; - break; - - case AVRO_ARRAY: - result = avro_generic_array_class(schema, state); - break; - case AVRO_ENUM: - result = avro_generic_enum_class(schema); - break; - case AVRO_FIXED: - result = avro_generic_fixed_class(schema); - break; - case AVRO_MAP: - result = avro_generic_map_class(schema, state); - break; - case AVRO_RECORD: - result = avro_generic_record_class(schema, state); - break; - case AVRO_UNION: - result = avro_generic_union_class(schema, state); - break; - - case AVRO_LINK: - { - avro_generic_link_value_iface_t *lresult = - avro_generic_link_class(schema); - lresult->next = state->links; - state->links = lresult; - result = &lresult->parent; - break; - } - - default: - avro_set_error("Unknown schema type"); - return NULL; - } - - /* - * Add the new value implementation to the memoized state before - * we return. - */ - - avro_memoize_set(&state->mem, schema, NULL, result); - return result; -} - -avro_value_iface_t * -avro_generic_class_from_schema(avro_schema_t schema) -{ - /* - * Create a state to keep track of the value implementations - * that we create for each subschema. - */ - - memoize_state_t state; - avro_memoize_init(&state.mem); - state.links = NULL; - - /* - * Create the value implementations. - */ - - avro_generic_value_iface_t *result = - avro_generic_class_from_schema_memoized(schema, &state); - if (result == NULL) { - avro_memoize_done(&state.mem); - return NULL; - } - - /* - * Fix up any link schemas so that their value implementations - * point to their target schemas' implementations. - */ - - while (state.links != NULL) { - avro_generic_link_value_iface_t *link_iface = state.links; - avro_schema_t target_schema = - avro_schema_link_target(link_iface->schema); - - avro_generic_value_iface_t *target_iface = NULL; - if (!avro_memoize_get(&state.mem, target_schema, NULL, - (void **) &target_iface)) { - avro_set_error("Never created a value implementation for %s", - avro_schema_type_name(target_schema)); - return NULL; - } - - /* We don't keep a reference to the target - * implementation, since that would give us a reference - * cycle. */ - link_iface->target_giface = target_iface; - state.links = link_iface->next; - link_iface->next = NULL; - } - - /* - * And now we can return. - */ - - avro_memoize_done(&state.mem); - return &result->parent; -} |