All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jcodec.common.io.DataReader Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
package org.jcodec.common.io;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * This class is part of JCodec ( www.jcodec.org ) This software is distributed
 * under FreeBSD License
 * 
 * This class is analogous to DataInputStream, it's backed by the Channel and
 * buffers the IO
 * 
 * @author The JCodec project
 * 
 */
public class DataReader implements Closeable {
    private static final int DEFAULT_BUFFER_SIZE = 1 << 20; // 1 megabyte

    private SeekableByteChannel channel;
    private ByteBuffer buffer;

    public static DataReader createDataReader(SeekableByteChannel channel, ByteOrder order) {
        return new DataReader(channel, order, DEFAULT_BUFFER_SIZE);
    }

    public DataReader(SeekableByteChannel channel, ByteOrder order, int bufferSize) {
        this.channel = channel;
        this.buffer = ByteBuffer.allocate(bufferSize);
        this.buffer.limit(0);
        this.buffer.order(order);
    }

    public int readFully3(byte[] b, int off, int len) throws IOException {
        int initOff = off;
        while (len > 0) {
            fetchIfNeeded(len);

            if (buffer.remaining() == 0)
                break;

            int toRead = Math.min(buffer.remaining(), len);
            buffer.get(b, off, toRead);
            off += toRead;
            len -= toRead;
        }
        return off - initOff;
    }

    public int skipBytes(int n) throws IOException {
        long oldPosition = position();
        if (n < buffer.remaining()) {
            buffer.position(buffer.position() + n);
        } else {
            setPosition(oldPosition + n);
        }
        return (int) (position() - oldPosition);
    }

    public byte readByte() throws IOException {
        fetchIfNeeded(1);
        return buffer.get();
    }

    public short readShort() throws IOException {
        fetchIfNeeded(2);
        return buffer.getShort();
    }

    public char readChar() throws IOException {
        fetchIfNeeded(2);
        return buffer.getChar();
    }

    public int readInt() throws IOException {
        fetchIfNeeded(4);
        return buffer.getInt();
    }

    public long readLong() throws IOException {
        fetchIfNeeded(8);
        return buffer.getLong();
    }

    public float readFloat() throws IOException {
        fetchIfNeeded(4);
        return buffer.getFloat();
    }

    public double readDouble() throws IOException {
        fetchIfNeeded(8);
        return buffer.getDouble();
    }

    public long position() throws IOException {
        return channel.position() - buffer.limit() + buffer.position();
    }

    public long setPosition(long newPos) throws IOException {
        int relative = (int) (newPos - (channel.position() - buffer.limit()));
        if (relative >= 0 && relative < buffer.limit()) {
            buffer.position(relative);
        } else {
            buffer.limit(0);
            channel.setPosition(newPos);
        }
        return position();
    }

    @Override
    public void close() throws IOException {
        channel.close();
    }

    private void fetchIfNeeded(int length) throws IOException {
        if (buffer.remaining() < length) {
            moveRemainderToTheStart(buffer);
            channel.read(buffer);
            buffer.flip();
        }
    }

    private static void moveRemainderToTheStart(ByteBuffer readBuf) {
        int rem = readBuf.remaining();
        for (int i = 0; i < rem; i++) {
            readBuf.put(i, readBuf.get());
        }
        readBuf.clear();
        readBuf.position(rem);
    }

    public long size() throws IOException {
        return channel.size();
    }

    public int readFully(byte[] b) throws IOException {
        return readFully3(b, 0, b.length);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy