Fixed issue: #55
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
core/src/main/java/org/luaj/vm2/libs/IoLib$LinesIterator.class
Normal file
BIN
core/src/main/java/org/luaj/vm2/libs/IoLib$LinesIterator.class
Normal file
Binary file not shown.
Binary file not shown.
@@ -81,6 +81,10 @@ public class IoLib extends TwoArgFunction {
|
||||
abstract public void write( LuaString string ) throws IOException;
|
||||
abstract public void flush() throws IOException;
|
||||
abstract public boolean isstdfile();
|
||||
/**
|
||||
* Close the underlying resource explicitly.
|
||||
* Callers must not rely on garbage collection or finalization for cleanup.
|
||||
*/
|
||||
abstract public void close() throws IOException;
|
||||
abstract public boolean isclosed();
|
||||
// returns new position
|
||||
@@ -118,18 +122,6 @@ public class IoLib extends TwoArgFunction {
|
||||
public String tojstring() {
|
||||
return "file: " + Integer.toHexString(hashCode());
|
||||
}
|
||||
|
||||
public void finalize() throws Throwable {
|
||||
try {
|
||||
if (!isclosed()) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException ignore) {}
|
||||
}
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Enumerated value representing stdin */
|
||||
@@ -222,12 +214,15 @@ public class IoLib extends TwoArgFunction {
|
||||
|
||||
private static final int IO_INDEX = 18;
|
||||
private static final int LINES_ITER = 19;
|
||||
private static final int IO_LINESX = 20;
|
||||
private static final int FILE_LINESX = 21;
|
||||
|
||||
public static final String[] IO_NAMES = {
|
||||
"close",
|
||||
"flush",
|
||||
"input",
|
||||
"lines",
|
||||
"linesx",
|
||||
"open",
|
||||
"output",
|
||||
"popen",
|
||||
@@ -241,6 +236,7 @@ public class IoLib extends TwoArgFunction {
|
||||
"close",
|
||||
"flush",
|
||||
"lines",
|
||||
"linesx",
|
||||
"read",
|
||||
"seek",
|
||||
"setvbuf",
|
||||
@@ -316,6 +312,7 @@ public class IoLib extends TwoArgFunction {
|
||||
case IO_POPEN: return iolib._io_popen(args.checkjstring(1),args.optjstring(2,"r"));
|
||||
case IO_OPEN: return iolib._io_open(args.checkjstring(1), args.optjstring(2,"r"));
|
||||
case IO_LINES: return iolib._io_lines(args);
|
||||
case IO_LINESX: return iolib._io_linesx(args);
|
||||
case IO_READ: return iolib._io_read(args);
|
||||
case IO_WRITE: return iolib._io_write(args);
|
||||
|
||||
@@ -323,6 +320,7 @@ public class IoLib extends TwoArgFunction {
|
||||
case FILE_FLUSH: return iolib._file_flush(args.arg1());
|
||||
case FILE_SETVBUF: return iolib._file_setvbuf(args.arg1(),args.checkjstring(2),args.optint(3,8192));
|
||||
case FILE_LINES: return iolib._file_lines(args);
|
||||
case FILE_LINESX: return iolib._file_linesx(args);
|
||||
case FILE_READ: return iolib._file_read(args.arg1(),args.subargs(2));
|
||||
case FILE_SEEK: return iolib._file_seek(args.arg1(),args.optjstring(2,"cur"),args.optint(3,0));
|
||||
case FILE_WRITE: return iolib._file_write(args.arg1(),args.subargs(2));
|
||||
@@ -332,6 +330,12 @@ public class IoLib extends TwoArgFunction {
|
||||
}
|
||||
} catch ( IOException ioe ) {
|
||||
if (opcode == LINES_ITER) {
|
||||
if (toclose && f != null && !f.isclosed()) {
|
||||
try {
|
||||
f.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
String s = ioe.getMessage();
|
||||
error(s != null ? s : ioe.toString());
|
||||
}
|
||||
@@ -407,6 +411,14 @@ public class IoLib extends TwoArgFunction {
|
||||
return lines(infile, filename != null, args.subargs(2));
|
||||
}
|
||||
|
||||
// io.linesx(filename, ...) -> closable iterator
|
||||
public Varargs _io_linesx(Varargs args) {
|
||||
String filename = args.optjstring(1, null);
|
||||
File infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r");
|
||||
checkopen(infile);
|
||||
return linesx(infile, filename != null, args.subargs(2));
|
||||
}
|
||||
|
||||
// io.read(...) -> (...)
|
||||
public Varargs _io_read(Varargs args) throws IOException {
|
||||
checkopen(input());
|
||||
@@ -447,6 +459,11 @@ public class IoLib extends TwoArgFunction {
|
||||
return lines(checkfile(args.arg1()), false, args.subargs(2));
|
||||
}
|
||||
|
||||
// file:linesx(...) -> closable iterator
|
||||
public Varargs _file_linesx(Varargs args) {
|
||||
return linesx(checkfile(args.arg1()), false, args.subargs(2));
|
||||
}
|
||||
|
||||
// file:read(...) -> (...)
|
||||
public Varargs _file_read(LuaValue file, Varargs subargs) throws IOException {
|
||||
return ioread(checkfile(file),subargs);
|
||||
@@ -481,7 +498,7 @@ public class IoLib extends TwoArgFunction {
|
||||
if ( f == null ) argerror(1, "not a file: " + file);
|
||||
if ( f.isclosed() ) error("file is already closed");
|
||||
Varargs ret = ioread(f, args);
|
||||
if (toclose && ret.isnil(1) && f.eof()) f.close();
|
||||
if (toclose && ret.isnil(1) && !f.isclosed()) f.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -532,6 +549,84 @@ public class IoLib extends TwoArgFunction {
|
||||
}
|
||||
}
|
||||
|
||||
private Varargs linesx(final File f, boolean toclose, Varargs args) {
|
||||
try {
|
||||
return new LinesIterator(f, toclose, args);
|
||||
} catch ( Exception e ) {
|
||||
return error("linesx: "+e);
|
||||
}
|
||||
}
|
||||
|
||||
private final class LinesIterator extends LuaTable {
|
||||
private final File file;
|
||||
private final boolean toclose;
|
||||
private final Varargs args;
|
||||
private boolean closed;
|
||||
|
||||
LinesIterator(File file, boolean toclose, Varargs args) {
|
||||
this.file = file;
|
||||
this.toclose = toclose;
|
||||
this.args = args.dealias();
|
||||
set("next", new next());
|
||||
set("close", new close());
|
||||
LuaTable mt = new LuaTable();
|
||||
mt.set(CALL, new invoke());
|
||||
setmetatable(mt);
|
||||
}
|
||||
|
||||
private Varargs nextLine() {
|
||||
if (closed || file.isclosed()) {
|
||||
return NIL;
|
||||
}
|
||||
try {
|
||||
Varargs ret = ioread(file, args);
|
||||
if (toclose && ret.isnil(1) && !file.isclosed()) {
|
||||
file.close();
|
||||
closed = true;
|
||||
}
|
||||
return ret;
|
||||
} catch (IOException ioe) {
|
||||
if (!file.isclosed()) {
|
||||
try {
|
||||
file.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
closed = true;
|
||||
String s = ioe.getMessage();
|
||||
error(s != null ? s : ioe.toString());
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
private final class invoke extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
return nextLine();
|
||||
}
|
||||
}
|
||||
|
||||
private final class next extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
return nextLine();
|
||||
}
|
||||
}
|
||||
|
||||
private final class close extends OneArgFunction {
|
||||
public LuaValue call(LuaValue self) {
|
||||
if (!closed && !file.isclosed()) {
|
||||
try {
|
||||
file.close();
|
||||
} catch (IOException ioe) {
|
||||
String s = ioe.getMessage();
|
||||
error(s != null ? s : ioe.toString());
|
||||
}
|
||||
}
|
||||
closed = true;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Varargs iowrite(File f, Varargs args) throws IOException {
|
||||
for ( int i=1, n=args.narg(); i<=n; i++ )
|
||||
f.write( args.checkstring(i) );
|
||||
@@ -685,4 +780,4 @@ public class IoLib extends TwoArgFunction {
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user