Implement redirection for pluggable scripting contexts

This commit is contained in:
James Roseborough
2013-02-03 01:29:46 +00:00
parent 8a93c061f7
commit 424e80900a
4 changed files with 162 additions and 21 deletions

View File

@@ -97,7 +97,7 @@ public class ScriptEngineSample {
"print(\"string written using 'print'\")\n" +
"io.write(\"string written using 'io.write()'\\n\")\n" +
"io.stdout:write(\"string written using 'io.stdout:write()'\\n\")\n" +
"io.stderr:write(\"string written using 'io.stderr:write()'\\n\")\n" +
"io.stderr:write(\"string written using 'io.stderr:write(), hit return to continue...'\\n\")\n" +
"io.write([[string read using 'io.stdin:read(\"*l\")':]]..io.stdin:read(\"*l\")..\"\\n\")\n";
System.out.println("Evaluating script with redirection set.");
@@ -114,7 +114,7 @@ public class ScriptEngineSample {
e.getContext().setReader(null);
e.getContext().setWriter(null);
e.getContext().setErrorWriter(null);
e.eval(script);
e.eval(script); // Will wait for a line from the user at this step!
System.out.println("output::>"+output+"<::output");
System.out.println("errors::>"+errors+"<::errors");

View File

@@ -111,6 +111,14 @@ public class IoLib extends OneArgFunction {
}
}
/** Enumerated value representing stdin */
protected static final int FTYPE_STDIN = 0;
/** Enumerated value representing stdout */
protected static final int FTYPE_STDOUT = 1;
/** Enumerated value representing stderr */
protected static final int FTYPE_STDERR = 2;
/** Enumerated value representing a file type for a named file */
protected static final int FTYPE_NAMED = 3;
/**
* Wrap the standard input.
@@ -126,6 +134,13 @@ public class IoLib extends OneArgFunction {
*/
abstract protected File wrapStdout() throws IOException;
/**
* Wrap the standard error output.
* @return File
* @throws IOException
*/
abstract protected File wrapStderr() throws IOException;
/**
* Open a file in a particular mode.
* @param filename
@@ -295,7 +310,7 @@ public class IoLib extends OneArgFunction {
}
private File input() {
return infile!=null? infile: (infile=ioopenfile("-","r"));
return infile!=null? infile: (infile=ioopenfile(FTYPE_STDIN, "-","r"));
}
// io.flush() -> bool
@@ -320,7 +335,7 @@ public class IoLib extends OneArgFunction {
// io.input([file]) -> file
public Varargs _io_input(LuaValue file) {
infile = file.isnil()? input():
file.isstring()? ioopenfile(file.checkjstring(),"r"):
file.isstring()? ioopenfile(FTYPE_NAMED, file.checkjstring(),"r"):
checkfile(file);
return infile;
}
@@ -328,7 +343,7 @@ public class IoLib extends OneArgFunction {
// io.output(filename) -> file
public Varargs _io_output(LuaValue filename) {
outfile = filename.isnil()? output():
filename.isstring()? ioopenfile(filename.checkjstring(),"w"):
filename.isstring()? ioopenfile(FTYPE_NAMED, filename.checkjstring(),"w"):
checkfile(filename);
return outfile;
}
@@ -348,12 +363,12 @@ public class IoLib extends OneArgFunction {
// io.open(filename, [mode]) -> file | nil,err
public Varargs _io_open(String filename, String mode) throws IOException {
return rawopenfile(filename, mode);
return rawopenfile(FTYPE_NAMED, filename, mode);
}
// io.lines(filename) -> iterator
public Varargs _io_lines(String filename) {
infile = filename==null? input(): ioopenfile(filename,"r");
infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r");
checkopen(infile);
return lines(infile);
}
@@ -420,16 +435,16 @@ public class IoLib extends OneArgFunction {
}
private File output() {
return outfile!=null? outfile: (outfile=ioopenfile("-","w"));
return outfile!=null? outfile: (outfile=ioopenfile(FTYPE_STDOUT,"-","w"));
}
private File errput() {
return errfile!=null? errfile: (errfile=ioopenfile("-","w"));
return errfile!=null? errfile: (errfile=ioopenfile(FTYPE_STDERR,"-","w"));
}
private File ioopenfile(String filename, String mode) {
private File ioopenfile(int filetype, String filename, String mode) {
try {
return rawopenfile(filename, mode);
return rawopenfile(filetype, filename, mode);
} catch ( Exception e ) {
error("io error: "+e.getMessage());
return null;
@@ -518,14 +533,13 @@ public class IoLib extends OneArgFunction {
return file;
}
private File rawopenfile(String filename, String mode) throws IOException {
boolean isstdfile = "-".equals(filename);
boolean isreadmode = mode.startsWith("r");
if ( isstdfile ) {
return isreadmode?
wrapStdin():
wrapStdout();
private File rawopenfile(int filetype, String filename, String mode) throws IOException {
switch (filetype) {
case FTYPE_STDIN: return wrapStdin();
case FTYPE_STDOUT: return wrapStdout();
case FTYPE_STDERR: return wrapStderr();
}
boolean isreadmode = mode.startsWith("r");
boolean isappend = mode.startsWith("a");
boolean isupdate = mode.indexOf("+") > 0;
boolean isbinary = mode.endsWith("b");

View File

@@ -75,6 +75,10 @@ public class JmeIoLib extends IoLib {
return new FileImpl(globals.STDOUT);
}
protected File wrapStderr() throws IOException {
return new FileImpl(globals.STDERR);
}
protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException {
String url = "file:///" + filename;
int mode = readMode? Connector.READ: Connector.READ_WRITE;

View File

@@ -23,9 +23,11 @@ package org.luaj.vm2.lib.jse;
import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import org.luaj.vm2.LuaError;
@@ -68,11 +70,15 @@ import org.luaj.vm2.lib.LibFunction;
public class JseIoLib extends IoLib {
protected File wrapStdin() throws IOException {
return new FileImpl(globals.STDIN);
return new StdinFile();
}
protected File wrapStdout() throws IOException {
return new FileImpl(globals.STDOUT);
return new StdoutFile(FTYPE_STDOUT);
}
protected File wrapStderr() throws IOException {
return new StdoutFile(FTYPE_STDERR);
}
protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException {
@@ -103,6 +109,7 @@ public class JseIoLib extends IoLib {
throw new LuaError("not implemented");
}
private final class FileImpl extends File {
private final RandomAccessFile file;
private final InputStream is;
@@ -215,4 +222,120 @@ public class JseIoLib extends IoLib {
return length;
}
}
private final class StdoutFile extends File {
private final int file_type;
private StdoutFile(int file_type) {
this.file_type = file_type;
}
public String tojstring() {
return "file ("+this.hashCode()+")";
}
private final PrintStream getPrintStream() {
return file_type == FTYPE_STDERR?
globals.STDERR:
globals.STDOUT;
}
public void write(LuaString string) throws IOException {
getPrintStream().write(string.m_bytes, string.m_offset, string.m_length);
}
public void flush() throws IOException {
getPrintStream().flush();
}
public boolean isstdfile() {
return true;
}
public void close() throws IOException {
// do not close std files.
}
public boolean isclosed() {
return false;
}
public int seek(String option, int bytecount) throws IOException {
return 0;
}
public void setvbuf(String mode, int size) {
}
public int remaining() throws IOException {
return 0;
}
public int peek() throws IOException, EOFException {
return 0;
}
public int read() throws IOException, EOFException {
return 0;
}
public int read(byte[] bytes, int offset, int length)
throws IOException {
return 0;
}
}
private final class StdinFile extends File {
private StdinFile() {
}
public String tojstring() {
return "file ("+this.hashCode()+")";
}
public void write(LuaString string) throws IOException {
}
public void flush() throws IOException {
}
public boolean isstdfile() {
return true;
}
public void close() throws IOException {
// do not close std files.
}
public boolean isclosed() {
return false;
}
public int seek(String option, int bytecount) throws IOException {
return 0;
}
public void setvbuf(String mode, int size) {
}
public int remaining() throws IOException {
return 0;
}
public int peek() throws IOException, EOFException {
globals.STDIN.mark(1);
int c = globals.STDIN.read();
globals.STDIN.reset();
return c;
}
public int read() throws IOException, EOFException {
return globals.STDIN.read();
}
public int read(byte[] bytes, int offset, int length)
throws IOException {
return globals.STDIN.read(bytes, offset, length);
}
}
}