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;
024import java.util.LinkedList;
025import java.util.List;
026
027public class DataInputByteBuffer extends DataInputStream {
028
029  private static class Buffer extends InputStream {
030    private final byte[] scratch = new byte[1];
031    ByteBuffer[] buffers = new ByteBuffer[0];
032    int bidx, pos, length;
033    @Override
034    public int read() {
035      if (-1 == read(scratch, 0, 1)) {
036        return -1;
037      }
038      return scratch[0] & 0xFF;
039    }
040    @Override
041    public int read(byte[] b, int off, int len) {
042      if (bidx >= buffers.length) {
043        return -1;
044      }
045      int cur = 0;
046      do {
047        int rem = Math.min(len, buffers[bidx].remaining());
048        buffers[bidx].get(b, off, rem);
049        cur += rem;
050        off += rem;
051        len -= rem;
052      } while (len > 0 && ++bidx < buffers.length);
053      pos += cur;
054      return cur;
055    }
056    public void reset(ByteBuffer[] buffers) {
057      bidx = pos = length = 0;
058      this.buffers = buffers;
059      for (ByteBuffer b : buffers) {
060        length += b.remaining();
061      }
062    }
063    public int getPosition() {
064      return pos;
065    }
066    public int getLength() {
067      return length;
068    }
069    public ByteBuffer[] getData() {
070      return buffers;
071    }
072  }
073
074  private Buffer buffers;
075
076  public DataInputByteBuffer() {
077    this(new Buffer());
078  }
079
080  private DataInputByteBuffer(Buffer buffers) {
081    super(buffers);
082    this.buffers = buffers;
083  }
084
085  public void reset(ByteBuffer... input) {
086    buffers.reset(input);
087  }
088
089  public ByteBuffer[] getData() {
090    return buffers.getData();
091  }
092
093  public int getPosition() {
094    return buffers.getPosition();
095  }
096
097  public int getLength() {
098    return buffers.getLength();
099  }
100}