summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--js/os.ts29
-rw-r--r--src/handlers.h1
-rw-r--r--src/handlers.rs59
-rw-r--r--src/reply.cc7
-rw-r--r--tests/read_file_sync.ts18
-rw-r--r--tests/read_file_sync.ts.out1
6 files changed, 110 insertions, 5 deletions
diff --git a/js/os.ts b/js/os.ts
index ab73395b3..a3f45e467 100644
--- a/js/os.ts
+++ b/js/os.ts
@@ -85,15 +85,34 @@ export function codeCache(
}
export function readFileSync(filename: string): Uint8Array {
- assert(false, "Not Implemented");
- return null;
- /*
- const res = pubInternal("os", {
+ /* Ideally we could write
+ const res = send({
command: fbs.Command.READ_FILE_SYNC,
readFileSyncFilename: filename
});
return res.readFileSyncData;
- */
+ */
+ const builder = new flatbuffers.Builder();
+ const filename_ = builder.createString(filename);
+ fbs.ReadFileSync.startReadFileSync(builder);
+ fbs.ReadFileSync.addFilename(builder, filename_);
+ const msg = fbs.ReadFileSync.endReadFileSync(builder);
+ fbs.Base.startBase(builder);
+ fbs.Base.addMsg(builder, msg);
+ fbs.Base.addMsgType(builder, fbs.Any.ReadFileSync);
+ builder.finish(fbs.Base.endBase(builder));
+ const resBuf = libdeno.send(builder.asUint8Array());
+ assert(resBuf != null);
+
+ const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf));
+ const baseRes = fbs.Base.getRootAsBase(bb);
+ if (fbs.Any.NONE === baseRes.msgType()) {
+ throw Error(baseRes.error());
+ }
+ assert(fbs.Any.ReadFileSyncRes === baseRes.msgType());
+ const res = new fbs.ReadFileSyncRes();
+ assert(baseRes.msg(res) != null);
+ return new Uint8Array(res.dataArray());
}
export function writeFileSync(
diff --git a/src/handlers.h b/src/handlers.h
index decbe59da..715db3483 100644
--- a/src/handlers.h
+++ b/src/handlers.h
@@ -14,5 +14,6 @@ void handle_code_cache(Deno* d, uint32_t cmd_id, const char* filename,
void handle_timer_start(Deno* d, uint32_t cmd_id, uint32_t timer_id,
bool interval, uint32_t delay);
void handle_timer_clear(Deno* d, uint32_t cmd_id, uint32_t timer_id);
+void handle_read_file_sync(Deno* d, uint32_t cmd_id, const char* filename);
} // extern "C"
#endif // HANDLERS_H_
diff --git a/src/handlers.rs b/src/handlers.rs
index 480d7b6b8..f0c64e46e 100644
--- a/src/handlers.rs
+++ b/src/handlers.rs
@@ -2,12 +2,17 @@
use binding;
use binding::{deno_buf, deno_set_response, DenoC};
use flatbuffers;
+use flatbuffers::ByteStringOffset;
+use flatbuffers::LabeledUOffsetT;
use from_c;
+use fs;
use futures;
use futures::sync::oneshot;
use libc::c_char;
+use mem;
use msg_generated::deno as msg;
use std::ffi::CStr;
+use std::path::Path;
// Help. Is there a way to do this without macros?
// Want: fn str_from_ptr(*const c_char) -> &str
@@ -226,6 +231,60 @@ fn send_timer_ready(d: *const DenoC, timer_id: u32, done: bool) {
);
}
+// Prototype https://github.com/denoland/deno/blob/golang/os.go#L171-L184
+#[no_mangle]
+pub extern "C" fn handle_read_file_sync(
+ d: *const DenoC,
+ cmd_id: u32,
+ filename: *const c_char,
+) {
+ let filename = str_from_ptr!(filename);
+
+ debug!("handle_read_file_sync {}", filename);
+ let result = fs::read_file_sync(Path::new(filename));
+ if result.is_err() {
+ let err = result.unwrap_err();
+ let errmsg = format!("{}", err);
+ reply_error(d, cmd_id, &errmsg);
+ return;
+ }
+
+ // Build the response message. memcpy data into msg.
+ let mut builder = flatbuffers::FlatBufferBuilder::new();
+
+ let vec = result.unwrap();
+ //let data =
+ // flatbuffers::LabeledUOffsetT::new(builder.push_bytes(vec.as_slice()));
+
+ let data_ = builder.create_byte_vector(vec.as_slice());
+
+ // TODO(ry) This is a hack that can be removed once builder.create_byte_vector
+ // works properly.
+ let data = unsafe {
+ mem::transmute::<LabeledUOffsetT<ByteStringOffset>, LabeledUOffsetT<&[i8]>>(
+ data_,
+ )
+ };
+
+ let msg = msg::CreateReadFileSyncRes(
+ &mut builder,
+ &msg::ReadFileSyncResArgs {
+ data,
+ ..Default::default()
+ },
+ );
+ builder.finish(msg);
+ set_response_base(
+ d,
+ &mut builder,
+ &msg::BaseArgs {
+ msg: Some(msg.union()),
+ msg_type: msg::Any::ReadFileSyncRes,
+ ..Default::default()
+ },
+ );
+}
+
// TODO(ry) Use Deno instead of DenoC as first arg.
fn remove_timer(d: *const DenoC, timer_id: u32) {
let deno = from_c(d);
diff --git a/src/reply.cc b/src/reply.cc
index dada4e168..62abe1364 100644
--- a/src/reply.cc
+++ b/src/reply.cc
@@ -95,6 +95,13 @@ void deno_handle_msg_from_js(Deno* d, deno_buf buf) {
break;
}
+ case deno::Any_ReadFileSync: {
+ auto msg = base->msg_as_ReadFileSync();
+ auto filename = msg->filename()->c_str();
+ handle_read_file_sync(d, cmd_id, filename);
+ break;
+ }
+
case deno::Any_NONE:
CHECK(false && "Got message with msg_type == Any_NONE");
break;
diff --git a/tests/read_file_sync.ts b/tests/read_file_sync.ts
new file mode 100644
index 000000000..9e6c555c8
--- /dev/null
+++ b/tests/read_file_sync.ts
@@ -0,0 +1,18 @@
+// TODO(ry) Once unit_tests.js lands (#448) this file should be removed
+// and replaced with a faster version like was done in the prototype.
+// https://github.com/denoland/deno/blob/golang/tests.ts#L34-L45
+import * as deno from "deno";
+
+const data = deno.readFileSync("package.json");
+if (!data.byteLength) {
+ throw Error(
+ `Expected positive value for data.byteLength ${data.byteLength}`
+ );
+}
+const decoder = new TextDecoder("utf-8");
+const json = decoder.decode(data);
+const pkg = JSON.parse(json);
+if (pkg['devDependencies'] == null) {
+ throw Error("Expected a positive number of devDependencies");
+}
+console.log("ok");
diff --git a/tests/read_file_sync.ts.out b/tests/read_file_sync.ts.out
new file mode 100644
index 000000000..9766475a4
--- /dev/null
+++ b/tests/read_file_sync.ts.out
@@ -0,0 +1 @@
+ok