Implement redirection for pluggable scripting contexts
This commit is contained in:
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -517,15 +532,14 @@ public class IoLib extends OneArgFunction {
|
||||
error("attempt to use a closed file");
|
||||
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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user