package com.github.hoffart.dmap.util; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class ExtendedFileChannel { public static final byte TRUE_BYTE = 1; public static final byte FALSE_BYTE = 0; private FileChannel fileChannel_; private final ByteBuffer boolBuffer_; private final ByteBuffer intBuffer_; private final ByteBuffer vIntBuffer_; private final ByteBuffer longBuffer_; private final ByteBuffer vLongBuffer_; public ExtendedFileChannel(FileChannel fileChannel) { fileChannel_ = fileChannel; boolBuffer_ = ByteBuffer.allocate(1); intBuffer_ = ByteBuffer.allocate(4); vIntBuffer_ = ByteBuffer.allocate(5); longBuffer_ = ByteBuffer.allocate(8); vLongBuffer_ = ByteBuffer.allocate(9); } public int write(ByteBuffer byteBuffer) throws IOException { byteBuffer.position(0); return fileChannel_.write(byteBuffer); } public int write(byte[] bytes) throws IOException { return write(ByteBuffer.wrap(bytes)); } public int writeBool(boolean value) throws IOException { boolBuffer_.rewind(); boolBuffer_.put(value ? TRUE_BYTE : FALSE_BYTE); return write(boolBuffer_); } public int writeInt(int value) throws IOException { intBuffer_.rewind(); intBuffer_.putInt(value); return write(intBuffer_); } public int writeVInt(int value) throws IOException { vIntBuffer_.clear(); int length = CompressionUtils.writeVInt(vIntBuffer_, value); vIntBuffer_.rewind(); vIntBuffer_.limit(length); return fileChannel_.write(vIntBuffer_); } public int writeLong(long value) throws IOException { longBuffer_.rewind(); longBuffer_.putLong(value); return write(longBuffer_); } public int writeVLong(long value) throws IOException { vLongBuffer_.clear(); int length = CompressionUtils.writeVLong(vLongBuffer_, value); vLongBuffer_.rewind(); vLongBuffer_.limit(length); return fileChannel_.write(vLongBuffer_); } public int read(ByteBuffer byteBuffer) throws IOException { return fileChannel_.read(byteBuffer); } public int read(byte[] bytes) throws IOException { return read(ByteBuffer.wrap(bytes)); } public boolean readBool() throws IOException { boolBuffer_.rewind(); read(boolBuffer_); return boolBuffer_.get(0) == TRUE_BYTE; } public int readInt() throws IOException { intBuffer_.rewind(); read(intBuffer_); return intBuffer_.getInt(0); } public int readVInt() throws IOException { return (int) readVLong(); } public long readLong() throws IOException { longBuffer_.rewind(); read(longBuffer_); return longBuffer_.getLong(0); } public long readVLong() throws IOException { vLongBuffer_.clear(); vLongBuffer_.limit(1); read(vLongBuffer_); byte firstByte = vLongBuffer_.get(0); int length = CompressionUtils.decodeVNumSize(firstByte); vLongBuffer_.limit(length); read(vLongBuffer_); vLongBuffer_.position(1); return CompressionUtils.readVLong(vLongBuffer_, length, firstByte); } public void flush() throws IOException { fileChannel_.force(true); } public void close() throws IOException { fileChannel_.close(); } public long size() throws IOException { return fileChannel_.size(); } public long position() throws IOException { return fileChannel_.position(); } public ExtendedFileChannel position(long newPosition) throws IOException { fileChannel_.position(newPosition); return this; } public MappedByteBuffer map(FileChannel.MapMode mapMode, long position, long size) throws IOException { return fileChannel_.map(mapMode, position, size); } }