diff --git a/src/main/java/erjang/driver/efile/EFile.java b/src/main/java/erjang/driver/efile/EFile.java index 40f66c12..315fa4bf 100644 --- a/src/main/java/erjang/driver/efile/EFile.java +++ b/src/main/java/erjang/driver/efile/EFile.java @@ -361,6 +361,9 @@ public static class Info { public static final byte FILE_RESP_LDATA = 6; public static final byte FILE_RESP_N2DATA = 7; public static final byte FILE_RESP_EOF = 8; + public static final byte FILE_RESP_FNAME = 9; + public static final byte FILE_RESP_ALL_DATA = 10; + private static final byte[] FILE_RESP_ALL_DATA_HEADER = new byte[]{ FILE_RESP_ALL_DATA }; /* Options */ @@ -877,7 +880,7 @@ public void ready() throws Pausable { } binp.flip(); - driver_output_binary(FILE_RESP_OK_HEADER, binp); + driver_output_binary(isUnicodeDriverInterface() ? FILE_RESP_ALL_DATA_HEADER : FILE_RESP_OK_HEADER, binp); } }; @@ -1389,10 +1392,22 @@ public void ready() throws Pausable { if (!result_ok) { reply_posix_error(posix_errno); } else { - ByteBuffer reply = ByteBuffer.allocate(1+pwd.length()); - reply.put(FILE_RESP_OK); - IO.putstr(reply, pwd, false); - driver_output2(reply, null); + ByteBuffer reply = null; + ByteBuffer data = null; + if (isUnicodeDriverInterface()) { + // prim_file interface from R14 on + reply = ByteBuffer.allocate(1); + data = ByteBuffer.allocate(pwd.length()); + reply.put(FILE_RESP_FNAME); + IO.putstr(data, pwd, false); + } + else { + // prim_file interface up to R13B + reply = ByteBuffer.allocate(1+pwd.length()); + reply.put(FILE_RESP_OK); + IO.putstr(reply, pwd, false); + } + driver_output2(reply, data); } } @@ -1902,19 +1917,55 @@ public String toString() { void reply_list_directory(String[] files) throws Pausable { for (int i = 0; i < files.length; i++) { - ByteBuffer resbuf = ByteBuffer.allocate(files[i].length()+1); - resbuf.put(FILE_RESP_OK); - resbuf.limit(resbuf.capacity()); - resbuf.position(1); - - IO.putstr(resbuf, files[i], false); - - driver_output2(resbuf, null); + if (isUnicodeDriverInterface()) { + // prim_file interface from R14 on + ByteBuffer reply = ByteBuffer.allocate(1); + reply.put(FILE_RESP_FNAME); + + ByteBuffer data = ByteBuffer.allocate(files[i].length()); + data.limit(data.capacity()); + data.position(0); + IO.putstr(data, files[i], false); + + driver_output2(reply, data); + } + else { + // prim_file interface up to R13B + ByteBuffer resbuf = ByteBuffer.allocate(files[i].length()+1); + resbuf.put(FILE_RESP_OK); + resbuf.limit(resbuf.capacity()); + resbuf.position(1); + + IO.putstr(resbuf, files[i], false); + + driver_output2(resbuf, null); + } } ByteBuffer resbuf = ByteBuffer.allocate(1); - resbuf.put(FILE_RESP_OK); + resbuf.put(isUnicodeDriverInterface() ? FILE_RESP_FNAME : FILE_RESP_OK); driver_output2(resbuf, null); } + /** + * the new unicode driver interface is used since OTP version R14B01. + * + * @see http://www.erlang.org/doc/apps/stdlib/unicode_usage.html#id60205 + */ + static boolean unicodeDriverInterface = ("R14B".compareTo(erjang.Main.OTP_VERSION) <= 0); + + /** + * Determine whether to use the new unicode driver interface + * from R14B01. + * + * @return true, if the new driver interface + * from R14B01 is to be used, false for the older + * driver interface up to R13 + * + * @see http://www.erlang.org/doc/apps/stdlib/unicode_usage.html#id60205 + */ + private static boolean isUnicodeDriverInterface() { + return unicodeDriverInterface; + } + }