Implement redirection for pluggable scripting contexts
This commit is contained in:
@@ -97,7 +97,7 @@ public class ScriptEngineSample {
|
|||||||
"print(\"string written using 'print'\")\n" +
|
"print(\"string written using 'print'\")\n" +
|
||||||
"io.write(\"string written using 'io.write()'\\n\")\n" +
|
"io.write(\"string written using 'io.write()'\\n\")\n" +
|
||||||
"io.stdout:write(\"string written using 'io.stdout: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";
|
"io.write([[string read using 'io.stdin:read(\"*l\")':]]..io.stdin:read(\"*l\")..\"\\n\")\n";
|
||||||
|
|
||||||
System.out.println("Evaluating script with redirection set.");
|
System.out.println("Evaluating script with redirection set.");
|
||||||
@@ -114,7 +114,7 @@ public class ScriptEngineSample {
|
|||||||
e.getContext().setReader(null);
|
e.getContext().setReader(null);
|
||||||
e.getContext().setWriter(null);
|
e.getContext().setWriter(null);
|
||||||
e.getContext().setErrorWriter(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("output::>"+output+"<::output");
|
||||||
System.out.println("errors::>"+errors+"<::errors");
|
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.
|
* Wrap the standard input.
|
||||||
@@ -126,6 +134,13 @@ public class IoLib extends OneArgFunction {
|
|||||||
*/
|
*/
|
||||||
abstract protected File wrapStdout() throws IOException;
|
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.
|
* Open a file in a particular mode.
|
||||||
* @param filename
|
* @param filename
|
||||||
@@ -295,7 +310,7 @@ public class IoLib extends OneArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private File input() {
|
private File input() {
|
||||||
return infile!=null? infile: (infile=ioopenfile("-","r"));
|
return infile!=null? infile: (infile=ioopenfile(FTYPE_STDIN, "-","r"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// io.flush() -> bool
|
// io.flush() -> bool
|
||||||
@@ -320,7 +335,7 @@ public class IoLib extends OneArgFunction {
|
|||||||
// io.input([file]) -> file
|
// io.input([file]) -> file
|
||||||
public Varargs _io_input(LuaValue file) {
|
public Varargs _io_input(LuaValue file) {
|
||||||
infile = file.isnil()? input():
|
infile = file.isnil()? input():
|
||||||
file.isstring()? ioopenfile(file.checkjstring(),"r"):
|
file.isstring()? ioopenfile(FTYPE_NAMED, file.checkjstring(),"r"):
|
||||||
checkfile(file);
|
checkfile(file);
|
||||||
return infile;
|
return infile;
|
||||||
}
|
}
|
||||||
@@ -328,7 +343,7 @@ public class IoLib extends OneArgFunction {
|
|||||||
// io.output(filename) -> file
|
// io.output(filename) -> file
|
||||||
public Varargs _io_output(LuaValue filename) {
|
public Varargs _io_output(LuaValue filename) {
|
||||||
outfile = filename.isnil()? output():
|
outfile = filename.isnil()? output():
|
||||||
filename.isstring()? ioopenfile(filename.checkjstring(),"w"):
|
filename.isstring()? ioopenfile(FTYPE_NAMED, filename.checkjstring(),"w"):
|
||||||
checkfile(filename);
|
checkfile(filename);
|
||||||
return outfile;
|
return outfile;
|
||||||
}
|
}
|
||||||
@@ -348,12 +363,12 @@ public class IoLib extends OneArgFunction {
|
|||||||
|
|
||||||
// io.open(filename, [mode]) -> file | nil,err
|
// io.open(filename, [mode]) -> file | nil,err
|
||||||
public Varargs _io_open(String filename, String mode) throws IOException {
|
public Varargs _io_open(String filename, String mode) throws IOException {
|
||||||
return rawopenfile(filename, mode);
|
return rawopenfile(FTYPE_NAMED, filename, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// io.lines(filename) -> iterator
|
// io.lines(filename) -> iterator
|
||||||
public Varargs _io_lines(String filename) {
|
public Varargs _io_lines(String filename) {
|
||||||
infile = filename==null? input(): ioopenfile(filename,"r");
|
infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r");
|
||||||
checkopen(infile);
|
checkopen(infile);
|
||||||
return lines(infile);
|
return lines(infile);
|
||||||
}
|
}
|
||||||
@@ -420,16 +435,16 @@ public class IoLib extends OneArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private File output() {
|
private File output() {
|
||||||
return outfile!=null? outfile: (outfile=ioopenfile("-","w"));
|
return outfile!=null? outfile: (outfile=ioopenfile(FTYPE_STDOUT,"-","w"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private File errput() {
|
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 {
|
try {
|
||||||
return rawopenfile(filename, mode);
|
return rawopenfile(filetype, filename, mode);
|
||||||
} catch ( Exception e ) {
|
} catch ( Exception e ) {
|
||||||
error("io error: "+e.getMessage());
|
error("io error: "+e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
@@ -518,14 +533,13 @@ public class IoLib extends OneArgFunction {
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
private File rawopenfile(String filename, String mode) throws IOException {
|
private File rawopenfile(int filetype, String filename, String mode) throws IOException {
|
||||||
boolean isstdfile = "-".equals(filename);
|
switch (filetype) {
|
||||||
boolean isreadmode = mode.startsWith("r");
|
case FTYPE_STDIN: return wrapStdin();
|
||||||
if ( isstdfile ) {
|
case FTYPE_STDOUT: return wrapStdout();
|
||||||
return isreadmode?
|
case FTYPE_STDERR: return wrapStderr();
|
||||||
wrapStdin():
|
|
||||||
wrapStdout();
|
|
||||||
}
|
}
|
||||||
|
boolean isreadmode = mode.startsWith("r");
|
||||||
boolean isappend = mode.startsWith("a");
|
boolean isappend = mode.startsWith("a");
|
||||||
boolean isupdate = mode.indexOf("+") > 0;
|
boolean isupdate = mode.indexOf("+") > 0;
|
||||||
boolean isbinary = mode.endsWith("b");
|
boolean isbinary = mode.endsWith("b");
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ public class JmeIoLib extends IoLib {
|
|||||||
return new FileImpl(globals.STDOUT);
|
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 {
|
protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException {
|
||||||
String url = "file:///" + filename;
|
String url = "file:///" + filename;
|
||||||
int mode = readMode? Connector.READ: Connector.READ_WRITE;
|
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.BufferedInputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaError;
|
import org.luaj.vm2.LuaError;
|
||||||
@@ -68,11 +70,15 @@ import org.luaj.vm2.lib.LibFunction;
|
|||||||
public class JseIoLib extends IoLib {
|
public class JseIoLib extends IoLib {
|
||||||
|
|
||||||
protected File wrapStdin() throws IOException {
|
protected File wrapStdin() throws IOException {
|
||||||
return new FileImpl(globals.STDIN);
|
return new StdinFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected File wrapStdout() throws IOException {
|
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 {
|
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");
|
throw new LuaError("not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final class FileImpl extends File {
|
private final class FileImpl extends File {
|
||||||
private final RandomAccessFile file;
|
private final RandomAccessFile file;
|
||||||
private final InputStream is;
|
private final InputStream is;
|
||||||
@@ -215,4 +222,120 @@ public class JseIoLib extends IoLib {
|
|||||||
return length;
|
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