package com.one;

import java.io.*;

public class PartialInputStream extends RandomAccessInputStream
{
	protected RandomAccessInputStream is;
	protected int currpos, markedpos;
	protected int start, end;
	
	// We may need to supply an extra dummy byte to our reader.
	// See Inflater.  We use a count here to simplify the logic
	// elsewhere in this class. Note that we ignore the dummy
	// byte in methods where we know it is not needed.
	protected int dummyByteCount;
	
	public PartialInputStream(RandomAccessInputStream rais, int off, int len) throws IOException
	{
		is = rais;
		
		if(off >= 0)
		{
			start = off;
		}
		else
		{
			start = 0;
		}
		
		if(len >= 0)
		{
			end = start + len;
		}
		else
		{
			end = rais.getCapacity();
		}
		
		currpos = start;
		markedpos = currpos;
		dummyByteCount = 0;
	}
	
	public void addDummyByte()
	{
		dummyByteCount = 1;
	}
	
	public int available()
	{
		return end - currpos;
	}
	
	public void close()
	{
	}
	
	public void mark(int readLimit)
	{
		markedpos = currpos;
	}
	
	public int read() throws IOException
	{
		if(currpos >= end)
		{
			if(dummyByteCount > 0)
			{
				dummyByteCount--;
				return 0;
			}
			else
			{
				return -1;
			}
		}
		
		is.setPosition(currpos++);
		
		return is.read();
	}
	
	public int read(byte[] b) throws IOException
	{
		return read(b, 0, b.length);
	}
	
	public int read(byte[] b, int off, int len) throws IOException
	{
		int available = available() + dummyByteCount;

		if(available <= 0)
		{
			return -1;
		}

		if(len > available)
		{
			len = available;
		}
		
		is.setPosition(currpos);
		int n = is.read(b, off, len);
		
		if(n < len && dummyByteCount > 0)
		{
			dummyByteCount--;
			b[off + n] = 0;
		}
		
		currpos += n;
		
		return n;
	}
	
	public void reset()
	{
		currpos = markedpos;
	}
	
	public long skip(long n)
	{
		if(n > available())
		{
			n = available();
		}
		
		currpos += n;
		
		return n;
	}
	
	public void setPosition(int pos) throws IOException
	{
		if(pos == currpos)
		{
			return;
		}
		
		if(pos < start)
		{
			pos = start;
		}
		else if(pos > end)
		{
			pos = end;
		}
		
		currpos = pos;
	}
	
	public int getPosition()
	{
		return currpos - start;
	}
	
	public int getCapacity()
	{
		return end - start;
	}
	
	public void update() throws IOException
	{
		is.update();
	}

	public void pause() throws IOException
	{
		is.pause();
	}

	public void resume() throws IOException
	{
		is.resume();
	}
}
