/* * 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. */ using System; using System.IO; namespace Avro.IO { /// /// Decoder for Avro binary format /// public partial class BinaryDecoder : Decoder { private readonly Stream stream; /// /// Initializes a new instance of the class. /// /// Stream to decode. public BinaryDecoder(Stream stream) { this.stream = stream; } /// /// null is written as zero bytes /// public void ReadNull() { } /// /// a boolean is written as a single byte /// whose value is either 0 (false) or 1 (true). /// /// public bool ReadBoolean() { byte b = read(); if (b == 0) return false; if (b == 1) return true; throw new AvroException("Not a boolean value in the stream: " + b); } /// /// int and long values are written using variable-length, zig-zag coding. /// /// An integer value. public int ReadInt() { return (int)ReadLong(); } /// /// int and long values are written using variable-length, zig-zag coding. /// /// A long value. public long ReadLong() { byte b = read(); ulong n = b & 0x7FUL; int shift = 7; while ((b & 0x80) != 0) { b = read(); n |= (b & 0x7FUL) << shift; shift += 7; } long value = (long)n; return (-(value & 0x01L)) ^ ((value >> 1) & 0x7fffffffffffffffL); } /// /// Bytes are encoded as a long followed by that many bytes of data. /// /// public byte[] ReadBytes() { return read(ReadLong()); } /// /// Reads an enumeration. /// /// Ordinal value of the enum. public int ReadEnum() { return ReadInt(); } /// /// Reads the size of the first block of an array. /// /// Size of the first block of an array. public long ReadArrayStart() { return doReadItemCount(); } /// /// Processes the next block of an array and returns the number of items in the block and /// let's the caller read those items. /// /// Number of items in the next block of an array. public long ReadArrayNext() { return doReadItemCount(); } /// /// Reads the size of the next block of map-entries. /// /// Size of the next block of map-entries. public long ReadMapStart() { return doReadItemCount(); } /// /// Processes the next block of map entries and returns the count of them. /// /// Number of entires in the next block of a map. public long ReadMapNext() { return doReadItemCount(); } /// /// Reads the tag index of a union written by . /// /// Tag index of a union. public int ReadUnionIndex() { return ReadInt(); } /// /// Reads fixed sized binary object. /// /// Buffer to read the fixed value into. public void ReadFixed(byte[] buffer) { ReadFixed(buffer, 0, buffer.Length); } /// /// Reads fixed sized binary object. /// /// Buffer to read the fixed value into. /// /// Position to start writing the fixed value to in the . /// /// /// Number of bytes of the fixed to read. /// public void ReadFixed(byte[] buffer, int start, int length) { Read(buffer, start, length); } /// /// Skips over a null value. /// public void SkipNull() { ReadNull(); } /// /// Skips over a boolean value. /// public void SkipBoolean() { ReadBoolean(); } /// /// Skips over an int value. /// public void SkipInt() { ReadInt(); } /// /// Skips over a long value. /// public void SkipLong() { ReadLong(); } /// /// Skips over a float value. /// public void SkipFloat() { Skip(4); } /// /// Skips over a double value. /// public void SkipDouble() { Skip(8); } /// /// Skips a byte-string written by . /// public void SkipBytes() { Skip(ReadLong()); } /// /// Skips a string written by . /// public void SkipString() { SkipBytes(); } /// /// Skips an enum value. /// public void SkipEnum() { ReadLong(); } /// /// Skips a union tag index. /// public void SkipUnionIndex() { ReadLong(); } /// /// Skips a fixed value of a specified length. /// /// Length of the fixed to skip. public void SkipFixed(int len) { Skip(len); } // Read p bytes into a new byte buffer private byte[] read(long p) { byte[] buffer = new byte[p]; Read(buffer, 0, buffer.Length); return buffer; } private byte read() { int n = stream.ReadByte(); if (n >= 0) return (byte)n; throw new AvroException("End of stream reached"); } private long doReadItemCount() { long result = ReadLong(); if (result < 0) { ReadLong(); // Consume byte-count if present result = -result; } return result; } private void Skip(int p) { stream.Seek(p, SeekOrigin.Current); } private void Skip(long p) { stream.Seek(p, SeekOrigin.Current); } } }