@@ -152,6 +152,9 @@ private void writeMockJavaClasses(Path sourceDir) throws Exception {
152152 " public final native Class<?> getClass();\n " +
153153 "}\n " ).getBytes (StandardCharsets .UTF_8 ));
154154
155+ // java.lang.AutoCloseable
156+ Files .write (lang .resolve ("AutoCloseable.java" ), "package java.lang; public interface AutoCloseable { void close() throws java.io.IOException; }" .getBytes (StandardCharsets .UTF_8 ));
157+
155158 // java.lang.String
156159 Files .write (lang .resolve ("String.java" ), ("package java.lang;\n " +
157160 "public class String {\n " +
@@ -286,6 +289,35 @@ private void writeMockJavaClasses(Path sourceDir) throws Exception {
286289 // java.io.Serializable
287290 Files .write (io .resolve ("Serializable.java" ), "package java.io; public interface Serializable {}" .getBytes (StandardCharsets .UTF_8 ));
288291
292+ // java.io.IOException
293+ Files .write (io .resolve ("IOException.java" ), "package java.io; public class IOException extends Exception { public IOException() {} public IOException(String s) { super(s); } }" .getBytes (StandardCharsets .UTF_8 ));
294+
295+ // java.io.InputStream
296+ Files .write (io .resolve ("InputStream.java" ), ("package java.io;\n " +
297+ "public class InputStream implements java.lang.AutoCloseable {\n " +
298+ " public InputStream() {}\n " +
299+ " public int available() throws IOException { return 0; }\n " +
300+ " public int read() throws IOException { return -1; }\n " +
301+ " public int read(byte[] b, int off, int len) throws IOException { return read(); }\n " +
302+ " public long skip(long n) throws IOException { return 0; }\n " +
303+ " public void close() throws IOException {}\n " +
304+ " public synchronized void mark(int readlimit) {}\n " +
305+ " public void reset() throws IOException { throw new IOException(); }\n " +
306+ " public boolean markSupported() { return false; }\n " +
307+ "}\n " ).getBytes (StandardCharsets .UTF_8 ));
308+
309+ // java.io.OutputStream
310+ Files .write (io .resolve ("OutputStream.java" ), ("package java.io;\n " +
311+ "public class OutputStream implements java.lang.AutoCloseable {\n " +
312+ " public OutputStream() {}\n " +
313+ " public void write(int b) throws IOException {}\n " +
314+ " public void write(byte[] b, int off, int len) throws IOException {\n " +
315+ " for (int i = 0; i < len; i++) { write(b[off + i]); }\n " +
316+ " }\n " +
317+ " public void flush() throws IOException {}\n " +
318+ " public void close() throws IOException {}\n " +
319+ "}\n " ).getBytes (StandardCharsets .UTF_8 ));
320+
289321 // Minimal java.io.File to satisfy translator native headers
290322 Files .write (io .resolve ("File.java" ), ("package java.io;\n " +
291323 "public class File {\n " +
@@ -341,29 +373,47 @@ private void writeMockJavaClasses(Path sourceDir) throws Exception {
341373 "}\n " ).getBytes (StandardCharsets .UTF_8 ));
342374
343375 Files .write (io .resolve ("FileInputStream.java" ), ("package java.io;\n " +
344- "public class FileInputStream {\n " +
345- " public FileInputStream(String name) { open(name); }\n " +
346- " public FileInputStream(File file) { open(file); }\n " +
347- " public native int read();\n " +
348- " public native int read(byte[] b, int off, int len);\n " +
349- " public native long skip(long n);\n " +
350- " public native int available();\n " +
351- " public native void close();\n " +
352- " private native void open(String name);\n " +
353- " private native void open(File file);\n " +
376+ "public class FileInputStream extends InputStream {\n " +
377+ " private long handle;\n " +
378+ " private boolean closed;\n " +
379+ " public FileInputStream(String name) throws IOException { this(name == null ? null : new File(name)); }\n " +
380+ " public FileInputStream(File file) throws IOException {\n " +
381+ " if (file == null) throw new NullPointerException();\n " +
382+ " this.handle = openImpl(file.getPath());\n " +
383+ " if (this.handle == 0) throw new IOException();\n " +
384+ " }\n " +
385+ " public int read() throws IOException { byte[] b = new byte[1]; int c = read(b,0,1); return c <= 0 ? -1 : b[0] & 0xff; }\n " +
386+ " public int read(byte[] b, int off, int len) throws IOException { if (closed) throw new IOException(); return readImpl(handle, b, off, len); }\n " +
387+ " public long skip(long n) throws IOException { if (closed) throw new IOException(); return skipImpl(handle, n); }\n " +
388+ " public int available() throws IOException { if (closed) throw new IOException(); return availableImpl(handle); }\n " +
389+ " public void close() throws IOException { if (!closed) { closed = true; closeImpl(handle); handle = 0; } }\n " +
390+ " private static native long openImpl(String path) throws IOException;\n " +
391+ " private static native int readImpl(long handle, byte[] b, int off, int len) throws IOException;\n " +
392+ " private static native long skipImpl(long handle, long n) throws IOException;\n " +
393+ " private static native int availableImpl(long handle) throws IOException;\n " +
394+ " private static native void closeImpl(long handle) throws IOException;\n " +
354395 "}\n " ).getBytes (StandardCharsets .UTF_8 ));
355396
356397 Files .write (io .resolve ("FileOutputStream.java" ), ("package java.io;\n " +
357- "public class FileOutputStream {\n " +
358- " public FileOutputStream(String name) { open(name, false); }\n " +
359- " public FileOutputStream(String name, boolean append) { open(name, append); }\n " +
360- " public FileOutputStream(File file) { open(file.getPath(), false); }\n " +
361- " public FileOutputStream(File file, boolean append) { open(file.getPath(), append); }\n " +
362- " public native void write(int b);\n " +
363- " public native void write(byte[] b, int off, int len);\n " +
364- " public native void flush();\n " +
365- " public native void close();\n " +
366- " private native void open(String name, boolean append);\n " +
398+ "public class FileOutputStream extends OutputStream {\n " +
399+ " private long handle;\n " +
400+ " private boolean closed;\n " +
401+ " public FileOutputStream(String name) throws IOException { this(name, false); }\n " +
402+ " public FileOutputStream(String name, boolean append) throws IOException { this(name == null ? null : new File(name), append); }\n " +
403+ " public FileOutputStream(File file) throws IOException { this(file, false); }\n " +
404+ " public FileOutputStream(File file, boolean append) throws IOException {\n " +
405+ " if (file == null) throw new NullPointerException();\n " +
406+ " this.handle = openImpl(file.getPath(), append);\n " +
407+ " if (this.handle == 0) throw new IOException();\n " +
408+ " }\n " +
409+ " public void write(int b) throws IOException { byte[] tmp = new byte[]{(byte)b}; write(tmp,0,1); }\n " +
410+ " public void write(byte[] b, int off, int len) throws IOException { if (closed) throw new IOException(); writeImpl(handle, b, off, len); }\n " +
411+ " public void flush() throws IOException { if (closed) throw new IOException(); flushImpl(handle); }\n " +
412+ " public void close() throws IOException { if (!closed) { closed = true; flushImpl(handle); closeImpl(handle); handle = 0; } }\n " +
413+ " private static native long openImpl(String path, boolean append) throws IOException;\n " +
414+ " private static native void writeImpl(long handle, byte[] b, int off, int len) throws IOException;\n " +
415+ " private static native void flushImpl(long handle) throws IOException;\n " +
416+ " private static native void closeImpl(long handle) throws IOException;\n " +
367417 "}\n " ).getBytes (StandardCharsets .UTF_8 ));
368418
369419 Files .write (io .resolve ("FileWriter.java" ), ("package java.io;\n " +
0 commit comments