package net.contrapunctus.rngzip.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import net.contrapunctus.rngzip.util.BitInputStream;
import net.contrapunctus.rngzip.util.BitOutputStream;
/**
* Objects of this class represent choice points by querying the user
* whenever it needs to make a choice. This can be useful for tracing
* and debugging; it provides a way to guide a decompressor
* interactively through the automaton.
*
* <p class='license'>This is free software; you may modify and/or
* redistribute it under the terms of the GNU General Public License,
* but it comes with <b>absolutely no warranty.</b>
*
* @author Christopher League
* @see InteractiveInput
*/
public class InteractiveChoiceDecoder implements ChoiceDecoder
{
private BufferedReader in;
private PrintStream out;
private Object id;
private int limit;
/**
* Construct an interctive decoder representing a choice point with
* up to ‘limit’ possible choices.
*
* @param in reads user’s input from this stream
* @param out prompts user on this stream
* @param limit the number of choices at this choice point, which
* must be strictly positive.
* @param id this object is used to represent the choice point for
* debugging purposes.
*/
public InteractiveChoiceDecoder
( BufferedReader in, PrintStream out,
int limit, Object id )
{
this.in = in;
this.out = out;
this.limit = limit;
this.id = id;
}
/**
* Ignores the <code>BitInputStream</code> and queries the user
* interactively instead.
*/
public int decode( BitInputStream bi ) throws IOException
{
out.printf("%s --%d--> ", this, limit);
out.flush();
int ch = Integer.parseInt(in.readLine());
if(ch < 0 || ch >= limit)
throw new RNGZFormatException("invalid choice");
return ch;
}
/**
* Identifies this choice point using the ‘id’ object provided to
* the constructor (if it was non-null).
*/
public String toString()
{
if(id == null) return super.toString();
else return id.toString();
}
}