diff options
Diffstat (limited to '')
-rw-r--r-- | fluent-bit/lib/avro/src/wrapped-buffer.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/fluent-bit/lib/avro/src/wrapped-buffer.c b/fluent-bit/lib/avro/src/wrapped-buffer.c new file mode 100644 index 00000000..e7496b42 --- /dev/null +++ b/fluent-bit/lib/avro/src/wrapped-buffer.c @@ -0,0 +1,145 @@ +/* + * 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 <errno.h> +#include <stdlib.h> +#include <string.h> + +#include "avro_private.h" +#include "avro/allocation.h" +#include "avro/data.h" +#include "avro/refcount.h" + +struct avro_wrapped_copy { + volatile int refcount; + size_t allocated_size; +}; + +static void +avro_wrapped_copy_free(avro_wrapped_buffer_t *self) +{ + struct avro_wrapped_copy *copy = (struct avro_wrapped_copy *) self->user_data; + if (avro_refcount_dec(©->refcount)) { + avro_free(copy, copy->allocated_size); + } +} + +static int +avro_wrapped_copy_copy(avro_wrapped_buffer_t *dest, + const avro_wrapped_buffer_t *src, + size_t offset, size_t length) +{ + struct avro_wrapped_copy *copy = (struct avro_wrapped_copy *) src->user_data; + avro_refcount_inc(©->refcount); + dest->buf = (char *) src->buf + offset; + dest->size = length; + dest->user_data = copy; + dest->free = avro_wrapped_copy_free; + dest->copy = avro_wrapped_copy_copy; + dest->slice = NULL; + return 0; +} + +int +avro_wrapped_buffer_new_copy(avro_wrapped_buffer_t *dest, + const void *buf, size_t length) +{ + size_t allocated_size = sizeof(struct avro_wrapped_copy) + length; + struct avro_wrapped_copy *copy = (struct avro_wrapped_copy *) avro_malloc(allocated_size); + if (copy == NULL) { + return ENOMEM; + } + + dest->buf = ((char *) copy) + sizeof(struct avro_wrapped_copy); + dest->size = length; + dest->user_data = copy; + dest->free = avro_wrapped_copy_free; + dest->copy = avro_wrapped_copy_copy; + dest->slice = NULL; + + avro_refcount_set(©->refcount, 1); + copy->allocated_size = allocated_size; + memcpy((void *) dest->buf, buf, length); + return 0; +} + +int +avro_wrapped_buffer_new(avro_wrapped_buffer_t *dest, + const void *buf, size_t length) +{ + dest->buf = buf; + dest->size = length; + dest->user_data = NULL; + dest->free = NULL; + dest->copy = NULL; + dest->slice = NULL; + return 0; +} + + +void +avro_wrapped_buffer_move(avro_wrapped_buffer_t *dest, + avro_wrapped_buffer_t *src) +{ + memcpy(dest, src, sizeof(avro_wrapped_buffer_t)); + memset(src, 0, sizeof(avro_wrapped_buffer_t)); +} + +int +avro_wrapped_buffer_copy(avro_wrapped_buffer_t *dest, + const avro_wrapped_buffer_t *src, + size_t offset, size_t length) +{ + if (offset > src->size) { + avro_set_error("Invalid offset when slicing buffer"); + return EINVAL; + } + + if ((offset+length) > src->size) { + avro_set_error("Invalid length when slicing buffer"); + return EINVAL; + } + + if (src->copy == NULL) { + return avro_wrapped_buffer_new_copy(dest, (char *) src->buf + offset, length); + } else { + return src->copy(dest, src, offset, length); + } +} + +int +avro_wrapped_buffer_slice(avro_wrapped_buffer_t *self, + size_t offset, size_t length) +{ + if (offset > self->size) { + avro_set_error("Invalid offset when slicing buffer"); + return EINVAL; + } + + if ((offset+length) > self->size) { + avro_set_error("Invalid length when slicing buffer"); + return EINVAL; + } + + if (self->slice == NULL) { + self->buf = (char *) self->buf + offset; + self->size = length; + return 0; + } else { + return self->slice(self, offset, length); + } +} |