/**
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2004 satoshi akabane(akabane@logical-paradox.org)
 *
 */
package org.logical_paradox.common.io;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * ファイルに実際に出力せず，メモリ上でRandomAccessFileの処理を代理するクラス
 * @author satoshi akabane@logical-paradox.org
 * @version 1.0
 */
public class MemoryMappedRandomAccessFile implements RandomAccessFileDelegator {
	private boolean _closed = true;
	private ExpandableBuffer _buffer = new ExpandableBuffer();


	public MemoryMappedRandomAccessFile() {
		_closed = false;
	}
	public void close() throws IOException {
		if(_closed) {
			throw new IOException("このファイルは既に閉じられています");
		}
		_closed = true;
	}
	public long length() throws IOException {
		return _buffer.using();
	}
	public void seek(long pos) throws IOException {
		if(pos > length()) {
			throw new IOException("シークポインタがファイルサイズの終端を越えた");
		} else if(pos < 0) {
			throw new IOException("シークポインタは0以上で指定してください");
		}
		_buffer.seek((int)pos);
	}
	public int read(byte[] b) throws IOException {
		return _buffer.getInputStream().read(b);
	}
	public void readFully(byte[] b) throws IOException {
		read(b);
	}
	public byte readByte() throws IOException {
		int b = _buffer.read();
		if(b < 0) {
			throw new EOFException();
		}
		return (byte)b;
	}
	public int readInt() throws IOException, EOFException {
		int b1 = (int)readByte() & 0xff;
		int b2 = (int)readByte() & 0xff;
		int b3 = (int)readByte() & 0xff;
		int b4 = (int)readByte() & 0xff;

		return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
	}
	public long readLong() throws IOException, EOFException {
		int b1 = (int)readByte() & 0xff;
		int b2 = (int)readByte() & 0xff;
		int b3 = (int)readByte() & 0xff;
		int b4 = (int)readByte() & 0xff;
		int b5 = (int)readByte() & 0xff;
		int b6 = (int)readByte() & 0xff;
		int b7 = (int)readByte() & 0xff;
		int b8 = (int)readByte() & 0xff;

		return (b1 << 56) | (b2 << 48) | (b3 << 40) | (b4 << 32) | (b5 << 24) | (b6 << 16) | (b7 << 8) | b8;
	}
	public void write(byte[] b) throws IOException {
		_buffer.getOutputStream().write(b);
	}
	public void write(int b) throws IOException {
		_buffer.write(b);
	}
	public OutputStream getOutputStream() {
		return _buffer.getOutputStream();
	}
	public InputStream getInputStream() {
		return _buffer.getInputStream();
	}
}
