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;
+ }
+
}