summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/avro/src/encoding_binary.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/avro/src/encoding_binary.c')
-rw-r--r--fluent-bit/lib/avro/src/encoding_binary.c446
1 files changed, 446 insertions, 0 deletions
diff --git a/fluent-bit/lib/avro/src/encoding_binary.c b/fluent-bit/lib/avro/src/encoding_binary.c
new file mode 100644
index 00000000..1fc5f0c9
--- /dev/null
+++ b/fluent-bit/lib/avro/src/encoding_binary.c
@@ -0,0 +1,446 @@
+/*
+ * 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_private.h"
+#include "avro/allocation.h"
+#include "avro/errors.h"
+#include "encoding.h"
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+
+#define MAX_VARINT_BUF_SIZE 10
+
+static int read_long(avro_reader_t reader, int64_t * l)
+{
+ uint64_t value = 0;
+ uint8_t b;
+ int offset = 0;
+ do {
+ if (offset == MAX_VARINT_BUF_SIZE) {
+ /*
+ * illegal byte sequence
+ */
+ avro_set_error("Varint too long");
+ return EILSEQ;
+ }
+ AVRO_READ(reader, &b, 1);
+ value |= (int64_t) (b & 0x7F) << (7 * offset);
+ ++offset;
+ }
+ while (b & 0x80);
+ *l = ((value >> 1) ^ -(value & 1));
+ return 0;
+}
+
+static int skip_long(avro_reader_t reader)
+{
+ uint8_t b;
+ int offset = 0;
+ do {
+ if (offset == MAX_VARINT_BUF_SIZE) {
+ avro_set_error("Varint too long");
+ return EILSEQ;
+ }
+ AVRO_READ(reader, &b, 1);
+ ++offset;
+ }
+ while (b & 0x80);
+ return 0;
+}
+
+static int write_long(avro_writer_t writer, int64_t l)
+{
+ char buf[MAX_VARINT_BUF_SIZE];
+ uint8_t bytes_written = 0;
+ uint64_t n = (l << 1) ^ (l >> 63);
+ while (n & ~0x7F) {
+ buf[bytes_written++] = (char)((((uint8_t) n) & 0x7F) | 0x80);
+ n >>= 7;
+ }
+ buf[bytes_written++] = (char)n;
+ AVRO_WRITE(writer, buf, bytes_written);
+ return 0;
+}
+
+static int64_t size_long(avro_writer_t writer, int64_t l)
+{
+ AVRO_UNUSED(writer);
+
+ int64_t len = 0;
+ uint64_t n = (l << 1) ^ (l >> 63);
+ while (n & ~0x7F) {
+ len++;
+ n >>= 7;
+ }
+ len++;
+ return len;
+}
+
+static int read_int(avro_reader_t reader, int32_t * i)
+{
+ int64_t l;
+ int rval;
+ check(rval, read_long(reader, &l));
+ if (!(INT_MIN <= l && l <= INT_MAX)) {
+ avro_set_error("Varint out of range for int type");
+ return ERANGE;
+ }
+ *i = l;
+ return 0;
+}
+
+static int skip_int(avro_reader_t reader)
+{
+ return skip_long(reader);
+}
+
+static int write_int(avro_writer_t writer, const int32_t i)
+{
+ int64_t l = i;
+ return write_long(writer, l);
+}
+
+static int64_t size_int(avro_writer_t writer, const int32_t i)
+{
+ int64_t l = i;
+ return size_long(writer, l);
+}
+
+static int read_bytes(avro_reader_t reader, char **bytes, int64_t * len)
+{
+ int rval;
+ check_prefix(rval, read_long(reader, len),
+ "Cannot read bytes length: ");
+ *bytes = (char *) avro_malloc(*len + 1);
+ if (!*bytes) {
+ avro_set_error("Cannot allocate buffer for bytes value");
+ return ENOMEM;
+ }
+ AVRO_READ(reader, *bytes, *len);
+ (*bytes)[*len] = '\0';
+ return 0;
+}
+
+static int skip_bytes(avro_reader_t reader)
+{
+ int64_t len = 0;
+ int rval;
+ check_prefix(rval, read_long(reader, &len),
+ "Cannot read bytes length: ");
+ AVRO_SKIP(reader, len);
+ return 0;
+}
+
+static int
+write_bytes(avro_writer_t writer, const char *bytes, const int64_t len)
+{
+ int rval;
+ if (len < 0) {
+ avro_set_error("Invalid bytes value length");
+ return EINVAL;
+ }
+ check_prefix(rval, write_long(writer, len),
+ "Cannot write bytes length: ");
+ AVRO_WRITE(writer, (char *)bytes, len);
+ return 0;
+}
+
+static int64_t
+size_bytes(avro_writer_t writer, const char *bytes, const int64_t len)
+{
+ AVRO_UNUSED(bytes);
+
+ return size_long(writer, len) + len;
+}
+
+static int read_string(avro_reader_t reader, char **s, int64_t *len)
+{
+ int64_t str_len = 0;
+ int rval;
+ check_prefix(rval, read_long(reader, &str_len),
+ "Cannot read string length: ");
+ *len = str_len + 1;
+ *s = (char *) avro_malloc(*len);
+ if (!*s) {
+ avro_set_error("Cannot allocate buffer for string value");
+ return ENOMEM;
+ }
+ (*s)[str_len] = '\0';
+ AVRO_READ(reader, *s, str_len);
+ return 0;
+}
+
+static int skip_string(avro_reader_t reader)
+{
+ return skip_bytes(reader);
+}
+
+static int write_string(avro_writer_t writer, const char *s)
+{
+ int64_t len = strlen(s);
+ return write_bytes(writer, s, len);
+}
+
+static int64_t size_string(avro_writer_t writer, const char *s)
+{
+ int64_t len = strlen(s);
+ return size_bytes(writer, s, len);
+}
+
+static int read_float(avro_reader_t reader, float *f)
+{
+#if AVRO_PLATFORM_IS_BIG_ENDIAN
+ uint8_t buf[4];
+#endif
+ union {
+ float f;
+ int32_t i;
+ } v;
+#if AVRO_PLATFORM_IS_BIG_ENDIAN
+ AVRO_READ(reader, buf, 4);
+ v.i = ((int32_t) buf[0] << 0)
+ | ((int32_t) buf[1] << 8)
+ | ((int32_t) buf[2] << 16) | ((int32_t) buf[3] << 24);
+#else
+ AVRO_READ(reader, (void *)&v.i, 4);
+#endif
+ *f = v.f;
+ return 0;
+}
+
+static int skip_float(avro_reader_t reader)
+{
+ AVRO_SKIP(reader, 4);
+ return 0;
+}
+
+static int write_float(avro_writer_t writer, const float f)
+{
+#if AVRO_PLATFORM_IS_BIG_ENDIAN
+ uint8_t buf[4];
+#endif
+ union {
+ float f;
+ int32_t i;
+ } v;
+
+ v.f = f;
+#if AVRO_PLATFORM_IS_BIG_ENDIAN
+ buf[0] = (uint8_t) (v.i >> 0);
+ buf[1] = (uint8_t) (v.i >> 8);
+ buf[2] = (uint8_t) (v.i >> 16);
+ buf[3] = (uint8_t) (v.i >> 24);
+ AVRO_WRITE(writer, buf, 4);
+#else
+ AVRO_WRITE(writer, (void *)&v.i, 4);
+#endif
+ return 0;
+}
+
+static int64_t size_float(avro_writer_t writer, const float f)
+{
+ AVRO_UNUSED(writer);
+ AVRO_UNUSED(f);
+
+ return 4;
+}
+
+static int read_double(avro_reader_t reader, double *d)
+{
+#if AVRO_PLATFORM_IS_BIG_ENDIAN
+ uint8_t buf[8];
+#endif
+ union {
+ double d;
+ int64_t l;
+ } v;
+
+#if AVRO_PLATFORM_IS_BIG_ENDIAN
+ AVRO_READ(reader, buf, 8);
+ v.l = ((int64_t) buf[0] << 0)
+ | ((int64_t) buf[1] << 8)
+ | ((int64_t) buf[2] << 16)
+ | ((int64_t) buf[3] << 24)
+ | ((int64_t) buf[4] << 32)
+ | ((int64_t) buf[5] << 40)
+ | ((int64_t) buf[6] << 48) | ((int64_t) buf[7] << 56);
+#else
+ AVRO_READ(reader, (void *)&v.l, 8);
+#endif
+ *d = v.d;
+ return 0;
+}
+
+static int skip_double(avro_reader_t reader)
+{
+ AVRO_SKIP(reader, 8);
+ return 0;
+}
+
+static int write_double(avro_writer_t writer, const double d)
+{
+#if AVRO_PLATFORM_IS_BIG_ENDIAN
+ uint8_t buf[8];
+#endif
+ union {
+ double d;
+ int64_t l;
+ } v;
+
+ v.d = d;
+#if AVRO_PLATFORM_IS_BIG_ENDIAN
+ buf[0] = (uint8_t) (v.l >> 0);
+ buf[1] = (uint8_t) (v.l >> 8);
+ buf[2] = (uint8_t) (v.l >> 16);
+ buf[3] = (uint8_t) (v.l >> 24);
+ buf[4] = (uint8_t) (v.l >> 32);
+ buf[5] = (uint8_t) (v.l >> 40);
+ buf[6] = (uint8_t) (v.l >> 48);
+ buf[7] = (uint8_t) (v.l >> 56);
+ AVRO_WRITE(writer, buf, 8);
+#else
+ AVRO_WRITE(writer, (void *)&v.l, 8);
+#endif
+ return 0;
+}
+
+static int64_t size_double(avro_writer_t writer, const double d)
+{
+ AVRO_UNUSED(writer);
+ AVRO_UNUSED(d);
+
+ return 8;
+}
+
+static int read_boolean(avro_reader_t reader, int8_t * b)
+{
+ AVRO_READ(reader, b, 1);
+ return 0;
+}
+
+static int skip_boolean(avro_reader_t reader)
+{
+ AVRO_SKIP(reader, 1);
+ return 0;
+}
+
+static int write_boolean(avro_writer_t writer, const int8_t b)
+{
+ AVRO_WRITE(writer, (char *)&b, 1);
+ return 0;
+}
+
+static int64_t size_boolean(avro_writer_t writer, const int8_t b)
+{
+ AVRO_UNUSED(writer);
+ AVRO_UNUSED(b);
+
+ return 1;
+}
+
+static int read_skip_null(avro_reader_t reader)
+{
+ /*
+ * no-op
+ */
+ AVRO_UNUSED(reader);
+
+ return 0;
+}
+
+static int write_null(avro_writer_t writer)
+{
+ /*
+ * no-op
+ */
+ AVRO_UNUSED(writer);
+
+ return 0;
+}
+
+static int64_t size_null(avro_writer_t writer)
+{
+ AVRO_UNUSED(writer);
+
+ return 0;
+}
+
+/* Win32 doesn't support the C99 method of initializing named elements
+ * in a struct declaration. So hide the named parameters for Win32,
+ * and initialize in the order the code was written.
+ */
+const avro_encoding_t avro_binary_encoding = {
+ /* .description = */ "BINARY FORMAT",
+ /*
+ * string
+ */
+ /* .read_string = */ read_string,
+ /* .skip_string = */ skip_string,
+ /* .write_string = */ write_string,
+ /* .size_string = */ size_string,
+ /*
+ * bytes
+ */
+ /* .read_bytes = */ read_bytes,
+ /* .skip_bytes = */ skip_bytes,
+ /* .write_bytes = */ write_bytes,
+ /* .size_bytes = */ size_bytes,
+ /*
+ * int
+ */
+ /* .read_int = */ read_int,
+ /* .skip_int = */ skip_int,
+ /* .write_int = */ write_int,
+ /* .size_int = */ size_int,
+ /*
+ * long
+ */
+ /* .read_long = */ read_long,
+ /* .skip_long = */ skip_long,
+ /* .write_long = */ write_long,
+ /* .size_long = */ size_long,
+ /*
+ * float
+ */
+ /* .read_float = */ read_float,
+ /* .skip_float = */ skip_float,
+ /* .write_float = */ write_float,
+ /* .size_float = */ size_float,
+ /*
+ * double
+ */
+ /* .read_double = */ read_double,
+ /* .skip_double = */ skip_double,
+ /* .write_double = */ write_double,
+ /* .size_double = */ size_double,
+ /*
+ * boolean
+ */
+ /* .read_boolean = */ read_boolean,
+ /* .skip_boolean = */ skip_boolean,
+ /* .write_boolean = */ write_boolean,
+ /* .size_boolean = */ size_boolean,
+ /*
+ * null
+ */
+ /* .read_null = */ read_skip_null,
+ /* .skip_null = */ read_skip_null,
+ /* .write_null = */ write_null,
+ /* .size_null = */ size_null
+};