summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/msg.fbs21
-rw-r--r--cli/ops.rs71
-rw-r--r--js/buffer.ts49
-rw-r--r--js/buffer_test.ts29
-rw-r--r--js/deno.ts9
-rw-r--r--js/files.ts180
-rw-r--r--js/files_test.ts36
-rw-r--r--js/io.ts11
-rw-r--r--js/read_file.ts37
-rw-r--r--js/write_file.ts70
10 files changed, 330 insertions, 183 deletions
diff --git a/cli/msg.fbs b/cli/msg.fbs
index 243034cfb..e6b860908 100644
--- a/cli/msg.fbs
+++ b/cli/msg.fbs
@@ -39,8 +39,6 @@ union Any {
Read,
ReadDir,
ReadDirRes,
- ReadFile,
- ReadFileRes,
ReadRes,
Readlink,
ReadlinkRes,
@@ -69,7 +67,6 @@ union Any {
WorkerGetMessageRes,
WorkerPostMessage,
Write,
- WriteFile,
WriteRes,
}
@@ -296,14 +293,6 @@ table Remove {
recursive: bool;
}
-table ReadFile {
- filename: string;
-}
-
-table ReadFileRes {
- data: [ubyte];
-}
-
table ReadDir {
path: string;
}
@@ -312,16 +301,6 @@ table ReadDirRes {
entries: [StatRes];
}
-table WriteFile {
- filename: string;
- data: [ubyte];
- update_perm: bool;
- perm: uint;
- // perm specified by https://godoc.org/os#FileMode
- is_create: bool;
- is_append: bool;
-}
-
table CopyFile {
from: string;
to: string;
diff --git a/cli/ops.rs b/cli/ops.rs
index 68e593934..8f5304793 100644
--- a/cli/ops.rs
+++ b/cli/ops.rs
@@ -174,7 +174,6 @@ pub fn op_selector_std(inner_type: msg::Any) -> Option<OpCreator> {
msg::Any::Permissions => Some(op_permissions),
msg::Any::Read => Some(op_read),
msg::Any::ReadDir => Some(op_read_dir),
- msg::Any::ReadFile => Some(op_read_file),
msg::Any::Readlink => Some(op_read_link),
msg::Any::Remove => Some(op_remove),
msg::Any::Rename => Some(op_rename),
@@ -193,7 +192,6 @@ pub fn op_selector_std(inner_type: msg::Any) -> Option<OpCreator> {
msg::Any::WorkerGetMessage => Some(op_worker_get_message),
msg::Any::WorkerPostMessage => Some(op_worker_post_message),
msg::Any::Write => Some(op_write),
- msg::Any::WriteFile => Some(op_write_file),
_ => None,
}
}
@@ -1026,45 +1024,6 @@ fn op_remove(
})
}
-// Prototype https://github.com/denoland/deno/blob/golang/os.go#L171-L184
-fn op_read_file(
- sc: &IsolateStateContainer,
- base: &msg::Base<'_>,
- data: deno_buf,
-) -> Box<OpWithError> {
- assert_eq!(data.len(), 0);
- let inner = base.inner_as_read_file().unwrap();
- let cmd_id = base.cmd_id();
- let filename_ = inner.filename().unwrap();
- let filename = PathBuf::from(filename_);
- debug!("op_read_file {}", filename.display());
- if let Err(e) = sc.state().check_read(&filename_) {
- return odd_future(e);
- }
- blocking(base.sync(), move || {
- let vec = fs::read(&filename)?;
- // Build the response message. memcpy data into inner.
- // TODO(ry) zero-copy.
- let builder = &mut FlatBufferBuilder::new();
- let data_off = builder.create_vector(vec.as_slice());
- let inner = msg::ReadFileRes::create(
- builder,
- &msg::ReadFileResArgs {
- data: Some(data_off),
- },
- );
- Ok(serialize_response(
- cmd_id,
- builder,
- msg::BaseArgs {
- inner: Some(inner.as_union_value()),
- inner_type: msg::Any::ReadFileRes,
- ..Default::default()
- },
- ))
- })
-}
-
fn op_copy_file(
sc: &IsolateStateContainer,
base: &msg::Base<'_>,
@@ -1260,36 +1219,6 @@ fn op_read_dir(
})
}
-fn op_write_file(
- sc: &IsolateStateContainer,
- base: &msg::Base<'_>,
- data: deno_buf,
-) -> Box<OpWithError> {
- let inner = base.inner_as_write_file().unwrap();
- let filename = String::from(inner.filename().unwrap());
- let update_perm = inner.update_perm();
- let perm = inner.perm();
- let is_create = inner.is_create();
- let is_append = inner.is_append();
-
- if let Err(e) = sc.state().check_write(&filename) {
- return odd_future(e);
- }
-
- blocking(base.sync(), move || -> OpResult {
- debug!("op_write_file {} {}", filename, data.len());
- deno_fs::write_file_2(
- Path::new(&filename),
- data,
- update_perm,
- perm,
- is_create,
- is_append,
- )?;
- Ok(empty_buf())
- })
-}
-
fn op_rename(
sc: &IsolateStateContainer,
base: &msg::Base<'_>,
diff --git a/js/buffer.ts b/js/buffer.ts
index c5be762f5..551e8c4d4 100644
--- a/js/buffer.ts
+++ b/js/buffer.ts
@@ -5,7 +5,7 @@
// https://github.com/golang/go/blob/master/LICENSE
//import * as io from "./io";
-import { Reader, Writer, ReadResult } from "./io";
+import { Reader, Writer, ReadResult, SyncReader, SyncWriter } from "./io";
import { assert } from "./util";
import { TextDecoder } from "./text_encoding";
import { DenoError, ErrorKind } from "./errors";
@@ -32,7 +32,7 @@ function copyBytes(dst: Uint8Array, src: Uint8Array, off = 0): number {
/** A Buffer is a variable-sized buffer of bytes with read() and write()
* methods. Based on https://golang.org/pkg/bytes/#Buffer
*/
-export class Buffer implements Reader, Writer {
+export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
private buf: Uint8Array; // contents are the bytes buf[off : len(buf)]
private off = 0; // read at buf[off], write at buf[buf.byteLength]
@@ -126,11 +126,11 @@ export class Buffer implements Reader, Writer {
this.buf = new Uint8Array(this.buf.buffer, 0, len);
}
- /** read() reads the next len(p) bytes from the buffer or until the buffer
+ /** readSync() reads the next len(p) bytes from the buffer or until the buffer
* is drained. The return value n is the number of bytes read. If the
* buffer has no data to return, eof in the response will be true.
*/
- async read(p: Uint8Array): Promise<ReadResult> {
+ readSync(p: Uint8Array): ReadResult {
if (this.empty()) {
// Buffer is empty, reset to recover space.
this.reset();
@@ -145,11 +145,21 @@ export class Buffer implements Reader, Writer {
return { nread, eof: false };
}
- async write(p: Uint8Array): Promise<number> {
+ async read(p: Uint8Array): Promise<ReadResult> {
+ const rr = this.readSync(p);
+ return Promise.resolve(rr);
+ }
+
+ writeSync(p: Uint8Array): number {
const m = this._grow(p.byteLength);
return copyBytes(this.buf, p, m);
}
+ async write(p: Uint8Array): Promise<number> {
+ const n = this.writeSync(p);
+ return Promise.resolve(n);
+ }
+
/** _grow() grows the buffer to guarantee space for n more bytes.
* It returns the index where bytes should be written.
* If the buffer can't grow it will throw with ErrTooLarge.
@@ -226,6 +236,27 @@ export class Buffer implements Reader, Writer {
}
}
}
+
+ /** Sync version of `readFrom`
+ */
+ readFromSync(r: SyncReader): number {
+ let n = 0;
+ while (true) {
+ try {
+ const i = this._grow(MIN_READ);
+ this._reslice(i);
+ const fub = new Uint8Array(this.buf.buffer, i);
+ const { nread, eof } = r.readSync(fub);
+ this._reslice(i + nread);
+ n += nread;
+ if (eof) {
+ return n;
+ }
+ } catch (e) {
+ return n;
+ }
+ }
+ }
}
/** Read `r` until EOF and return the content as `Uint8Array`.
@@ -235,3 +266,11 @@ export async function readAll(r: Reader): Promise<Uint8Array> {
await buf.readFrom(r);
return buf.bytes();
}
+
+/** Read synchronously `r` until EOF and return the content as `Uint8Array`.
+ */
+export function readAllSync(r: SyncReader): Uint8Array {
+ const buf = new Buffer();
+ buf.readFromSync(r);
+ return buf.bytes();
+}
diff --git a/js/buffer_test.ts b/js/buffer_test.ts
index 90e171330..f07d9d65d 100644
--- a/js/buffer_test.ts
+++ b/js/buffer_test.ts
@@ -5,7 +5,7 @@
// https://github.com/golang/go/blob/master/LICENSE
import { assertEquals, test } from "./test_util.ts";
-const { Buffer, readAll } = Deno;
+const { Buffer, readAll, readAllSync } = Deno;
type Buffer = Deno.Buffer;
// N controls how many iterations of certain checks are performed.
@@ -193,6 +193,23 @@ test(async function bufferReadFrom() {
}
});
+test(async function bufferReadFromSync() {
+ init();
+ const buf = new Buffer();
+ for (let i = 3; i < 30; i += 3) {
+ const s = await fillBytes(
+ buf,
+ "",
+ 5,
+ testBytes.subarray(0, Math.floor(testBytes.byteLength / i))
+ );
+ const b = new Buffer();
+ b.readFromSync(buf);
+ const fub = new Uint8Array(testString.length);
+ await empty(b, s, fub);
+ }
+});
+
test(async function bufferTestGrow() {
const tmp = new Uint8Array(72);
for (let startLen of [0, 100, 1000, 10000, 100000]) {
@@ -226,3 +243,13 @@ test(async function testReadAll() {
assertEquals(testBytes[i], actualBytes[i]);
}
});
+
+test(function testReadAllSync() {
+ init();
+ const reader = new Buffer(testBytes.buffer as ArrayBuffer);
+ const actualBytes = readAllSync(reader);
+ assertEquals(testBytes.byteLength, actualBytes.byteLength);
+ for (let i = 0; i < testBytes.length; ++i) {
+ assertEquals(testBytes[i], actualBytes[i]);
+ }
+});
diff --git a/js/deno.ts b/js/deno.ts
index ed42dc89a..f7505fea4 100644
--- a/js/deno.ts
+++ b/js/deno.ts
@@ -6,12 +6,16 @@ export { chdir, cwd } from "./dir";
export {
File,
open,
+ openSync,
stdin,
stdout,
stderr,
read,
+ readSync,
write,
+ writeSync,
seek,
+ seekSync,
close,
OpenMode
} from "./files";
@@ -21,9 +25,12 @@ export {
ReadResult,
SeekMode,
Reader,
+ SyncReader,
Writer,
+ SyncWriter,
Closer,
Seeker,
+ SyncSeeker,
ReadCloser,
WriteCloser,
ReadSeeker,
@@ -31,7 +38,7 @@ export {
ReadWriteCloser,
ReadWriteSeeker
} from "./io";
-export { Buffer, readAll } from "./buffer";
+export { Buffer, readAll, readAllSync } from "./buffer";
export { mkdirSync, mkdir } from "./mkdir";
export {
makeTempDirSync,
diff --git a/js/files.ts b/js/files.ts
index 9ea378735..9da9fbe0a 100644
--- a/js/files.ts
+++ b/js/files.ts
@@ -1,20 +1,24 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { Reader, Writer, Seeker, Closer, ReadResult, SeekMode } from "./io";
+import {
+ Reader,
+ Writer,
+ Seeker,
+ Closer,
+ ReadResult,
+ SeekMode,
+ SyncReader,
+ SyncWriter,
+ SyncSeeker
+} from "./io";
import * as dispatch from "./dispatch";
import * as msg from "gen/msg_generated";
import { assert } from "./util";
import * as flatbuffers from "./flatbuffers";
-/** Open a file and return an instance of the `File` object.
- *
- * (async () => {
- * const file = await Deno.open("/foo/bar.txt");
- * })();
- */
-export async function open(
+function reqOpen(
filename: string,
- mode: OpenMode = "r"
-): Promise<File> {
+ mode: OpenMode
+): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const filename_ = builder.createString(filename);
const mode_ = builder.createString(mode);
@@ -22,7 +26,10 @@ export async function open(
msg.Open.addFilename(builder, filename_);
msg.Open.addMode(builder, mode_);
const inner = msg.Open.endOpen(builder);
- const baseRes = await dispatch.sendAsync(builder, msg.Any.Open, inner);
+ return [builder, msg.Any.Open, inner];
+}
+
+function resOpen(baseRes: null | msg.Base): File {
assert(baseRes != null);
assert(msg.Any.OpenRes === baseRes!.innerType());
const res = new msg.OpenRes();
@@ -32,16 +39,40 @@ export async function open(
return new File(rid);
}
-/** Read from a file ID into an array buffer.
+/** Open a file and return an instance of the `File` object
+ * synchronously.
*
- * Resolves with the `ReadResult` for the operation.
+ * const file = Deno.openSync("/foo/bar.txt");
*/
-export async function read(rid: number, p: Uint8Array): Promise<ReadResult> {
+export function openSync(filename: string, mode: OpenMode = "r"): File {
+ return resOpen(dispatch.sendSync(...reqOpen(filename, mode)));
+}
+
+/** Open a file and return an instance of the `File` object.
+ *
+ * (async () => {
+ * const file = await Deno.open("/foo/bar.txt");
+ * })();
+ */
+export async function open(
+ filename: string,
+ mode: OpenMode = "r"
+): Promise<File> {
+ return resOpen(await dispatch.sendAsync(...reqOpen(filename, mode)));
+}
+
+function reqRead(
+ rid: number,
+ p: Uint8Array
+): [flatbuffers.Builder, msg.Any, flatbuffers.Offset, Uint8Array] {
const builder = flatbuffers.createBuilder();
msg.Read.startRead(builder);
msg.Read.addRid(builder, rid);
const inner = msg.Read.endRead(builder);
- const baseRes = await dispatch.sendAsync(builder, msg.Any.Read, inner, p);
+ return [builder, msg.Any.Read, inner, p];
+}
+
+function resRead(baseRes: null | msg.Base): ReadResult {
assert(baseRes != null);
assert(msg.Any.ReadRes === baseRes!.innerType());
const res = new msg.ReadRes();
@@ -49,16 +80,47 @@ export async function read(rid: number, p: Uint8Array): Promise<ReadResult> {
return { nread: res.nread(), eof: res.eof() };
}
-/** Write to the file ID the contents of the array buffer.
+/** Read synchronously from a file ID into an array buffer.
+ *
+ * Return `ReadResult` for the operation.
+ *
+ * const file = Deno.openSync("/foo/bar.txt");
+ * const buf = new Uint8Array(100);
+ * const { nread, eof } = Deno.readSync(file.rid, buf);
+ * const text = new TextDecoder.decode(buf);
*
- * Resolves with the number of bytes written.
*/
-export async function write(rid: number, p: Uint8Array): Promise<number> {
+export function readSync(rid: number, p: Uint8Array): ReadResult {
+ return resRead(dispatch.sendSync(...reqRead(rid, p)));
+}
+
+/** Read from a file ID into an array buffer.
+ *
+ * Resolves with the `ReadResult` for the operation.
+ *
+ * (async () => {
+ * const file = await Deno.open("/foo/bar.txt");
+ * const buf = new Uint8Array(100);
+ * const { nread, eof } = await Deno.read(file.rid, buf);
+ * const text = new TextDecoder.decode(buf);
+ * })();
+ */
+export async function read(rid: number, p: Uint8Array): Promise<ReadResult> {
+ return resRead(await dispatch.sendAsync(...reqRead(rid, p)));
+}
+
+function reqWrite(
+ rid: number,
+ p: Uint8Array
+): [flatbuffers.Builder, msg.Any, flatbuffers.Offset, Uint8Array] {
const builder = flatbuffers.createBuilder();
msg.Write.startWrite(builder);
msg.Write.addRid(builder, rid);
const inner = msg.Write.endWrite(builder);
- const baseRes = await dispatch.sendAsync(builder, msg.Any.Write, inner, p);
+ return [builder, msg.Any.Write, inner, p];
+}
+
+function resWrite(baseRes: null | msg.Base): number {
assert(baseRes != null);
assert(msg.Any.WriteRes === baseRes!.innerType());
const res = new msg.WriteRes();
@@ -66,21 +128,71 @@ export async function write(rid: number, p: Uint8Array): Promise<number> {
return res.nbyte();
}
-/** Seek a file ID to the given offset under mode given by `whence`.
+/** Write synchronously to the file ID the contents of the array buffer.
*
+ * Resolves with the number of bytes written.
+ *
+ * const encoder = new TextEncoder();
+ * const data = encoder.encode("Hello world\n");
+ * const file = Deno.openSync("/foo/bar.txt");
+ * Deno.writeSync(file.rid, data);
*/
-export async function seek(
+export function writeSync(rid: number, p: Uint8Array): number {
+ return resWrite(dispatch.sendSync(...reqWrite(rid, p)));
+}
+
+/** Write to the file ID the contents of the array buffer.
+ *
+ * Resolves with the number of bytes written.
+ *
+ * (async () => {
+ * const encoder = new TextEncoder();
+ * const data = encoder.encode("Hello world\n");
+ * const file = await Deno.open("/foo/bar.txt");
+ * await Deno.write(file.rid, data);
+ * })();
+ *
+ */
+export async function write(rid: number, p: Uint8Array): Promise<number> {
+ return resWrite(await dispatch.sendAsync(...reqWrite(rid, p)));
+}
+
+function reqSeek(
rid: number,
offset: number,
whence: SeekMode
-): Promise<void> {
+): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
msg.Seek.startSeek(builder);
msg.Seek.addRid(builder, rid);
msg.Seek.addOffset(builder, offset);
msg.Seek.addWhence(builder, whence);
const inner = msg.Seek.endSeek(builder);
- await dispatch.sendAsync(builder, msg.Any.Seek, inner);
+ return [builder, msg.Any.Seek, inner];
+}
+
+/** Seek a file ID synchronously to the given offset under mode given by `whence`.
+ *
+ * const file = Deno.openSync("/foo/bar.txt");
+ * Deno.seekSync(file.rid, 0, 0);
+ */
+export function seekSync(rid: number, offset: number, whence: SeekMode): void {
+ dispatch.sendSync(...reqSeek(rid, offset, whence));
+}
+
+/** Seek a file ID to the given offset under mode given by `whence`.
+ *
+ * (async () => {
+ * const file = await Deno.open("/foo/bar.txt");
+ * await Deno.seek(file.rid, 0, 0);
+ * })();
+ */
+export async function seek(
+ rid: number,
+ offset: number,
+ whence: SeekMode
+): Promise<void> {
+ await dispatch.sendAsync(...reqSeek(rid, offset, whence));
}
/** Close the file ID. */
@@ -93,21 +205,41 @@ export function close(rid: number): void {
}
/** The Deno abstraction for reading and writing files. */
-export class File implements Reader, Writer, Seeker, Closer {
+export class File
+ implements
+ Reader,
+ SyncReader,
+ Writer,
+ SyncWriter,
+ Seeker,
+ SyncSeeker,
+ Closer {
constructor(readonly rid: number) {}
write(p: Uint8Array): Promise<number> {
return write(this.rid, p);
}
+ writeSync(p: Uint8Array): number {
+ return writeSync(this.rid, p);
+ }
+
read(p: Uint8Array): Promise<ReadResult> {
return read(this.rid, p);
}
+ readSync(p: Uint8Array): ReadResult {
+ return readSync(this.rid, p);
+ }
+
seek(offset: number, whence: SeekMode): Promise<void> {
return seek(this.rid, offset, whence);
}
+ seekSync(offset: number, whence: SeekMode): void {
+ return seekSync(this.rid, offset, whence);
+ }
+
close(): void {
close(this.rid);
}
diff --git a/js/files_test.ts b/js/files_test.ts
index 0decd9f00..f953946bc 100644
--- a/js/files_test.ts
+++ b/js/files_test.ts
@@ -163,6 +163,19 @@ testPerm({ read: true }, async function seekStart() {
assertEquals(decoded, "world!");
});
+testPerm({ read: true }, function seekSyncStart() {
+ const filename = "tests/hello.txt";
+ const file = Deno.openSync(filename);
+ // Deliberately move 1 step forward
+ file.readSync(new Uint8Array(1)); // "H"
+ // Skipping "Hello "
+ file.seekSync(6, Deno.SeekMode.SEEK_START);
+ const buf = new Uint8Array(6);
+ file.readSync(buf);
+ const decoded = new TextDecoder().decode(buf);
+ assertEquals(decoded, "world!");
+});
+
testPerm({ read: true }, async function seekCurrent() {
const filename = "tests/hello.txt";
const file = await Deno.open(filename);
@@ -176,6 +189,19 @@ testPerm({ read: true }, async function seekCurrent() {
assertEquals(decoded, "world!");
});
+testPerm({ read: true }, function seekSyncCurrent() {
+ const filename = "tests/hello.txt";
+ const file = Deno.openSync(filename);
+ // Deliberately move 1 step forward
+ file.readSync(new Uint8Array(1)); // "H"
+ // Skipping "ello "
+ file.seekSync(5, Deno.SeekMode.SEEK_CURRENT);
+ const buf = new Uint8Array(6);
+ file.readSync(buf);
+ const decoded = new TextDecoder().decode(buf);
+ assertEquals(decoded, "world!");
+});
+
testPerm({ read: true }, async function seekEnd() {
const filename = "tests/hello.txt";
const file = await Deno.open(filename);
@@ -186,6 +212,16 @@ testPerm({ read: true }, async function seekEnd() {
assertEquals(decoded, "world!");
});
+testPerm({ read: true }, function seekSyncEnd() {
+ const filename = "tests/hello.txt";
+ const file = Deno.openSync(filename);
+ file.seekSync(-6, Deno.SeekMode.SEEK_END);
+ const buf = new Uint8Array(6);
+ file.readSync(buf);
+ const decoded = new TextDecoder().decode(buf);
+ assertEquals(decoded, "world!");
+});
+
testPerm({ read: true }, async function seekMode() {
const filename = "tests/hello.txt";
const file = await Deno.open(filename);
diff --git a/js/io.ts b/js/io.ts
index 7f56187c1..dd3d12a6d 100644
--- a/js/io.ts
+++ b/js/io.ts
@@ -49,6 +49,10 @@ export interface Reader {
read(p: Uint8Array): Promise<ReadResult>;
}
+export interface SyncReader {
+ readSync(p: Uint8Array): ReadResult;
+}
+
// Writer is the interface that wraps the basic write() method.
// https://golang.org/pkg/io/#Writer
export interface Writer {
@@ -63,6 +67,9 @@ export interface Writer {
write(p: Uint8Array): Promise<number>;
}
+export interface SyncWriter {
+ writeSync(p: Uint8Array): number;
+}
// https://golang.org/pkg/io/#Closer
export interface Closer {
// The behavior of Close after the first call is undefined. Specific
@@ -85,6 +92,10 @@ export interface Seeker {
seek(offset: number, whence: SeekMode): Promise<void>;
}
+export interface SyncSeeker {
+ seekSync(offset: number, whence: SeekMode): void;
+}
+
// https://golang.org/pkg/io/#ReadCloser
export interface ReadCloser extends Reader, Closer {}
diff --git a/js/read_file.ts b/js/read_file.ts
index 3aeedec28..1ca52e276 100644
--- a/js/read_file.ts
+++ b/js/read_file.ts
@@ -1,29 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as msg from "gen/msg_generated";
-import * as flatbuffers from "./flatbuffers";
-import { assert } from "./util";
-import * as dispatch from "./dispatch";
-
-function req(
- filename: string
-): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
- const builder = flatbuffers.createBuilder();
- const filename_ = builder.createString(filename);
- msg.ReadFile.startReadFile(builder);
- msg.ReadFile.addFilename(builder, filename_);
- const inner = msg.ReadFile.endReadFile(builder);
- return [builder, msg.Any.ReadFile, inner];
-}
-
-function res(baseRes: null | msg.Base): Uint8Array {
- assert(baseRes != null);
- assert(msg.Any.ReadFileRes === baseRes!.innerType());
- const inner = new msg.ReadFileRes();
- assert(baseRes!.inner(inner) != null);
- const dataArray = inner.dataArray();
- assert(dataArray != null);
- return new Uint8Array(dataArray!);
-}
+import { open, openSync } from "./files";
+import { readAll, readAllSync } from "./buffer";
/** Read the entire contents of a file synchronously.
*
@@ -32,7 +9,10 @@ function res(baseRes: null | msg.Base): Uint8Array {
* console.log(decoder.decode(data));
*/
export function readFileSync(filename: string): Uint8Array {
- return res(dispatch.sendSync(...req(filename)));
+ const file = openSync(filename);
+ const contents = readAllSync(file);
+ file.close();
+ return contents;
}
/** Read the entire contents of a file.
@@ -42,5 +22,8 @@ export function readFileSync(filename: string): Uint8Array {
* console.log(decoder.decode(data));
*/
export async function readFile(filename: string): Promise<Uint8Array> {
- return res(await dispatch.sendAsync(...req(filename)));
+ const file = await open(filename);
+ const contents = await readAll(file);
+ file.close();
+ return contents;
}
diff --git a/js/write_file.ts b/js/write_file.ts
index 8c5c7ac0a..39372a27e 100644
--- a/js/write_file.ts
+++ b/js/write_file.ts
@@ -1,35 +1,7 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import * as msg from "gen/msg_generated";
-import * as flatbuffers from "./flatbuffers";
-import * as dispatch from "./dispatch";
-
-function req(
- filename: string,
- data: Uint8Array,
- options: WriteFileOptions
-): [flatbuffers.Builder, msg.Any, flatbuffers.Offset, Uint8Array] {
- const builder = flatbuffers.createBuilder();
- const filename_ = builder.createString(filename);
- msg.WriteFile.startWriteFile(builder);
- msg.WriteFile.addFilename(builder, filename_);
- // Perm is not updated by default
- if (options.perm !== undefined && options.perm !== null) {
- msg.WriteFile.addUpdatePerm(builder, true);
- msg.WriteFile.addPerm(builder, options.perm!);
- } else {
- msg.WriteFile.addUpdatePerm(builder, false);
- msg.WriteFile.addPerm(builder, 0o666);
- }
- // Create is turned on by default
- if (options.create !== undefined) {
- msg.WriteFile.addIsCreate(builder, !!options.create);
- } else {
- msg.WriteFile.addIsCreate(builder, true);
- }
- msg.WriteFile.addIsAppend(builder, !!options.append);
- const inner = msg.WriteFile.endWriteFile(builder);
- return [builder, msg.Any.WriteFile, inner, data];
-}
+import { stat, statSync } from "./stat";
+import { open, openSync } from "./files";
+import { chmod, chmodSync } from "./chmod";
/** Options for writing to a file.
* `perm` would change the file's permission if set.
@@ -53,7 +25,23 @@ export function writeFileSync(
data: Uint8Array,
options: WriteFileOptions = {}
): void {
- dispatch.sendSync(...req(filename, data, options));
+ if (options.create !== undefined) {
+ const create = !!options.create;
+ if (!create) {
+ // verify that file exists
+ statSync(filename);
+ }
+ }
+
+ const openMode = !!options.append ? "a" : "w";
+ const file = openSync(filename, openMode);
+
+ if (options.perm !== undefined && options.perm !== null) {
+ chmodSync(filename, options.perm);
+ }
+
+ file.writeSync(data);
+ file.close();
}
/** Write a new file, with given filename and data.
@@ -67,5 +55,21 @@ export async function writeFile(
data: Uint8Array,
options: WriteFileOptions = {}
): Promise<void> {
- await dispatch.sendAsync(...req(filename, data, options));
+ if (options.create !== undefined) {
+ const create = !!options.create;
+ if (!create) {
+ // verify that file exists
+ await stat(filename);
+ }
+ }
+
+ const openMode = !!options.append ? "a" : "w";
+ const file = await open(filename, openMode);
+
+ if (options.perm !== undefined && options.perm !== null) {
+ await chmod(filename, options.perm);
+ }
+
+ await file.write(data);
+ file.close();
}