/*********************************************************************************************************************** * * Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu) * * Licensed 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. * **********************************************************************************************************************/ package eu.stratosphere.api.java.typeutils.runtime; import java.io.DataInput; import java.io.IOException; import java.nio.ByteBuffer; import org.apache.avro.io.Decoder; import org.apache.avro.util.Utf8; public class DataInputDecoder extends Decoder implements java.io.Serializable { private static final long serialVersionUID = 1L; private transient Utf8 stringDecoder = new Utf8(); private transient DataInput in; public void setIn(DataInput in) { this.in = in; } // -------------------------------------------------------------------------------------------- // primitives // -------------------------------------------------------------------------------------------- @Override public void readNull() {} @Override public boolean readBoolean() throws IOException { return in.readBoolean(); } @Override public int readInt() throws IOException { return in.readInt(); } @Override public long readLong() throws IOException { return in.readLong(); } @Override public float readFloat() throws IOException { return in.readFloat(); } @Override public double readDouble() throws IOException { return in.readDouble(); } @Override public int readEnum() throws IOException { return readInt(); } // -------------------------------------------------------------------------------------------- // bytes // -------------------------------------------------------------------------------------------- @Override public void readFixed(byte[] bytes, int start, int length) throws IOException { in.readFully(bytes, start, length); } @Override public ByteBuffer readBytes(ByteBuffer old) throws IOException { int length = readInt(); ByteBuffer result; if (old != null && length <= old.capacity() && old.hasArray()) { result = old; result.clear(); } else { result = ByteBuffer.allocate(length); } in.readFully(result.array(), result.arrayOffset() + result.position(), length); result.limit(length); return result; } @Override public void skipFixed(int length) throws IOException { skipBytes(length); } @Override public void skipBytes() throws IOException { int num = readInt(); skipBytes(num); } // -------------------------------------------------------------------------------------------- // strings // -------------------------------------------------------------------------------------------- @Override public Utf8 readString(Utf8 old) throws IOException { int length = readInt(); Utf8 result = (old != null ? old : new Utf8()); result.setByteLength(length); if (length > 0) { in.readFully(result.getBytes(), 0, length); } return result; } @Override public String readString() throws IOException { return readString(stringDecoder).toString(); } @Override public void skipString() throws IOException { int len = readInt(); skipBytes(len); } // -------------------------------------------------------------------------------------------- // collection types // -------------------------------------------------------------------------------------------- @Override public long readArrayStart() throws IOException { return readVarLongCount(in); } @Override public long arrayNext() throws IOException { return readVarLongCount(in); } @Override public long skipArray() throws IOException { return readVarLongCount(in); } @Override public long readMapStart() throws IOException { return readVarLongCount(in); } @Override public long mapNext() throws IOException { return readVarLongCount(in); } @Override public long skipMap() throws IOException { return readVarLongCount(in); } // -------------------------------------------------------------------------------------------- // union // -------------------------------------------------------------------------------------------- @Override public int readIndex() throws IOException { return readInt(); } // -------------------------------------------------------------------------------------------- // utils // -------------------------------------------------------------------------------------------- private void skipBytes(int num) throws IOException { while (num > 0) { num -= in.skipBytes(num); } } public static long readVarLongCount(DataInput in) throws IOException { long value = in.readUnsignedByte(); if ((value & 0x80) == 0) { return value; } else { long curr; int shift = 7; value = value & 0x7f; while (((curr = in.readUnsignedByte()) & 0x80) != 0){ value |= (curr & 0x7f) << shift; shift += 7; } value |= curr << shift; return value; } } // -------------------------------------------------------------------------------------------- // serialization // -------------------------------------------------------------------------------------------- private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); this.stringDecoder = new Utf8(); this.in = null; } }