From 1a8631d0621dd212a325f04510ba9091388ce9e7 Mon Sep 17 00:00:00 2001 From: PolarETech <52513329+PolarETech@users.noreply.github.com> Date: Tue, 20 Sep 2022 04:59:02 +0900 Subject: [PATCH] fix(node/fs): position option of fs.read and fs.readSync works the same as Node (#2669) --- node/_fs/_fs_read.ts | 24 +++++++++--- node/_fs/_fs_read_test.ts | 81 +++++++++++++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 21 deletions(-) diff --git a/node/_fs/_fs_read.ts b/node/_fs/_fs_read.ts index f5959923c352..9ac20be7cfa5 100644 --- a/node/_fs/_fs_read.ts +++ b/node/_fs/_fs_read.ts @@ -98,12 +98,18 @@ export function read( let err: Error | null = null, numberOfBytesRead: number | null = null; - if (position) { - Deno.seekSync(fd, position, Deno.SeekMode.Current); - } - try { + let currentPosition = 0; + if (typeof position === "number" && position >= 0) { + currentPosition = Deno.seekSync(fd, 0, Deno.SeekMode.Current); + Deno.seekSync(fd, position, Deno.SeekMode.Start); + } + numberOfBytesRead = Deno.readSync(fd, buffer); + + if (typeof position === "number" && position >= 0) { + Deno.seekSync(fd, currentPosition, Deno.SeekMode.Start); + } } catch (error) { err = error instanceof Error ? error : new Error("[non-error thrown]"); } @@ -168,11 +174,17 @@ export function readSync( }`, ); - if (position) { - Deno.seekSync(fd, position, Deno.SeekMode.Current); + let currentPosition = 0; + if (typeof position === "number" && position >= 0) { + currentPosition = Deno.seekSync(fd, 0, Deno.SeekMode.Current); + Deno.seekSync(fd, position, Deno.SeekMode.Start); } const numberOfBytesRead = Deno.readSync(fd, buffer); + if (typeof position === "number" && position >= 0) { + Deno.seekSync(fd, currentPosition, Deno.SeekMode.Start); + } + return numberOfBytesRead ?? 0; } diff --git a/node/_fs/_fs_read_test.ts b/node/_fs/_fs_read_test.ts index a2c8a461d09f..7eff9a7c955d 100644 --- a/node/_fs/_fs_read_test.ts +++ b/node/_fs/_fs_read_test.ts @@ -87,25 +87,43 @@ Deno.test({ }); Deno.test({ - name: "[std/node/fs] Specifies where to begin reading from in the file", + name: + "[std/node/fs] position option of fs.read() specifies where to begin reading from in the file", async fn() { const moduleDir = path.dirname(path.fromFileUrl(import.meta.url)); const testData = path.resolve(moduleDir, "testdata", "hello.txt"); - const buf = Buffer.alloc(11); - await readTest( - testData, - buf, - buf.byteOffset, - buf.byteLength, - 6, - (_fd, bytesRead, data) => { - assertStrictEquals(bytesRead, 5); - assertEquals( - data, - Buffer.from([119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0]), + const fd = openSync(testData); + const buf = Buffer.alloc(5); + const positions = [6, 0, -1, null]; + const expected = [ + [119, 111, 114, 108, 100], + [104, 101, 108, 108, 111], + [104, 101, 108, 108, 111], + [32, 119, 111, 114, 108], + ]; + for (const [i, position] of positions.entries()) { + await new Promise((resolve) => { + read( + fd, + { + buffer: buf, + offset: buf.byteOffset, + length: buf.byteLength, + position, + }, + (err, bytesRead, data) => { + assertEquals(err, null); + assertStrictEquals(bytesRead, 5); + assertEquals( + data, + Buffer.from(expected[i]), + ); + return resolve(true); + }, ); - }, - ); + }); + } + closeSync(fd); }, }); @@ -184,6 +202,39 @@ Deno.test({ }, }); +Deno.test({ + name: + "[std/node/fs] position option of fs.readSync() specifies where to begin reading from in the file", + fn() { + const moduleDir = path.dirname(path.fromFileUrl(import.meta.url)); + const testData = path.resolve(moduleDir, "testdata", "hello.txt"); + const fd = openSync(testData); + const buf = Buffer.alloc(5); + const positions = [6, 0, -1, null]; + const expected = [ + [119, 111, 114, 108, 100], + [104, 101, 108, 108, 111], + [104, 101, 108, 108, 111], + [32, 119, 111, 114, 108], + ]; + for (const [i, position] of positions.entries()) { + const bytesRead = readSync( + fd, + buf, + buf.byteOffset, + buf.byteLength, + position, + ); + assertStrictEquals(bytesRead, 5); + assertEquals( + buf, + Buffer.from(expected[i]), + ); + } + closeSync(fd); + }, +}); + Deno.test({ name: "[std/node/fs] Read fs.readSync(fd, buffer[, options]) signature", fn() {