package rpn;
import java.io.*;

public class StreamInput extends Input {
	InputStream cis;
	byte buf[];
	int bufSize = 512;
	public StreamInput(InputStream s) {
		this.cis = s;
		start = 0;
		mark = 0;
		eoi = 0;
		buf = new byte[bufSize];
	}
	
	public char nextChar(int i) {
		return((char) buf[i]);
	}
	
	public int peek(int m) {
		// assertion: start < mark <= eoi always
		int k = start+m;
		if (k < eoi) {
			return((int) buf[k]);
		}
		else {
			// k >= eoi, or k lies beyond what has been read
			// we have to load more stuff
			// we must first store buf[start, bufSize) 
			// and shift start, mark
			// System.out.println("eoi, start = " + eoi + ", " + start);
			eoi -= start;
			// so eoi now = amount of stuff to be kept
			if (m+1 >= bufSize) {
				// we must expand the buffer
				// because there isn't room in it for m+1 things
				byte tmp[] = new byte[bufSize+256];
				for (int i=0;i<eoi;i++) {
					tmp[i] = buf[i+start];
				}
				buf = tmp;
				bufSize = bufSize + 256;
			}
			else {
				for (int i=0;i<eoi;i++) {
					buf[i] = buf[i+start];
				}
			}
			mark -= start;
			start = 0;
			// there is room in the buffer for everything we want
			// and it needs to be loaded, starting at ell
			int nread = 0;
			try {
				// System.out.println("... " + eoi + ", " + bufSize);
				nread = cis.read(buf, eoi, bufSize-eoi);
			} catch(IOException ioe) { ; }
			if (nread != -1) {
				// true end of input had not been reached yet
				eoi += nread;
			}
			else return(255);
		}
		// now start + m < bufSize
		if (m < eoi) {
			return(buf[m]);
		}
		else {
			return(255);
		}
	}	
}

