Skip to content

Commit

Permalink
Implemented seek and seekSync
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderOMara committed Nov 8, 2024
1 parent f8c9725 commit 5b1b629
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 17 deletions.
10 changes: 6 additions & 4 deletions packages/shim-deno/src/deno/stable/classes/FsFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { read } from "../functions/read.js";
import { readSync } from "../functions/readSync.js";
import { write } from "../functions/write.js";
import { writeSync } from "../functions/writeSync.js";
import { seek } from "../functions/seek.js";
import { seekSync } from "../functions/seekSync.js";

(Symbol as any).dispose ??= Symbol("Symbol.dispose");
(Symbol as any).asyncDispose ??= Symbol("Symbol.asyncDispose");
Expand Down Expand Up @@ -51,12 +53,12 @@ export class FsFile implements Deno.FsFile {
return readSync(this.rid, p);
}

seek(_offset: number, _whence: Deno.SeekMode): Promise<number> {
throw new Error("Method not implemented.");
async seek(offset: number, whence: Deno.SeekMode): Promise<number> {
return await seek(this.rid, offset, whence);
}

seekSync(_offset: number, _whence: Deno.SeekMode): number {
throw new Error("Method not implemented.");
seekSync(offset: number, whence: Deno.SeekMode): number {
return seekSync(this.rid, offset, whence);
}

async stat(): Promise<Deno.FileInfo> {
Expand Down
7 changes: 6 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/close.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

import * as fs from "fs";

export const close: typeof Deno.close = fs.closeSync;
import { positions } from "./seekSync.js";

export const close: typeof Deno.close = function close(fd) {
fs.closeSync(fd);
positions.delete(fd);
};
2 changes: 2 additions & 0 deletions packages/shim-deno/src/deno/stable/functions/open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { open as _open } from "fs";
import { promisify } from "util";

import { File } from "../classes/FsFile.js";
import { positions } from "../functions/seekSync.js";
import { getFsFlag } from "../../internal/fs_flags.js";
import mapError from "../../internal/errorMap.js";

Expand All @@ -25,6 +26,7 @@ export const open: typeof Deno.open = async function open(
});
try {
const fd = await nodeOpen(path, flagMode, mode);
positions.set(fd, 0);
return new File(fd);
} catch (err) {
throw mapError(err);
Expand Down
2 changes: 2 additions & 0 deletions packages/shim-deno/src/deno/stable/functions/openSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { openSync as nodeOpenSync } from "fs";

import { File } from "../classes/FsFile.js";
import { positions } from "../functions/seekSync.js";
import { getFsFlag } from "../../internal/fs_flags.js";
import mapError from "../../internal/errorMap.js";

Expand All @@ -22,6 +23,7 @@ export const openSync: typeof Deno.openSync = function openSync(
});
try {
const fd = nodeOpenSync(path, flagMode, mode);
positions.set(fd, 0);
return new File(fd);
} catch (err) {
throw mapError(err);
Expand Down
8 changes: 7 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import { promisify } from "util";
import { read as nodeRead } from "fs";

import { positions } from "./seekSync.js";

const _read = promisify(nodeRead);

export const read: typeof Deno.read = async function read(rid, buffer) {
Expand All @@ -13,7 +15,11 @@ export const read: typeof Deno.read = async function read(rid, buffer) {
return 0;
}

const { bytesRead } = await _read(rid, buffer, 0, buffer.length, null);
const position = positions.get(rid) ?? null;
const { bytesRead } = await _read(rid, buffer, 0, buffer.length, position);
if (position !== null) {
positions.set(rid, position + bytesRead);
}
// node returns 0 on EOF, Deno expects null
return bytesRead === 0 ? null : bytesRead;
};
8 changes: 7 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/readSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

import * as fs from "fs";

import { positions } from "./seekSync.js";

export const readSync: typeof Deno.readSync = (fd, buffer) => {
const bytesRead = fs.readSync(fd, buffer);
const position = positions.get(fd) ?? null;
const bytesRead = fs.readSync(fd, buffer, { position });
if (position !== null) {
positions.set(fd, position + bytesRead);
}
// node returns 0 on EOF, Deno expects null
return bytesRead === 0 ? null : bytesRead;
};
30 changes: 30 additions & 0 deletions packages/shim-deno/src/deno/stable/functions/seek.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
///<reference path="../lib.deno.d.ts" />

import { fstat } from "fs";
import { promisify } from "util";

import { positions } from "./seekSync.js";

const nodeFstat = promisify(fstat);

export const seek: typeof Deno.seek = async function (fd, offset, whence) {
let p = positions.get(fd);
if (p == null) {
throw new Error("Bad file descriptor");
}
switch (whence) {
case Deno.SeekMode.Start:
p = Number(offset);
break;
case Deno.SeekMode.Current:
p += Number(offset);
break;
case Deno.SeekMode.End:
p = (await nodeFstat(fd)).size + Number(offset);
break;
default:
throw new TypeError(`Invalid seek mode: ${whence}`);
}
positions.set(fd, p!);
return p!;
};
27 changes: 27 additions & 0 deletions packages/shim-deno/src/deno/stable/functions/seekSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
///<reference path="../lib.deno.d.ts" />

import { fstatSync } from "fs";

export const positions = new Map<number, number>();

export const seekSync: typeof Deno.seekSync = function (fd, offset, whence) {
let p = positions.get(fd);
if (p == null) {
throw new Error("Bad file descriptor");
}
switch (whence) {
case Deno.SeekMode.Start:
p = Number(offset);
break;
case Deno.SeekMode.Current:
p += Number(offset);
break;
case Deno.SeekMode.End:
p = fstatSync(fd).size + Number(offset);
break;
default:
throw new TypeError(`Invalid seek mode: ${whence}`);
}
positions.set(fd, p!);
return p!;
};
8 changes: 7 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
import * as fs from "fs";
import { promisify } from "util";

import { positions } from "./seekSync.js";

const nodeWrite = promisify(fs.write);

export const write: typeof Deno.write = async (fd, data) => {
const { bytesWritten } = await nodeWrite(fd, data);
const position = positions.get(fd) ?? null;
const { bytesWritten } = await nodeWrite(fd, data, { position });
if (position !== null) {
positions.set(fd, position + bytesWritten);
}
return bytesWritten;
};
11 changes: 10 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/writeSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,13 @@

import * as fs from "fs";

export const writeSync: typeof Deno.writeSync = fs.writeSync;
import { positions } from "./seekSync.js";

export const writeSync: typeof Deno.writeSync = (fd, data) => {
const position = positions.get(fd) ?? null;
const bytesWritten = fs.writeSync(fd, data, { position });
if (position !== null) {
positions.set(fd, position + bytesWritten);
}
return bytesWritten;
};
8 changes: 0 additions & 8 deletions packages/shim-deno/tools/run_tests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,6 @@ const testsToSkip = new Set([
"openNotFound", // includes full path in node.js
"openModeWriteRead", // not implemented
"readFileIsDirectoryErrorCode", // todo(https://github.com/denoland/deno/issues/18629): re-enable
"seekStart", // not implemented
"seekSyncStart", // not implemented
"seekCurrent", // not implemented
"seekStartBigInt", // not implemented
"seekSyncCurrent", // not implemented
"seekEnd", // not implemented
"seekSyncEnd", // not implemented
"seekMode", // not implemented

// mkdir_test
"mkdirMode", // depends on Deno.umask
Expand Down

0 comments on commit 5b1b629

Please sign in to comment.