提交 35bc9ddf 编写于 作者: R Ryan Dahl

Implement deno.readFile()

As an example of how to implement ops that have both sync and async
versions.
上级 c29392b2
......@@ -196,6 +196,7 @@ run_node("gen_declarations") {
"js/global-eval.ts",
"js/globals.ts",
"js/os.ts",
"js/read_file.ts",
"js/text_encoding.ts",
"js/timers.ts",
"js/tsconfig.generated.json",
......@@ -234,6 +235,7 @@ run_node("bundle") {
"js/main.ts",
"js/os.ts",
"js/plugins.d.ts",
"js/read_file.ts",
"js/text_encoding.ts",
"js/timers.ts",
"js/types.ts",
......
......@@ -7,12 +7,12 @@ export {
FileInfo,
makeTempDirSync,
mkdirSync,
readFileSync,
renameSync,
statSync,
lstatSync,
writeFileSync
} from "./os";
export { readFileSync, readFile } from "./read_file";
export { ErrorKind, DenoError } from "./errors";
export { libdeno } from "./libdeno";
export const argv: string[] = [];
......@@ -126,37 +126,6 @@ export function mkdirSync(path: string, mode = 0o777): void {
sendSync(builder, fbs.Any.MkdirSync, msg);
}
/**
* Read the file.
* import { readFileSync } from "deno";
*
* const decoder = new TextDecoder("utf-8");
* const data = readFileSync("hello.txt");
* console.log(decoder.decode(data));
*/
export function readFileSync(filename: string): Uint8Array {
/* Ideally we could write
const res = sendSync({
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);
const baseRes = sendSync(builder, fbs.Any.ReadFileSync, msg);
assert(baseRes != null);
assert(fbs.Any.ReadFileSyncRes === baseRes!.msgType());
const res = new fbs.ReadFileSyncRes();
assert(baseRes!.msg(res) != null);
const dataArray = res.dataArray();
assert(dataArray != null);
return new Uint8Array(dataArray!);
}
function createEnv(_msg: fbs.EnvironRes): { [index: string]: string } {
const env: { [index: string]: string } = {};
......@@ -365,13 +334,6 @@ export function writeFileSync(
* renameSync(oldpath, newpath);
*/
export function renameSync(oldpath: string, newpath: string): void {
/* Ideally we could write:
const res = sendSync({
command: fbs.Command.RENAME_SYNC,
renameOldPath: oldpath,
renameNewPath: newpath
});
*/
const builder = new flatbuffers.Builder();
const _oldpath = builder.createString(oldpath);
const _newpath = builder.createString(newpath);
......
......@@ -85,34 +85,6 @@ test(async function lstatSyncNotFound() {
assertEqual(badInfo, undefined);
});
test(async function readFileSyncSuccess() {
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);
assertEqual(pkg.name, "deno");
});
/* TODO We should be able to catch specific types.
test(function tests_readFileSync_NotFound() {
let caughtError = false;
let data;
try {
data = deno.readFileSync("bad_filename");
} catch (e) {
caughtError = true;
assert(e instanceof deno.NotFound);
}
assert(caughtError);
assert(data === undefined);
});
*/
testPerm({ write: true }, function writeFileSyncSuccess() {
const enc = new TextEncoder();
const data = enc.encode("Hello");
......
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
import * as fbs from "gen/msg_generated";
import { flatbuffers } from "flatbuffers";
import { assert } from "./util";
import * as dispatch from "./dispatch";
/**
* Read the entire contents of a file synchronously.
*
* import { readFileSync } from "deno";
* const decoder = new TextDecoder("utf-8");
* const data = readFileSync("hello.txt");
* console.log(decoder.decode(data));
*/
export function readFileSync(filename: string): Uint8Array {
return res(dispatch.sendSync(...req(filename)));
}
/**
* Read the entire contents of a file.
*
* import { readFile } from "deno";
* const decoder = new TextDecoder("utf-8");
* const data = await readFile("hello.txt");
* console.log(decoder.decode(data));
*/
export async function readFile(filename: string): Promise<Uint8Array> {
return res(await dispatch.sendAsync(...req(filename)));
}
function req(
filename: string
): [flatbuffers.Builder, fbs.Any, flatbuffers.Offset] {
const builder = new flatbuffers.Builder();
const filename_ = builder.createString(filename);
fbs.ReadFile.startReadFile(builder);
fbs.ReadFile.addFilename(builder, filename_);
const msg = fbs.ReadFile.endReadFile(builder);
return [builder, fbs.Any.ReadFile, msg];
}
function res(baseRes: null | fbs.Base): Uint8Array {
assert(baseRes != null);
assert(fbs.Any.ReadFileRes === baseRes!.msgType());
const msg = new fbs.ReadFileRes();
assert(baseRes!.msg(msg) != null);
const dataArray = msg.dataArray();
assert(dataArray != null);
return new Uint8Array(dataArray!);
}
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
import { test, assert, assertEqual } from "./test_util.ts";
import * as deno from "deno";
test(function readFileSyncSuccess() {
const data = deno.readFileSync("package.json");
assert(data.byteLength > 0);
const decoder = new TextDecoder("utf-8");
const json = decoder.decode(data);
const pkg = JSON.parse(json);
assertEqual(pkg.name, "deno");
});
test(function readFileSyncNotFound() {
let caughtError = false;
let data;
try {
data = deno.readFileSync("bad_filename");
} catch (e) {
caughtError = true;
assertEqual(e.kind, deno.ErrorKind.NotFound);
}
assert(caughtError);
assert(data === undefined);
});
test(async function readFileSuccess() {
const data = await deno.readFile("package.json");
assert(data.byteLength > 0);
const decoder = new TextDecoder("utf-8");
const json = decoder.decode(data);
const pkg = JSON.parse(json);
assertEqual(pkg.name, "deno");
});
......@@ -3,5 +3,6 @@
// But it can also be run manually: ./out/debug/deno js/unit_tests.ts
import "./compiler_test.ts";
import "./console_test.ts";
import "./os_test.ts";
import "./fetch_test.ts";
import "./os_test.ts";
import "./read_file_test.ts";
......@@ -50,7 +50,7 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) {
msg::Any::TimerClear => handle_timer_clear,
msg::Any::MakeTempDir => handle_make_temp_dir,
msg::Any::MkdirSync => handle_mkdir_sync,
msg::Any::ReadFileSync => handle_read_file_sync,
msg::Any::ReadFile => handle_read_file,
msg::Any::RenameSync => handle_rename_sync,
msg::Any::SetEnv => handle_set_env,
msg::Any::StatSync => handle_stat_sync,
......@@ -430,20 +430,20 @@ fn handle_mkdir_sync(d: *const DenoC, base: &msg::Base) -> Box<Op> {
}
// Prototype https://github.com/denoland/deno/blob/golang/os.go#L171-L184
fn handle_read_file_sync(_d: *const DenoC, base: &msg::Base) -> Box<Op> {
let msg = base.msg_as_read_file_sync().unwrap();
fn handle_read_file(_d: *const DenoC, base: &msg::Base) -> Box<Op> {
let msg = base.msg_as_read_file().unwrap();
let cmd_id = base.cmd_id();
let filename = String::from(msg.filename().unwrap());
Box::new(futures::future::result(|| -> OpResult {
debug!("handle_read_file_sync {}", filename);
debug!("handle_read_file {}", filename);
let vec = fs::read(Path::new(&filename))?;
// Build the response message. memcpy data into msg.
// TODO(ry) zero-copy.
let builder = &mut FlatBufferBuilder::new();
let data_off = builder.create_vector(vec.as_slice());
let msg = msg::ReadFileSyncRes::create(
let msg = msg::ReadFileRes::create(
builder,
&msg::ReadFileSyncResArgs {
&msg::ReadFileResArgs {
data: Some(data_off),
..Default::default()
},
......@@ -453,7 +453,7 @@ fn handle_read_file_sync(_d: *const DenoC, base: &msg::Base) -> Box<Op> {
builder,
msg::BaseArgs {
msg: Some(msg.as_union_value()),
msg_type: msg::Any::ReadFileSyncRes,
msg_type: msg::Any::ReadFileRes,
..Default::default()
},
))
......
......@@ -15,8 +15,8 @@ union Any {
MakeTempDir,
MakeTempDirRes,
MkdirSync,
ReadFileSync,
ReadFileSyncRes,
ReadFile,
ReadFileRes,
RenameSync,
StatSync,
StatSyncRes,
......@@ -173,11 +173,11 @@ table MkdirSync {
// mode specified by https://godoc.org/os#FileMode
}
table ReadFileSync {
table ReadFile {
filename: string;
}
table ReadFileSyncRes {
table ReadFileRes {
data: [ubyte];
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册