| /* |
| * 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 "avro/errors.h" |
| #include <stdlib.h> |
| #include <errno.h> |
| #include <string.h> |
| #include "encoding.h" |
| #include "schema.h" |
| |
| static int skip_array(avro_reader_t reader, const avro_encoding_t * enc, |
| struct avro_array_schema_t *writers_schema) |
| { |
| int rval; |
| int64_t i; |
| int64_t block_count; |
| int64_t block_size; |
| |
| check_prefix(rval, enc->read_long(reader, &block_count), |
| "Cannot read array block count: "); |
| |
| while (block_count != 0) { |
| if (block_count < 0) { |
| block_count = block_count * -1; |
| check_prefix(rval, enc->read_long(reader, &block_size), |
| "Cannot read array block size: "); |
| } |
| |
| for (i = 0; i < block_count; i++) { |
| check_prefix(rval, avro_skip_data(reader, writers_schema->items), |
| "Cannot skip array element: "); |
| } |
| |
| check_prefix(rval, enc->read_long(reader, &block_count), |
| "Cannot read array block count: "); |
| } |
| return 0; |
| } |
| |
| static int skip_map(avro_reader_t reader, const avro_encoding_t * enc, |
| struct avro_map_schema_t *writers_schema) |
| { |
| int rval; |
| int64_t i, block_count; |
| |
| check_prefix(rval, enc->read_long(reader, &block_count), |
| "Cannot read map block count: "); |
| while (block_count != 0) { |
| int64_t block_size; |
| if (block_count < 0) { |
| block_count = block_count * -1; |
| check_prefix(rval, enc->read_long(reader, &block_size), |
| "Cannot read map block size: "); |
| } |
| for (i = 0; i < block_count; i++) { |
| check_prefix(rval, enc->skip_string(reader), |
| "Cannot skip map key: "); |
| check_prefix(rval, |
| avro_skip_data(reader, |
| avro_schema_to_map(writers_schema)-> |
| values), |
| "Cannot skip map value: "); |
| } |
| check_prefix(rval, enc->read_long(reader, &block_count), |
| "Cannot read map block count: "); |
| } |
| return 0; |
| } |
| |
| static int skip_union(avro_reader_t reader, const avro_encoding_t * enc, |
| struct avro_union_schema_t *writers_schema) |
| { |
| int rval; |
| int64_t index; |
| avro_schema_t branch_schema; |
| |
| check_prefix(rval, enc->read_long(reader, &index), |
| "Cannot read union discriminant: "); |
| branch_schema = avro_schema_union_branch(&writers_schema->obj, index); |
| if (!branch_schema) { |
| return EILSEQ; |
| } |
| return avro_skip_data(reader, branch_schema); |
| } |
| |
| static int skip_record(avro_reader_t reader, const avro_encoding_t * enc, |
| struct avro_record_schema_t *writers_schema) |
| { |
| int rval; |
| long i; |
| |
| AVRO_UNUSED(enc); |
| |
| for (i = 0; i < writers_schema->fields->num_entries; i++) { |
| avro_schema_t field_schema; |
| |
| field_schema = avro_schema_record_field_get_by_index |
| (&writers_schema->obj, i); |
| check_prefix(rval, avro_skip_data(reader, field_schema), |
| "Cannot skip record field: "); |
| } |
| return 0; |
| } |
| |
| int avro_skip_data(avro_reader_t reader, avro_schema_t writers_schema) |
| { |
| check_param(EINVAL, reader, "reader"); |
| check_param(EINVAL, is_avro_schema(writers_schema), "writer schema"); |
| |
| int rval = EINVAL; |
| const avro_encoding_t *enc = &avro_binary_encoding; |
| |
| switch (avro_typeof(writers_schema)) { |
| case AVRO_NULL: |
| rval = enc->skip_null(reader); |
| break; |
| |
| case AVRO_BOOLEAN: |
| rval = enc->skip_boolean(reader); |
| break; |
| |
| case AVRO_STRING: |
| rval = enc->skip_string(reader); |
| break; |
| |
| case AVRO_INT32: |
| rval = enc->skip_int(reader); |
| break; |
| |
| case AVRO_INT64: |
| rval = enc->skip_long(reader); |
| break; |
| |
| case AVRO_FLOAT: |
| rval = enc->skip_float(reader); |
| break; |
| |
| case AVRO_DOUBLE: |
| rval = enc->skip_double(reader); |
| break; |
| |
| case AVRO_BYTES: |
| rval = enc->skip_bytes(reader); |
| break; |
| |
| case AVRO_FIXED: |
| rval = |
| avro_skip(reader, |
| avro_schema_to_fixed(writers_schema)->size); |
| break; |
| |
| case AVRO_ENUM: |
| rval = enc->skip_long(reader); |
| break; |
| |
| case AVRO_ARRAY: |
| rval = |
| skip_array(reader, enc, |
| avro_schema_to_array(writers_schema)); |
| break; |
| |
| case AVRO_MAP: |
| rval = |
| skip_map(reader, enc, avro_schema_to_map(writers_schema)); |
| break; |
| |
| case AVRO_UNION: |
| rval = |
| skip_union(reader, enc, |
| avro_schema_to_union(writers_schema)); |
| break; |
| |
| case AVRO_RECORD: |
| rval = |
| skip_record(reader, enc, |
| avro_schema_to_record(writers_schema)); |
| break; |
| |
| case AVRO_LINK: |
| rval = |
| avro_skip_data(reader, |
| (avro_schema_to_link(writers_schema))->to); |
| break; |
| } |
| |
| return rval; |
| } |