blob: 947ce801c434bea4436eb1ed51b320bc862d6666 [file] [log] [blame]
/*
* 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/platform.h>
#include <stdlib.h>
#include "avro/basics.h"
#include "avro/io.h"
#include "avro/value.h"
#include "avro_private.h"
#include "encoding.h"
static int
write_array_value(avro_writer_t writer, avro_value_t *src)
{
int rval;
size_t element_count;
check(rval, avro_value_get_size(src, &element_count));
if (element_count > 0) {
check_prefix(rval, avro_binary_encoding.write_long
(writer, element_count),
"Cannot write array block count: ");
size_t i;
for (i = 0; i < element_count; i++) {
avro_value_t child;
check(rval, avro_value_get_by_index(src, i, &child, NULL));
check(rval, avro_value_write(writer, &child));
}
}
check_prefix(rval, avro_binary_encoding.write_long(writer, 0),
"Cannot write array block count: ");
return 0;
}
static int
write_map_value(avro_writer_t writer, avro_value_t *src)
{
int rval;
size_t element_count;
check(rval, avro_value_get_size(src, &element_count));
if (element_count > 0) {
check_prefix(rval, avro_binary_encoding.write_long
(writer, element_count),
"Cannot write map block count: ");
size_t i;
for (i = 0; i < element_count; i++) {
avro_value_t child;
const char *key;
check(rval, avro_value_get_by_index(src, i, &child, &key));
check(rval, avro_binary_encoding.write_string(writer, key));
check(rval, avro_value_write(writer, &child));
}
}
check_prefix(rval, avro_binary_encoding.write_long(writer, 0),
"Cannot write map block count: ");
return 0;
}
static int
write_record_value(avro_writer_t writer, avro_value_t *src)
{
int rval;
size_t field_count;
check(rval, avro_value_get_size(src, &field_count));
size_t i;
for (i = 0; i < field_count; i++) {
avro_value_t field;
check(rval, avro_value_get_by_index(src, i, &field, NULL));
check(rval, avro_value_write(writer, &field));
}
return 0;
}
static int
write_union_value(avro_writer_t writer, avro_value_t *src)
{
int rval;
int discriminant;
avro_value_t branch;
check(rval, avro_value_get_discriminant(src, &discriminant));
check(rval, avro_value_get_current_branch(src, &branch));
check(rval, avro_binary_encoding.write_long(writer, discriminant));
return avro_value_write(writer, &branch);
}
int
avro_value_write(avro_writer_t writer, avro_value_t *src)
{
int rval;
switch (avro_value_get_type(src)) {
case AVRO_BOOLEAN:
{
int val;
check(rval, avro_value_get_boolean(src, &val));
return avro_binary_encoding.write_boolean(writer, val);
}
case AVRO_BYTES:
{
const void *buf;
size_t size;
check(rval, avro_value_get_bytes(src, &buf, &size));
return avro_binary_encoding.write_bytes(writer, (const char *) buf, size);
}
case AVRO_DOUBLE:
{
double val;
check(rval, avro_value_get_double(src, &val));
return avro_binary_encoding.write_double(writer, val);
}
case AVRO_FLOAT:
{
float val;
check(rval, avro_value_get_float(src, &val));
return avro_binary_encoding.write_float(writer, val);
}
case AVRO_INT32:
{
int32_t val;
check(rval, avro_value_get_int(src, &val));
return avro_binary_encoding.write_long(writer, val);
}
case AVRO_INT64:
{
int64_t val;
check(rval, avro_value_get_long(src, &val));
return avro_binary_encoding.write_long(writer, val);
}
case AVRO_NULL:
{
check(rval, avro_value_get_null(src));
return avro_binary_encoding.write_null(writer);
}
case AVRO_STRING:
{
const char *str;
size_t size;
check(rval, avro_value_get_string(src, &str, &size));
return avro_binary_encoding.write_bytes(writer, str, size-1);
}
case AVRO_ARRAY:
return write_array_value(writer, src);
case AVRO_ENUM:
{
int val;
check(rval, avro_value_get_enum(src, &val));
return avro_binary_encoding.write_long(writer, val);
}
case AVRO_FIXED:
{
const void *buf;
size_t size;
check(rval, avro_value_get_fixed(src, &buf, &size));
return avro_write(writer, (void *) buf, size);
}
case AVRO_MAP:
return write_map_value(writer, src);
case AVRO_RECORD:
return write_record_value(writer, src);
case AVRO_UNION:
return write_union_value(writer, src);
default:
{
avro_set_error("Unknown schema type");
return EINVAL;
}
}
return 0;
}