Fix(node:fs): add buffer parameter in fs.read callback. (#4191)

Close: #4178
This commit is contained in:
Ai Hoshino
2023-08-18 05:27:33 +08:00
committed by GitHub
parent b0e76a965d
commit b2f8ef4dff
3 changed files with 151 additions and 5 deletions

View File

@@ -4,6 +4,7 @@ var WriteStream;
const EventEmitter = require("node:events");
const promises = require("node:fs/promises");
const Stream = require("node:stream");
const { isArrayBufferView } = require("node:util/types");
var fs = Bun.fs();
class FSWatcher extends EventEmitter {
@@ -126,8 +127,37 @@ var access = function access(...args) {
open = function open(...args) {
callbackify(fs.openSync, args);
},
read = function read(...args) {
callbackify(fs.readSync, args);
read = function read(fd, buffer, offsetOrOptions, length, position, callback) {
let offset = offsetOrOptions;
let params = null;
if (arguments.length <= 4) {
if (arguments.length === 4) {
// fs.read(fd, buffer, options, callback)
callback = length;
params = offsetOrOptions;
} else if (arguments.length === 3) {
// fs.read(fd, bufferOrParams, callback)
if (!isArrayBufferView(buffer)) {
// fs.read(fd, params, callback)
params = buffer;
({ buffer = Buffer.alloc(16384) } = params ?? {});
}
callback = offsetOrOptions;
} else {
// fs.read(fd, callback)
callback = buffer;
buffer = Buffer.alloc(16384);
}
({ offset = 0, length = buffer?.byteLength - offset, position = null } = params ?? {});
}
queueMicrotask(() => {
try {
var bytesRead = fs.readSync(fd, buffer, offset, length, position);
} catch (e) {
callback(e);
}
callback(null, bytesRead, buffer);
});
},
write = function write(...args) {
callbackify(fs.writeSync, args);

File diff suppressed because one or more lines are too long

View File

@@ -1692,3 +1692,119 @@ it("createReadStream on a large file emits readable event correctly", () => {
});
});
});
describe("fs.read", () => {
it("should work with (fd, callback)", done => {
const path = `${tmpdir()}/bun-fs-read-1-${Date.now()}.txt`;
fs.writeFileSync(path, "bun");
const fd = fs.openSync(path, "r");
fs.read(fd, (err, bytesRead, buffer) => {
try {
expect(err).toBeNull();
expect(bytesRead).toBe(3);
expect(buffer).toStrictEqual(Buffer.concat([Buffer.from("bun"), Buffer.alloc(16381)]));
} catch (e) {
return done(e);
} finally {
unlinkSync(path);
}
done();
});
});
it("should work with (fd, options, callback)", done => {
const path = `${tmpdir()}/bun-fs-read-2-${Date.now()}.txt`;
fs.writeFileSync(path, "bun");
const fd = fs.openSync(path, "r");
const buffer = Buffer.alloc(16);
fs.read(fd, { buffer: buffer }, (err, bytesRead, buffer) => {
try {
expect(err).toBeNull();
expect(bytesRead).toBe(3);
expect(buffer.slice(0, bytesRead).toString()).toStrictEqual("bun");
} catch (e) {
return done(e);
} finally {
unlinkSync(path);
}
done();
});
});
it("should work with (fd, buffer, offset, length, position, callback)", done => {
const path = `${tmpdir()}/bun-fs-read-3-${Date.now()}.txt`;
fs.writeFileSync(path, "bun");
const fd = fs.openSync(path, "r");
const buffer = Buffer.alloc(16);
fs.read(fd, buffer, 0, buffer.length, 0, (err, bytesRead, buffer) => {
try {
expect(err).toBeNull();
expect(bytesRead).toBe(3);
expect(buffer.slice(0, bytesRead).toString()).toStrictEqual("bun");
} catch (e) {
return done(e);
} finally {
unlinkSync(path);
}
done();
});
});
it("should work with offset", done => {
const path = `${tmpdir()}/bun-fs-read-4-${Date.now()}.txt`;
fs.writeFileSync(path, "bun");
const fd = fs.openSync(path, "r");
const buffer = Buffer.alloc(16);
fs.read(fd, buffer, 1, buffer.length - 1, 0, (err, bytesRead, buffer) => {
try {
expect(err).toBeNull();
expect(bytesRead).toBe(3);
expect(buffer.slice(1, bytesRead + 1).toString()).toStrictEqual("bun");
} catch (e) {
return done(e);
} finally {
unlinkSync(path);
}
done();
});
});
it("should work with position", done => {
const path = `${tmpdir()}/bun-fs-read-5-${Date.now()}.txt`;
fs.writeFileSync(path, "bun");
const fd = fs.openSync(path, "r");
const buffer = Buffer.alloc(16);
fs.read(fd, buffer, 0, buffer.length, 1, (err, bytesRead, buffer) => {
try {
expect(err).toBeNull();
expect(bytesRead).toBe(2);
expect(buffer.slice(0, bytesRead).toString()).toStrictEqual("un");
} catch (e) {
return done(e);
} finally {
unlinkSync(path);
}
done();
});
});
it("should work with both position and offset", done => {
const path = `${tmpdir()}/bun-fs-read-6-${Date.now()}.txt`;
fs.writeFileSync(path, "bun");
const fd = fs.openSync(path, "r");
const buffer = Buffer.alloc(16);
fs.read(fd, buffer, 1, buffer.length - 1, 1, (err, bytesRead, buffer) => {
try {
expect(err).toBeNull();
expect(bytesRead).toBe(2);
expect(buffer.slice(1, bytesRead + 1).toString()).toStrictEqual("un");
} catch (e) {
return done(e);
} finally {
unlinkSync(path);
}
done();
});
});
});