Author: massie
Date: Fri Nov 20 04:57:17 2009
New Revision: 882414
URL: http://svn.apache.org/viewvc?rev=882414&view=rev
Log:
AVRO-224. Code cleanup: cleaner distinction between public and private methods
Added:
hadoop/avro/trunk/src/c/avro_private.c
hadoop/avro/trunk/src/c/datatypes/primitives.c
Removed:
hadoop/avro/trunk/src/c/avro_primitives.c
hadoop/avro/trunk/src/c/avro_value.c
Modified:
hadoop/avro/trunk/CHANGES.txt
hadoop/avro/trunk/src/c/Makefile.am
hadoop/avro/trunk/src/c/avro.c
hadoop/avro/trunk/src/c/avro.h
Modified: hadoop/avro/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/CHANGES.txt?rev=882414&r1=882413&r2=882414&view=diff
==============================================================================
--- hadoop/avro/trunk/CHANGES.txt (original)
+++ hadoop/avro/trunk/CHANGES.txt Fri Nov 20 04:57:17 2009
@@ -132,6 +132,9 @@
AVRO-223. Fix test-avroj on Mac OS X. (Philip Zeyliger via cutting)
+ AVRO-224. Code cleanup: cleaner distinction between public and private
+ methods (massie)
+
Avro 1.2.0 (14 October 2009)
INCOMPATIBLE CHANGES
Modified: hadoop/avro/trunk/src/c/Makefile.am
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/Makefile.am?rev=882414&r1=882413&r2=882414&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c/Makefile.am (original)
+++ hadoop/avro/trunk/src/c/Makefile.am Fri Nov 20 04:57:17 2009
@@ -10,7 +10,7 @@
include_HEADERS = avro.h
lib_LTLIBRARIES = libavro.la
-libavro_la_SOURCES = avro.h avro_private.h avro.c avro_value.c
avro_primitives.c \
+libavro_la_SOURCES = avro.h avro_private.h avro.c avro_private.c \
json/json_parser.c json/json_parser.h json/json_tokenizer.c \
json/json.c json/json.h json/json_tokenizer.h \
util/dump.c util/dump.h util/error.c util/error.h \
@@ -18,7 +18,7 @@
datatypes/array.c datatypes/boolean.c datatypes/bytes.c datatypes/double.c \
datatypes/enum.c datatypes/fixed.c datatypes/float.c datatypes/int.c
datatypes/long.c \
datatypes/map.c datatypes/null.c datatypes/record.c datatypes/string.c
datatypes/union.c \
-datatypes/decorator.c \
+datatypes/decorator.c datatypes/primitives.c \
io/file.c io/socket.c io/memory.c io/file_container.c
libavro_la_LDFLAGS = \
-version-info $(LIBAVRO_VERSION) \
Modified: hadoop/avro/trunk/src/c/avro.c
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/avro.c?rev=882414&r1=882413&r2=882414&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c/avro.c (original)
+++ hadoop/avro/trunk/src/c/avro.c Fri Nov 20 04:57:17 2009
@@ -17,83 +17,19 @@
under the License.
*/
+#include "avro.h"
#include "avro_private.h"
-#include <stdlib.h>
#include <locale.h>
-#include "apr_pools.h"
-#include "apr_file_io.h"
-#include "apr_file_info.h"
-char *
-avro_util_file_read_full (apr_pool_t * pool, const char *fname,
- apr_size_t * len)
-{
- apr_status_t status;
- apr_finfo_t finfo;
- apr_file_t *file;
- char *rval;
- apr_size_t bytes_read;
-
- /* open the file */
- status = apr_file_open (&file, fname, APR_READ, 0, pool);
- if (status != APR_SUCCESS)
- {
- return NULL;
- }
-
- /* get the file length */
- status = apr_file_info_get (&finfo, APR_FINFO_SIZE, file);
- if (status != APR_SUCCESS)
- {
- return NULL;
- }
-
- /* alloc space for the data */
- rval = apr_palloc (pool, finfo.size + 1);
- if (!rval)
- {
- return NULL;
- }
-
- /* read in the data */
- status = apr_file_read_full (file, rval, finfo.size, &bytes_read);
- if (status != APR_SUCCESS)
- {
- return NULL;
- }
- rval[finfo.size] = '\0';
-
- if (len)
- {
- *len = bytes_read;
- }
- return rval;
-}
-
-/* Helper utility for reading an attribute from a JSON object */
-const JSON_value *
-json_attr_get (const JSON_value * obj, const wchar_t * key)
+avro_status_t
+avro_value_type (avro_value value, avro_type_t * type)
{
- apr_ssize_t klen;
- apr_hash_t *table;
-
- if (!obj || !key || obj->type != JSON_OBJECT)
+ if (!value || !type)
{
- return NULL;
+ return AVRO_FAILURE;
}
-
- table = obj->json_object;
- klen = wcslen (key) * sizeof (wchar_t);
- return apr_hash_get (table, key, klen);
-}
-
-/* Helper utility for reading an attribute from JSON w/type checking */
-const JSON_value *
-json_attr_get_check_type (const JSON_value * obj, const wchar_t * key,
- JSON_type type)
-{
- const JSON_value *value = json_attr_get (obj, key);
- return value && value->type == type ? value : NULL;
+ *type = value->type;
+ return AVRO_OK;
}
avro_status_t
@@ -110,14 +46,3 @@
return AVRO_OK;
}
-
-/* Helper to print indent before a value */
-void
-avro_value_indent (struct avro_value *value, FILE * fp)
-{
- struct avro_value *cur;
- for (cur = value->parent; cur; cur = cur->parent)
- {
- fprintf (fp, " ");
- }
-}
Modified: hadoop/avro/trunk/src/c/avro.h
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/avro.h?rev=882414&r1=882413&r2=882414&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c/avro.h (original)
+++ hadoop/avro/trunk/src/c/avro.h Fri Nov 20 04:57:17 2009
@@ -96,6 +96,8 @@
typedef struct avro_value * avro_value;
+avro_status_t avro_initialize (void);
+
avro_status_t avro_value_type(avro_value value, avro_type_t *type);
#ifdef __cplusplus
Added: hadoop/avro/trunk/src/c/avro_private.c
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/avro_private.c?rev=882414&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/avro_private.c (added)
+++ hadoop/avro/trunk/src/c/avro_private.c Fri Nov 20 04:57:17 2009
@@ -0,0 +1,300 @@
+/*
+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
+
+http://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 <stdlib.h>
+#include "apr_pools.h"
+#include "apr_file_io.h"
+#include "apr_file_info.h"
+
+extern const struct avro_value_module avro_string_module;
+extern const struct avro_value_module avro_bytes_module;
+extern const struct avro_value_module avro_int_module;
+extern const struct avro_value_module avro_long_module;
+extern const struct avro_value_module avro_float_module;
+extern const struct avro_value_module avro_double_module;
+extern const struct avro_value_module avro_boolean_module;
+extern const struct avro_value_module avro_null_module;
+extern const struct avro_value_module avro_record_module;
+extern const struct avro_value_module avro_field_module;
+extern const struct avro_value_module avro_enum_module;
+extern const struct avro_value_module avro_fixed_module;
+extern const struct avro_value_module avro_map_module;
+extern const struct avro_value_module avro_array_module;
+extern const struct avro_value_module avro_union_module;
+extern const struct avro_value_module avro_decorator_module;
+/* WARNING! This registry needs to match avro_type and avro_private_type
enums! */
+const struct avro_value_module *avro_value_registry[AVRO_NUM_PRIVATE_TYPES] = {
+ &avro_string_module,
+ &avro_bytes_module,
+ &avro_int_module,
+ &avro_long_module,
+ &avro_float_module,
+ &avro_double_module,
+ &avro_boolean_module,
+ &avro_null_module,
+ &avro_record_module,
+ &avro_enum_module,
+ &avro_fixed_module,
+ &avro_map_module,
+ &avro_array_module,
+ &avro_union_module,
+ &avro_field_module,
+ &avro_decorator_module
+};
+
+/* TODO: gperf this? */
+static avro_status_t
+avro_type_lookup (const avro_string_t name, avro_type_t * type)
+{
+ int i;
+ if (name)
+ {
+ for (i = 0; i < AVRO_NUM_TYPES; i++)
+ {
+ const struct avro_value_module *info = avro_value_registry[i];
+ if (!info->private && wcscmp (info->name, name) == 0)
+ {
+ *type = info->type;
+ return AVRO_OK;
+ }
+ }
+ }
+ return AVRO_FAILURE;
+}
+
+static avro_status_t
+avro_type_from_json (const JSON_value * json, avro_type_t * type)
+{
+ if (!json)
+ {
+ return AVRO_FAILURE;
+ }
+
+ if (json->type == JSON_STRING)
+ {
+ return avro_type_lookup (json->json_string, type);
+ }
+ else if (json->type == JSON_ARRAY)
+ {
+ *type = AVRO_UNION;
+ return AVRO_OK;
+ }
+ else if (json->type == JSON_OBJECT)
+ {
+ const JSON_value *type_attr =
+ json_attr_get_check_type (json, L"type", JSON_STRING);
+ if (type_attr)
+ {
+ return avro_type_lookup (type_attr->json_string, type);
+ }
+ }
+
+ return AVRO_FAILURE;
+}
+
+struct avro_value *
+avro_value_from_json (struct avro_value_ctx *ctx,
+ struct avro_value *parent, const JSON_value * json)
+{
+ avro_status_t avro_status;
+ apr_status_t status;
+ avro_type_t avro_type;
+ apr_pool_t *subpool;
+ const JSON_value *schema = json;
+
+ status = apr_pool_create (&subpool, parent ? parent->pool : NULL);
+ if (status != APR_SUCCESS)
+ {
+ return NULL;
+ }
+
+ avro_status = avro_type_from_json (schema, &avro_type);
+ if (avro_status != AVRO_OK)
+ {
+ if (!ctx || json->type != JSON_STRING)
+ {
+ return NULL;
+ }
+ schema =
+ apr_hash_get (ctx->named_objects, json->json_string,
+ wcslen (json->json_string) * sizeof (wchar_t));
+ if (!schema)
+ {
+ return NULL;
+ }
+ avro_type = AVRO_DECORATOR;
+ }
+
+ return avro_value_registry[avro_type]->create (ctx, parent, subpool,
+ schema);
+}
+
+struct avro_value *
+avro_value_create (apr_pool_t * pool, char *jsontext, apr_size_t textlen)
+{
+ struct avro_value_ctx *ctx;
+
+ const JSON_value *json = JSON_parse (pool, jsontext, textlen);
+ if (!json)
+ {
+ return NULL;
+ }
+
+ ctx =
+ (struct avro_value_ctx *) apr_palloc (pool,
+ sizeof (struct avro_value_ctx));
+ if (!ctx)
+ {
+ return NULL;
+ }
+
+ ctx->named_objects = apr_hash_make (pool);
+ if (!ctx->named_objects)
+ {
+ return NULL;
+ }
+
+ return avro_value_from_json (ctx, NULL, json);
+}
+
+avro_status_t
+avro_value_read_data (struct avro_value * value, struct avro_reader * reader)
+{
+ if (!value || !reader)
+ {
+ return AVRO_FAILURE;
+ }
+ return avro_value_registry[value->type]->formats[reader->format].
+ read_data (value, reader);
+}
+
+avro_status_t
+avro_value_skip_data (struct avro_value * value, struct avro_reader * reader)
+{
+ if (!value || !reader)
+ {
+ return AVRO_FAILURE;
+ }
+ return avro_value_registry[value->type]->formats[reader->format].
+ skip_data (value, reader);
+}
+
+avro_status_t
+avro_value_write_data (struct avro_value * value, struct avro_writer * writer)
+{
+ if (!value || !writer)
+ {
+ return AVRO_FAILURE;
+ }
+ return avro_value_registry[value->type]->formats[writer->format].
+ write_data (value, writer);
+}
+
+void
+avro_value_print_info (struct avro_value *value, FILE * fp)
+{
+ if (!value || !fp)
+ {
+ return;
+ }
+ avro_value_registry[value->type]->print_info (value, fp);
+}
+
+char *
+avro_util_file_read_full (apr_pool_t * pool, const char *fname,
+ apr_size_t * len)
+{
+ apr_status_t status;
+ apr_finfo_t finfo;
+ apr_file_t *file;
+ char *rval;
+ apr_size_t bytes_read;
+
+ /* open the file */
+ status = apr_file_open (&file, fname, APR_READ, 0, pool);
+ if (status != APR_SUCCESS)
+ {
+ return NULL;
+ }
+
+ /* get the file length */
+ status = apr_file_info_get (&finfo, APR_FINFO_SIZE, file);
+ if (status != APR_SUCCESS)
+ {
+ return NULL;
+ }
+
+ /* alloc space for the data */
+ rval = apr_palloc (pool, finfo.size + 1);
+ if (!rval)
+ {
+ return NULL;
+ }
+
+ /* read in the data */
+ status = apr_file_read_full (file, rval, finfo.size, &bytes_read);
+ if (status != APR_SUCCESS)
+ {
+ return NULL;
+ }
+ rval[finfo.size] = '\0';
+
+ if (len)
+ {
+ *len = bytes_read;
+ }
+ return rval;
+}
+
+/* Helper utility for reading an attribute from a JSON object */
+const JSON_value *
+json_attr_get (const JSON_value * obj, const wchar_t * key)
+{
+ apr_ssize_t klen;
+ apr_hash_t *table;
+
+ if (!obj || !key || obj->type != JSON_OBJECT)
+ {
+ return NULL;
+ }
+
+ table = obj->json_object;
+ klen = wcslen (key) * sizeof (wchar_t);
+ return apr_hash_get (table, key, klen);
+}
+
+/* Helper utility for reading an attribute from JSON w/type checking */
+const JSON_value *
+json_attr_get_check_type (const JSON_value * obj, const wchar_t * key,
+ JSON_type type)
+{
+ const JSON_value *value = json_attr_get (obj, key);
+ return value && value->type == type ? value : NULL;
+}
+
+/* Helper to print indent before a value */
+void
+avro_value_indent (struct avro_value *value, FILE * fp)
+{
+ struct avro_value *cur;
+ for (cur = value->parent; cur; cur = cur->parent)
+ {
+ fprintf (fp, " ");
+ }
+}
Added: hadoop/avro/trunk/src/c/datatypes/primitives.c
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/datatypes/primitives.c?rev=882414&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/datatypes/primitives.c (added)
+++ hadoop/avro/trunk/src/c/datatypes/primitives.c Fri Nov 20 04:57:17 2009
@@ -0,0 +1,371 @@
+/*
+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
+
+http://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 <stdlib.h>
+
+avro_status_t
+avro_write_string (struct avro_io_writer *io, apr_pool_t * pool,
+ avro_string_t string)
+{
+ avro_status_t status;
+ size_t wc_len, converted;
+ avro_long_t len;
+ char *s;
+ if (!io)
+ {
+ return AVRO_FAILURE;
+ }
+ wc_len = wcslen ((const wchar_t *) string);
+
+ /* TODO: how to calculate the number of char needed for wc_len
+ assuming max for now */
+ s = apr_pcalloc (pool, wc_len * 4);
+ if (!s)
+ {
+ return AVRO_FAILURE;
+ }
+
+ converted = wcstombs (s, string, wc_len * 4);
+ if (converted < 0)
+ {
+ return AVRO_FAILURE;
+ }
+ len = converted;
+ status = avro_write_long (io, &len);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ return io->write (io, s, len);
+}
+
+avro_status_t
+avro_read_string (struct avro_io_reader * io, apr_pool_t * pool,
+ avro_string_t * string)
+{
+ avro_status_t status;
+ avro_long_t len;
+ size_t converted;
+ char *s;
+
+ if (!io || !pool || !string)
+ {
+ return AVRO_FAILURE;
+ }
+ status = avro_read_long (io, &len);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ if (len < 0)
+ {
+ return AVRO_FAILURE;
+ }
+ s = apr_pcalloc (pool, len + 1);
+ if (!s)
+ {
+ return AVRO_FAILURE;
+ }
+ status = io->read (io, (void *) s, len);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ s[len] = '\0';
+
+ /* TODO: calculate this more exactly... assuming char len == wchar len is
wrong */
+ *string = apr_pcalloc (pool, (len + 1) * sizeof (wchar_t));
+ if (!*string)
+ {
+ return AVRO_FAILURE;
+ }
+ converted = mbstowcs (*string, s, len);
+ if (converted < 0)
+ {
+ return AVRO_FAILURE;
+ }
+ (*string)[converted] = '\0';
+ return AVRO_OK;
+}
+
+avro_status_t
+avro_write_bytes (struct avro_io_writer * io, void *data, avro_long_t len)
+{
+ avro_status_t status;
+ if (!io || !data || len < 0)
+ {
+ return AVRO_FAILURE;
+ }
+ status = avro_write_long (io, &len);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ return io->write (io, data, len);
+}
+
+avro_status_t
+avro_read_bytes (struct avro_io_reader * io, apr_pool_t * pool, void **data,
+ avro_long_t * len)
+{
+ avro_status_t status;
+ if (!io || !pool || !data || !len)
+ {
+ return AVRO_FAILURE;
+ }
+ status = avro_read_long (io, len);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ *data = apr_pcalloc (pool, *len);
+ if (!*data)
+ {
+ return AVRO_FAILURE;
+ }
+ return io->read (io, *data, *len);
+}
+
+avro_status_t
+avro_write_bool (struct avro_io_writer * io, int boolean)
+{
+ char b;
+ if (!io)
+ {
+ return AVRO_FAILURE;
+ }
+ b = boolean;
+ return io->write (io, &b, 1);
+}
+
+avro_status_t
+avro_read_bool (struct avro_io_reader * io, int *boolean)
+{
+ avro_status_t status;
+ char b;
+ if (!io || !boolean)
+ {
+ return AVRO_FAILURE;
+ }
+ status = io->read (io, &b, 1);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ *boolean = b;
+ return AVRO_OK;
+}
+
+avro_status_t
+avro_write_int (struct avro_io_writer * io, avro_int_t * ip)
+{
+ avro_status_t status;
+ uint32_t n;
+ uint8_t b;
+
+ if (!io || !ip)
+ {
+ return AVRO_FAILURE;
+ }
+
+ n = (*ip << 1) ^ (*ip >> 31);
+ while ((n & ~0x7F) != 0)
+ {
+ b = ((((uint8_t) n) & 0x7F) | 0x80);
+ status = io->write (io, (void *) &b, 1);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ n >>= 7;
+ }
+
+ b = (uint8_t) n;
+ return io->write (io, (void *) &b, 1);
+}
+
+avro_status_t
+avro_write_long (struct avro_io_writer *io, avro_long_t * lp)
+{
+ avro_status_t status;
+ uint64_t n;
+ uint8_t b;
+
+ if (!io || !lp)
+ {
+ return AVRO_FAILURE;
+ }
+
+ n = (*lp << 1) ^ (*lp >> 63);
+ while ((n & ~0x7F) != 0)
+ {
+ b = ((((uint8_t) n) & 0x7F) | 0x80);
+ status = io->write (io, (void *) &b, 1);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ n >>= 7;
+ }
+ b = (uint8_t) n;
+ return io->write (io, (void *) &b, 1);
+}
+
+avro_status_t
+avro_read_int (struct avro_io_reader *io, avro_int_t * ip)
+{
+ avro_status_t status;
+ uint32_t value = 0;
+ int offset = 0;
+ uint8_t b;
+ const int MAX_VARINT_BUF_SIZE = 5;
+
+ if (!io || !ip)
+ {
+ return AVRO_FAILURE;
+ }
+
+ do
+ {
+ if (offset == MAX_VARINT_BUF_SIZE)
+ {
+ return AVRO_FAILURE;
+ }
+ status = io->read (io, (char *) &b, 1);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ value |= (int32_t) (b & 0x7F) << (7 * offset);
+ ++offset;
+ }
+ while (b & 0x80);
+ *ip = (value >> 1) ^ -(value & 1);
+ return AVRO_OK;
+}
+
+avro_status_t
+avro_read_long (struct avro_io_reader * io, avro_long_t * lp)
+{
+ avro_status_t status;
+ uint64_t value = 0;
+ int offset = 0;
+ uint8_t b;
+ const int MAX_VARINT_BUF_SIZE = 10;
+
+ if (!io || !lp)
+ {
+ return AVRO_FAILURE;
+ }
+
+ do
+ {
+ if (offset == MAX_VARINT_BUF_SIZE)
+ {
+ return AVRO_FAILURE;
+ }
+ status = io->read (io, (char *) &b, 1);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ value |= (int64_t) (b & 0x7F) << (7 * offset);
+ ++offset;
+ }
+ while (b & 0x80);
+ *lp = (value >> 1) ^ -(value & 1);
+ return AVRO_OK;
+}
+
+avro_status_t
+avro_write_float (struct avro_io_writer * io, float value)
+{
+ union
+ {
+ float f;
+ int32_t i;
+ } v;
+ if (!io)
+ {
+ return AVRO_FAILURE;
+ }
+ v.f = value;
+ return avro_write_int32_le (io, (const int32_t) v.i);
+}
+
+avro_status_t
+avro_read_float (struct avro_io_reader *io, float *fp)
+{
+ avro_status_t status;
+ union
+ {
+ float f;
+ int32_t i;
+ } v;
+ if (!io || !fp)
+ {
+ return AVRO_FAILURE;
+ }
+ status = avro_read_int32_le (io, &v.i);
+ if (status != AVRO_OK)
+ {
+ return status;
+ }
+ *fp = v.f;
+ return AVRO_OK;
+}
+
+avro_status_t
+avro_write_double (struct avro_io_writer * io, double value)
+{
+ union
+ {
+ double d;
+ int64_t i;
+ } v;
+ if (!io)
+ {
+ return AVRO_FAILURE;
+ }
+ v.d = value;
+ return avro_write_int64_le (io, v.i);
+}
+
+avro_status_t
+avro_read_double (struct avro_io_reader * io, double *dp)
+{
+ avro_status_t status;
+ union
+ {
+ double d;
+ int64_t i;
+ } v;
+ if (!io || !dp)
+ {
+ return AVRO_FAILURE;
+ }
+ status = avro_read_int64_le (io, &v.i);
+ if (status != AVRO_OK)
+ {
+ return AVRO_FAILURE;
+ }
+ *dp = v.d;
+ return AVRO_OK;
+}