/* * 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 #include #include "avro/basics.h" #include "avro/io.h" #include "avro/value.h" #include "avro_private.h" #include "encoding.h" /* * Forward declaration; this is basically the same as avro_value_sizeof, * but it doesn't initialize size first. (Since it will have already * been initialized in avro_value_sizeof itself). */ static int sizeof_value(avro_value_t *src, size_t *size); static int sizeof_array_value(avro_value_t *src, size_t *size) { int rval; size_t element_count; check(rval, avro_value_get_size(src, &element_count)); if (element_count > 0) { *size += avro_binary_encoding.size_long(NULL, element_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, sizeof_value(&child, size)); } } *size += avro_binary_encoding.size_long(NULL, 0); return 0; } static int sizeof_map_value(avro_value_t *src, size_t *size) { int rval; size_t element_count; check(rval, avro_value_get_size(src, &element_count)); if (element_count > 0) { *size += avro_binary_encoding.size_long(NULL, element_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)); *size += avro_binary_encoding.size_string(NULL, key); check(rval, sizeof_value(&child, size)); } } *size += avro_binary_encoding.size_long(NULL, 0); return 0; } static int sizeof_record_value(avro_value_t *src, size_t *size) { 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, sizeof_value(&field, size)); } return 0; } static int sizeof_union_value(avro_value_t *src, size_t *size) { 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)); *size += avro_binary_encoding.size_long(NULL, discriminant); return sizeof_value(&branch, size); } static int sizeof_value(avro_value_t *src, size_t *size) { int rval; switch (avro_value_get_type(src)) { case AVRO_BOOLEAN: { int val; check(rval, avro_value_get_boolean(src, &val)); *size += avro_binary_encoding.size_boolean(NULL, val); return 0; } case AVRO_BYTES: { const void *buf; size_t sz; check(rval, avro_value_get_bytes(src, &buf, &sz)); *size += avro_binary_encoding.size_bytes(NULL, (const char *) buf, sz); return 0; } case AVRO_DOUBLE: { double val; check(rval, avro_value_get_double(src, &val)); *size += avro_binary_encoding.size_double(NULL, val); return 0; } case AVRO_FLOAT: { float val; check(rval, avro_value_get_float(src, &val)); *size += avro_binary_encoding.size_float(NULL, val); return 0; } case AVRO_INT32: { int32_t val; check(rval, avro_value_get_int(src, &val)); *size += avro_binary_encoding.size_long(NULL, val); return 0; } case AVRO_INT64: { int64_t val; check(rval, avro_value_get_long(src, &val)); *size += avro_binary_encoding.size_long(NULL, val); return 0; } case AVRO_NULL: { check(rval, avro_value_get_null(src)); *size += avro_binary_encoding.size_null(NULL); return 0; } case AVRO_STRING: { const char *str; size_t sz; check(rval, avro_value_get_string(src, &str, &sz)); *size += avro_binary_encoding.size_bytes(NULL, str, sz-1); return 0; } case AVRO_ARRAY: return sizeof_array_value(src, size); case AVRO_ENUM: { int val; check(rval, avro_value_get_enum(src, &val)); *size += avro_binary_encoding.size_long(NULL, val); return 0; } case AVRO_FIXED: { size_t sz; check(rval, avro_value_get_fixed(src, NULL, &sz)); *size += sz; return 0; } case AVRO_MAP: return sizeof_map_value(src, size); case AVRO_RECORD: return sizeof_record_value(src, size); case AVRO_UNION: return sizeof_union_value(src, size); default: { avro_set_error("Unknown schema type"); return EINVAL; } } return 0; } int avro_value_sizeof(avro_value_t *src, size_t *size) { check_param(EINVAL, size, "size pointer"); *size = 0; return sizeof_value(src, size); }