001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.hadoop.io;
020
021import java.io.DataInputStream;
022import java.io.InputStream;
023import java.nio.ByteBuffer;
024
025public class DataInputByteBuffer extends DataInputStream {
026
027  private static class Buffer extends InputStream {
028    private final byte[] scratch = new byte[1];
029    ByteBuffer[] buffers = new ByteBuffer[0];
030    int bidx, pos, length;
031    @Override
032    public int read() {
033      if (-1 == read(scratch, 0, 1)) {
034        return -1;
035      }
036      return scratch[0] & 0xFF;
037    }
038    @Override
039    public int read(byte[] b, int off, int len) {
040      if (bidx >= buffers.length) {
041        return -1;
042      }
043      int cur = 0;
044      do {
045        int rem = Math.min(len, buffers[bidx].remaining());
046        buffers[bidx].get(b, off, rem);
047        cur += rem;
048        off += rem;
049        len -= rem;
050      } while (len > 0 && ++bidx < buffers.length);
051      pos += cur;
052      return cur;
053    }
054    public void reset(ByteBuffer[] buffers) {
055      bidx = pos = length = 0;
056      this.buffers = buffers;
057      for (ByteBuffer b : buffers) {
058        length += b.remaining();
059      }
060    }
061    public int getPosition() {
062      return pos;
063    }
064    public int getLength() {
065      return length;
066    }
067    public ByteBuffer[] getData() {
068      return buffers;
069    }
070  }
071
072  private Buffer buffers;
073
074  public DataInputByteBuffer() {
075    this(new Buffer());
076  }
077
078  private DataInputByteBuffer(Buffer buffers) {
079    super(buffers);
080    this.buffers = buffers;
081  }
082
083  public void reset(ByteBuffer... input) {
084    buffers.reset(input);
085  }
086
087  public ByteBuffer[] getData() {
088    return buffers.getData();
089  }
090
091  public int getPosition() {
092    return buffers.getPosition();
093  }
094
095  public int getLength() {
096    return buffers.getLength();
097  }
098}