| /* |
| * 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. |
| */ |
| package org.apache.avro.io; |
| |
| import java.io.IOException; |
| import java.nio.ByteBuffer; |
| |
| import org.apache.avro.util.Utf8; |
| |
| /** |
| * Low-level support for de-serializing Avro values. |
| * <p/> |
| * This class has two types of methods. One type of methods support the reading |
| * of leaf values (for example, {@link #readLong} and {@link #readString}). |
| * <p/> |
| * The other type of methods support the reading of maps and arrays. These |
| * methods are {@link #readArrayStart}, {@link #arrayNext}, and similar methods |
| * for maps). See {@link #readArrayStart} for details on these methods.) |
| * <p/> |
| * {@link DecoderFactory} contains Decoder construction and configuration |
| * facilities. |
| * |
| * @see DecoderFactory |
| * @see Encoder |
| */ |
| |
| public abstract class Decoder { |
| |
| /** |
| * "Reads" a null value. (Doesn't actually read anything, but advances the state |
| * of the parser if the implementation is stateful.) |
| * |
| * @throws AvroTypeException If this is a stateful reader and null is not the |
| * type of the next value to be read |
| */ |
| public abstract void readNull() throws IOException; |
| |
| /** |
| * Reads a boolean value written by {@link Encoder#writeBoolean}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and boolean is not the |
| * type of the next value to be read |
| */ |
| |
| public abstract boolean readBoolean() throws IOException; |
| |
| /** |
| * Reads an integer written by {@link Encoder#writeInt}. |
| * |
| * @throws AvroTypeException If encoded value is larger than 32-bits |
| * @throws AvroTypeException If this is a stateful reader and int is not the |
| * type of the next value to be read |
| */ |
| public abstract int readInt() throws IOException; |
| |
| /** |
| * Reads a long written by {@link Encoder#writeLong}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and long is not the |
| * type of the next value to be read |
| */ |
| public abstract long readLong() throws IOException; |
| |
| /** |
| * Reads a float written by {@link Encoder#writeFloat}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and is not the type of |
| * the next value to be read |
| */ |
| public abstract float readFloat() throws IOException; |
| |
| /** |
| * Reads a double written by {@link Encoder#writeDouble}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and is not the type of |
| * the next value to be read |
| */ |
| public abstract double readDouble() throws IOException; |
| |
| /** |
| * Reads a char-string written by {@link Encoder#writeString}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and char-string is not |
| * the type of the next value to be read |
| */ |
| public abstract Utf8 readString(Utf8 old) throws IOException; |
| |
| /** |
| * Reads a char-string written by {@link Encoder#writeString}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and char-string is not |
| * the type of the next value to be read |
| */ |
| public abstract String readString() throws IOException; |
| |
| /** |
| * Discards a char-string written by {@link Encoder#writeString}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and char-string is not |
| * the type of the next value to be read |
| */ |
| public abstract void skipString() throws IOException; |
| |
| /** |
| * Reads a byte-string written by {@link Encoder#writeBytes}. if <tt>old</tt> is |
| * not null and has sufficient capacity to take in the bytes being read, the |
| * bytes are returned in <tt>old</tt>. |
| * |
| * @throws AvroTypeException If this is a stateful reader and byte-string is not |
| * the type of the next value to be read |
| */ |
| public abstract ByteBuffer readBytes(ByteBuffer old) throws IOException; |
| |
| /** |
| * Discards a byte-string written by {@link Encoder#writeBytes}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and byte-string is not |
| * the type of the next value to be read |
| */ |
| public abstract void skipBytes() throws IOException; |
| |
| /** |
| * Reads fixed sized binary object. |
| * |
| * @param bytes The buffer to store the contents being read. |
| * @param start The position where the data needs to be written. |
| * @param length The size of the binary object. |
| * @throws AvroTypeException If this is a stateful reader and fixed sized binary |
| * object is not the type of the next value to be read |
| * or the length is incorrect. |
| * @throws IOException |
| */ |
| public abstract void readFixed(byte[] bytes, int start, int length) throws IOException; |
| |
| /** |
| * A shorthand for <tt>readFixed(bytes, 0, bytes.length)</tt>. |
| * |
| * @throws AvroTypeException If this is a stateful reader and fixed sized binary |
| * object is not the type of the next value to be read |
| * or the length is incorrect. |
| * @throws IOException |
| */ |
| public void readFixed(byte[] bytes) throws IOException { |
| readFixed(bytes, 0, bytes.length); |
| } |
| |
| /** |
| * Discards fixed sized binary object. |
| * |
| * @param length The size of the binary object to be skipped. |
| * @throws AvroTypeException If this is a stateful reader and fixed sized binary |
| * object is not the type of the next value to be read |
| * or the length is incorrect. |
| * @throws IOException |
| */ |
| public abstract void skipFixed(int length) throws IOException; |
| |
| /** |
| * Reads an enumeration. |
| * |
| * @return The enumeration's value. |
| * @throws AvroTypeException If this is a stateful reader and enumeration is not |
| * the type of the next value to be read. |
| * @throws IOException |
| */ |
| public abstract int readEnum() throws IOException; |
| |
| /** |
| * Reads and returns the size of the first block of an array. If this method |
| * returns non-zero, then the caller should read the indicated number of items, |
| * and then call {@link #arrayNext} to find out the number of items in the next |
| * block. The typical pattern for consuming an array looks like: |
| * |
| * <pre> |
| * for(long i = in.readArrayStart(); i != 0; i = in.arrayNext()) { |
| * for (long j = 0; j < i; j++) { |
| * read next element of the array; |
| * } |
| * } |
| * </pre> |
| * |
| * @throws AvroTypeException If this is a stateful reader and array is not the |
| * type of the next value to be read |
| */ |
| public abstract long readArrayStart() throws IOException; |
| |
| /** |
| * Processes the next block of an array and returns the number of items in the |
| * block and let's the caller read those items. |
| * |
| * @throws AvroTypeException When called outside of an array context |
| */ |
| public abstract long arrayNext() throws IOException; |
| |
| /** |
| * Used for quickly skipping through an array. Note you can either skip the |
| * entire array, or read the entire array (with {@link #readArrayStart}), but |
| * you can't mix the two on the same array. |
| * |
| * This method will skip through as many items as it can, all of them if |
| * possible. It will return zero if there are no more items to skip through, or |
| * an item count if it needs the client's help in skipping. The typical usage |
| * pattern is: |
| * |
| * <pre> |
| * for(long i = in.skipArray(); i != 0; i = i.skipArray()) { |
| * for (long j = 0; j < i; j++) { |
| * read and discard the next element of the array; |
| * } |
| * } |
| * </pre> |
| * |
| * Note that this method can automatically skip through items if a byte-count is |
| * found in the underlying data, or if a schema has been provided to the |
| * implementation, but otherwise the client will have to skip through items |
| * itself. |
| * |
| * @throws AvroTypeException If this is a stateful reader and array is not the |
| * type of the next value to be read |
| */ |
| public abstract long skipArray() throws IOException; |
| |
| /** |
| * Reads and returns the size of the next block of map-entries. Similar to |
| * {@link #readArrayStart}. |
| * |
| * As an example, let's say you want to read a map of records, the record |
| * consisting of an Long field and a Boolean field. Your code would look |
| * something like this: |
| * |
| * <pre> |
| * Map<String, Record> m = new HashMap<String, Record>(); |
| * Record reuse = new Record(); |
| * for (long i = in.readMapStart(); i != 0; i = in.readMapNext()) { |
| * for (long j = 0; j < i; j++) { |
| * String key = in.readString(); |
| * reuse.intField = in.readInt(); |
| * reuse.boolField = in.readBoolean(); |
| * m.put(key, reuse); |
| * } |
| * } |
| * </pre> |
| * |
| * @throws AvroTypeException If this is a stateful reader and map is not the |
| * type of the next value to be read |
| */ |
| public abstract long readMapStart() throws IOException; |
| |
| /** |
| * Processes the next block of map entries and returns the count of them. |
| * Similar to {@link #arrayNext}. See {@link #readMapStart} for details. |
| * |
| * @throws AvroTypeException When called outside of a map context |
| */ |
| public abstract long mapNext() throws IOException; |
| |
| /** |
| * Support for quickly skipping through a map similar to {@link #skipArray}. |
| * |
| * As an example, let's say you want to skip a map of records, the record |
| * consisting of an Long field and a Boolean field. Your code would look |
| * something like this: |
| * |
| * <pre> |
| * for (long i = in.skipMap(); i != 0; i = in.skipMap()) { |
| * for (long j = 0; j < i; j++) { |
| * in.skipString(); // Discard key |
| * in.readInt(); // Discard int-field of value |
| * in.readBoolean(); // Discard boolean-field of value |
| * } |
| * } |
| * </pre> |
| * |
| * @throws AvroTypeException If this is a stateful reader and array is not the |
| * type of the next value to be read |
| */ |
| |
| public abstract long skipMap() throws IOException; |
| |
| /** |
| * Reads the tag of a union written by {@link Encoder#writeIndex}. |
| * |
| * @throws AvroTypeException If this is a stateful reader and union is not the |
| * type of the next value to be read |
| */ |
| public abstract int readIndex() throws IOException; |
| } |