package org.xmlsh.core.io;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;
import org.xmlsh.core.InputPort;
import org.xmlsh.util.NullInputStream;
import org.xmlsh.util.NullOutputStream;
public abstract class ShellReader extends Reader {
protected IShellPrompt mShellPrompt ;
private char buf[];
private int boff = -1;
private int promptLevel = 0;
public static class ShellNullReader extends ShellReader {
public ShellNullReader() {
super(null);
}
@Override
protected String readLine(String prompt) throws IOException {
return null;
}
@Override
public InputPort getInputPort() {
return new StreamInputPort( new NullInputStream(), "");
}
@Override
public OutputPort getOutputPort() {
return new StreamOutputPort( new NullOutputStream());
}
@Override
public OutputPort getErrorPort() {
return new StreamOutputPort( new NullOutputStream());
}
}
/*
* Shell Reader with stdio from supplied streams and Interactive/command IO from supplied in/out
*
*/
public static class ShellStreamReader extends ShellReader {
// Command/Interaractive in/out
private BufferedReader consoleReader ;
private PrintStream consoleOut;
private InputStream stdin;
private OutputStream stdout ;
private OutputStream stderr ;
ShellStreamReader(InputStream consoleIn , PrintStream consoleOut ,
InputStream stdin, OutputStream stdout , OutputStream stderr , IShellPrompt prompt) {
super(prompt);
consoleReader = new BufferedReader( new InputStreamReader( consoleIn ));
this.consoleOut = consoleOut ;
this.stdin = stdin ;
this.stdout = stdout ;
this.stderr = stderr ;
}
@Override
protected String readLine( String prompt ) throws IOException {
if( prompt != null ){
consoleOut.print( prompt );
consoleOut.flush();
}
return consoleReader.readLine();
}
public InputPort getInputPort()
{
return new StreamInputPort( stdin , null , stdin == System.in );
}
public OutputPort getOutputPort()
{
return new StreamOutputPort(stdout,false,stdout == System.out ) ;
}
public OutputPort getErrorPort()
{
return new StreamOutputPort(stderr,false,stderr == System.err ) ;
}
}
/*
* Shell Reader with stdio from System and Interactive/command IO from supplied in/out
*
*/
public static class ShellSystemReader extends ShellStreamReader {
ShellSystemReader(InputStream consoleIn , PrintStream consoleOut , IShellPrompt prompt) {
super(consoleIn, consoleOut , System.in, System.out , System.err , prompt );
}
}
protected String getPrompt() {
return getPrompt(promptLevel);
}
private String getPrompt(int level) {
if( mShellPrompt != null && promptLevel >= 0 )
return mShellPrompt.getPrompt(level);
else
return null;
}
public static ShellReader newNullReader() {
return new ShellNullReader();
}
public static ShellReader newSystemReader( IShellPrompt prompt)
{
return new ShellSystemReader( System.in, System.out ,prompt);
}
public static ShellReader newStreamReader(InputStream consoleIn , PrintStream consoleOut ,
InputStream stdin, OutputStream stdout , OutputStream stderr , IShellPrompt prompt) {
return new ShellStreamReader(stdin, consoleOut, stdin, stderr, stderr, prompt);
}
public ShellReader(IShellPrompt prompt) {
mShellPrompt = prompt;
}
@Override
public void reset() throws IOException {
promptLevel = 0;
}
@Override
public int read(char[] cbuf, int coff, int len) throws IOException {
ShellConsole.mLogger.entry(cbuf, coff, len);
assert( len >0 );
if( buf == null ){
String line = readLine();
if( line == null )
return -1;
buf = line.toCharArray();
boff =0 ;
promptLevel = 1;
}
int blen = buf.length - boff ;
int clen = Math.min(blen, len);
if( blen > 0){
if( clen > 0 ){
System.arraycopy(buf, boff, cbuf, coff , clen );
boff += clen ;
coff += clen ;
len -= clen ;
blen -= clen ;
assert( len >= 0);
assert( blen >=0 );
}
// copy NL if reached end of line
}
if( blen == 0 && len > 0 ){
cbuf[coff] = '\n';
buf = null ;
boff = -1;
clen++;
}
return ShellConsole.mLogger.exit(clen);
}
@Override
public void close() throws IOException {
ShellConsole.mLogger.entry();
// just toss input
buf = null ;
boff = -1;
}
protected abstract String readLine(String prompt) throws IOException;
protected String readLine() throws IOException {
return readLine(getPrompt());
}
// InputPort is for Non prompting data reads
public abstract InputPort getInputPort();
public abstract OutputPort getOutputPort();
public abstract OutputPort getErrorPort();
}