Skip to content

Commit 2260bb9

Browse files
SirR4Ttargos
authored andcommitted
fs: update read to work with any TypedArray/DataView
PR-URL: #22150 Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 5321c31 commit 2260bb9

File tree

5 files changed

+72
-32
lines changed

5 files changed

+72
-32
lines changed

doc/api/fs.md

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,10 @@ this API: [`fs.open()`][].
23452345
<!-- YAML
23462346
added: v0.0.2
23472347
changes:
2348+
- version: REPLACEME
2349+
pr-url: https://github.com/nodejs/node/pull/22150
2350+
description: The `buffer` parameter can now be any `TypedArray`, or a
2351+
`DataView`.
23482352
- version: v7.4.0
23492353
pr-url: https://github.com/nodejs/node/pull/10382
23502354
description: The `buffer` parameter can now be a `Uint8Array`.
@@ -2354,7 +2358,7 @@ changes:
23542358
-->
23552359

23562360
* `fd` {integer}
2357-
* `buffer` {Buffer|Uint8Array}
2361+
* `buffer` {Buffer|TypedArray|DataView}
23582362
* `offset` {integer}
23592363
* `length` {integer}
23602364
* `position` {integer}
@@ -2624,13 +2628,17 @@ the link path returned will be passed as a `Buffer` object.
26242628
<!-- YAML
26252629
added: v0.1.21
26262630
changes:
2631+
- version: REPLACEME
2632+
pr-url: https://github.com/nodejs/node/pull/22150
2633+
description: The `buffer` parameter can now be any `TypedArray` or a
2634+
`DataView`.
26272635
- version: v6.0.0
26282636
pr-url: https://github.com/nodejs/node/pull/4518
26292637
description: The `length` parameter can now be `0`.
26302638
-->
26312639

26322640
* `fd` {integer}
2633-
* `buffer` {Buffer|Uint8Array}
2641+
* `buffer` {Buffer|TypedArray|DataView}
26342642
* `offset` {integer}
26352643
* `length` {integer}
26362644
* `position` {integer}
@@ -3354,6 +3362,10 @@ This happens when:
33543362
<!-- YAML
33553363
added: v0.0.2
33563364
changes:
3365+
- version: REPLACEME
3366+
pr-url: https://github.com/nodejs/node/pull/22150
3367+
description: The `buffer` parameter can now be any `TypedArray` or a
3368+
`DataView`
33573369
- version: v10.0.0
33583370
pr-url: https://github.com/nodejs/node/pull/12562
33593371
description: The `callback` parameter is no longer optional. Not passing
@@ -3371,14 +3383,14 @@ changes:
33713383
-->
33723384

33733385
* `fd` {integer}
3374-
* `buffer` {Buffer|Uint8Array}
3386+
* `buffer` {Buffer|TypedArray|DataView}
33753387
* `offset` {integer}
33763388
* `length` {integer}
33773389
* `position` {integer}
33783390
* `callback` {Function}
33793391
* `err` {Error}
33803392
* `bytesWritten` {integer}
3381-
* `buffer` {Buffer|Uint8Array}
3393+
* `buffer` {Buffer|TypedArray|DataView}
33823394

33833395
Write `buffer` to the file specified by `fd`.
33843396

@@ -3453,6 +3465,10 @@ the end of the file.
34533465
<!-- YAML
34543466
added: v0.1.29
34553467
changes:
3468+
- version: REPLACEME
3469+
pr-url: https://github.com/nodejs/node/pull/22150
3470+
description: The `data` parameter can now be any `TypedArray` or a
3471+
`DataView`.
34563472
- version: v10.0.0
34573473
pr-url: https://github.com/nodejs/node/pull/12562
34583474
description: The `callback` parameter is no longer optional. Not passing
@@ -3470,7 +3486,7 @@ changes:
34703486
-->
34713487

34723488
* `file` {string|Buffer|URL|integer} filename or file descriptor
3473-
* `data` {string|Buffer|Uint8Array}
3489+
* `data` {string|Buffer|TypedArray|DataView}
34743490
* `options` {Object|string}
34753491
* `encoding` {string|null} **Default:** `'utf8'`
34763492
* `mode` {integer} **Default:** `0o666`
@@ -3486,7 +3502,8 @@ The `encoding` option is ignored if `data` is a buffer.
34863502
Example:
34873503

34883504
```js
3489-
fs.writeFile('message.txt', 'Hello Node.js', (err) => {
3505+
const data = new Uint8Array(Buffer.from('Hello Node.js'));
3506+
fs.writeFile('message.txt', data, (err) => {
34903507
if (err) throw err;
34913508
console.log('The file has been saved!');
34923509
});
@@ -3511,6 +3528,10 @@ automatically.
35113528
<!-- YAML
35123529
added: v0.1.29
35133530
changes:
3531+
- version: REPLACEME
3532+
pr-url: https://github.com/nodejs/node/pull/22150
3533+
description: The `data` parameter can now be any `TypedArray` or a
3534+
`DataView`.
35143535
- version: v7.4.0
35153536
pr-url: https://github.com/nodejs/node/pull/10382
35163537
description: The `data` parameter can now be a `Uint8Array`.
@@ -3520,7 +3541,7 @@ changes:
35203541
-->
35213542

35223543
* `file` {string|Buffer|URL|integer} filename or file descriptor
3523-
* `data` {string|Buffer|Uint8Array}
3544+
* `data` {string|Buffer|TypedArray|DataView}
35243545
* `options` {Object|string}
35253546
* `encoding` {string|null} **Default:** `'utf8'`
35263547
* `mode` {integer} **Default:** `0o666`
@@ -3535,6 +3556,10 @@ this API: [`fs.writeFile()`][].
35353556
<!-- YAML
35363557
added: v0.1.21
35373558
changes:
3559+
- version: REPLACEME
3560+
pr-url: https://github.com/nodejs/node/pull/22150
3561+
description: The `buffer` parameter can now be any `TypedArray` or a
3562+
`DataView`.
35383563
- version: v7.4.0
35393564
pr-url: https://github.com/nodejs/node/pull/10382
35403565
description: The `buffer` parameter can now be a `Uint8Array`.
@@ -3544,7 +3569,7 @@ changes:
35443569
-->
35453570

35463571
* `fd` {integer}
3547-
* `buffer` {Buffer|Uint8Array}
3572+
* `buffer` {Buffer|TypedArray|DataView}
35483573
* `offset` {integer}
35493574
* `length` {integer}
35503575
* `position` {integer}

lib/fs.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const {
4141

4242
const { _extend } = require('util');
4343
const pathModule = require('path');
44-
const { isUint8Array } = require('internal/util/types');
44+
const { isArrayBufferView } = require('internal/util/types');
4545
const binding = process.binding('fs');
4646
const { Buffer, kMaxLength } = require('buffer');
4747
const errors = require('internal/errors');
@@ -450,7 +450,7 @@ function read(fd, buffer, offset, length, position, callback) {
450450
});
451451
}
452452

453-
validateOffsetLengthRead(offset, length, buffer.length);
453+
validateOffsetLengthRead(offset, length, buffer.byteLength);
454454

455455
if (!Number.isSafeInteger(position))
456456
position = -1;
@@ -480,7 +480,7 @@ function readSync(fd, buffer, offset, length, position) {
480480
return 0;
481481
}
482482

483-
validateOffsetLengthRead(offset, length, buffer.length);
483+
validateOffsetLengthRead(offset, length, buffer.byteLength);
484484

485485
if (!Number.isSafeInteger(position))
486486
position = -1;
@@ -507,7 +507,7 @@ function write(fd, buffer, offset, length, position, callback) {
507507
const req = new FSReqWrap();
508508
req.oncomplete = wrapper;
509509

510-
if (isUint8Array(buffer)) {
510+
if (isArrayBufferView(buffer)) {
511511
callback = maybeCallback(callback || position || length || offset);
512512
if (typeof offset !== 'number')
513513
offset = 0;
@@ -545,13 +545,13 @@ function writeSync(fd, buffer, offset, length, position) {
545545
validateUint32(fd, 'fd');
546546
const ctx = {};
547547
let result;
548-
if (isUint8Array(buffer)) {
548+
if (isArrayBufferView(buffer)) {
549549
if (position === undefined)
550550
position = null;
551551
if (typeof offset !== 'number')
552552
offset = 0;
553553
if (typeof length !== 'number')
554-
length = buffer.length - offset;
554+
length = buffer.byteLength - offset;
555555
validateOffsetLengthWrite(offset, length, buffer.byteLength);
556556
result = binding.writeBuffer(fd, buffer, offset, length, position,
557557
undefined, ctx);
@@ -1152,11 +1152,11 @@ function writeFile(path, data, options, callback) {
11521152
});
11531153

11541154
function writeFd(fd, isUserFd) {
1155-
const buffer = isUint8Array(data) ?
1155+
const buffer = isArrayBufferView(data) ?
11561156
data : Buffer.from('' + data, options.encoding || 'utf8');
11571157
const position = /a/.test(flag) ? null : 0;
11581158

1159-
writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback);
1159+
writeAll(fd, isUserFd, buffer, 0, buffer.byteLength, position, callback);
11601160
}
11611161
}
11621162

@@ -1167,11 +1167,11 @@ function writeFileSync(path, data, options) {
11671167
const isUserFd = isFd(path); // file descriptor ownership
11681168
const fd = isUserFd ? path : fs.openSync(path, flag, options.mode);
11691169

1170-
if (!isUint8Array(data)) {
1170+
if (!isArrayBufferView(data)) {
11711171
data = Buffer.from('' + data, options.encoding || 'utf8');
11721172
}
11731173
let offset = 0;
1174-
let length = data.length;
1174+
let length = data.byteLength;
11751175
let position = /a/.test(flag) ? null : 0;
11761176
try {
11771177
while (length > 0) {

lib/internal/fs/utils.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const {
99
ERR_INVALID_OPT_VALUE_ENCODING,
1010
ERR_OUT_OF_RANGE
1111
} = require('internal/errors').codes;
12-
const { isUint8Array } = require('internal/util/types');
12+
const { isUint8Array, isArrayBufferView } = require('internal/util/types');
1313
const pathModule = require('path');
1414
const util = require('util');
1515
const kType = Symbol('type');
@@ -394,9 +394,10 @@ function toUnixTimestamp(time, name = 'time') {
394394
}
395395

396396
function validateBuffer(buffer) {
397-
if (!isUint8Array(buffer)) {
397+
if (!isArrayBufferView(buffer)) {
398398
const err = new ERR_INVALID_ARG_TYPE('buffer',
399-
['Buffer', 'Uint8Array'], buffer);
399+
['Buffer', 'TypedArray', 'DataView'],
400+
buffer);
400401
Error.captureStackTrace(err, validateBuffer);
401402
throw err;
402403
}

test/parallel/test-fs-read-type.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ assert.throws(
1515
{
1616
code: 'ERR_INVALID_ARG_TYPE',
1717
name: 'TypeError [ERR_INVALID_ARG_TYPE]',
18-
message: 'The "buffer" argument must be one of type Buffer or Uint8Array.' +
19-
' Received type number'
18+
message: 'The "buffer" argument must be one of type Buffer, TypedArray, ' +
19+
'or DataView. Received type number'
2020
}
2121
);
2222

@@ -70,8 +70,8 @@ assert.throws(
7070
{
7171
code: 'ERR_INVALID_ARG_TYPE',
7272
name: 'TypeError [ERR_INVALID_ARG_TYPE]',
73-
message: 'The "buffer" argument must be one of type Buffer or Uint8Array.' +
74-
' Received type number'
73+
message: 'The "buffer" argument must be one of type Buffer, TypedArray, ' +
74+
'or DataView. Received type number'
7575
}
7676
);
7777

test/parallel/test-fs-write-file-uint8array.js renamed to test/parallel/test-fs-write-file-typedarrays.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,27 @@ const s = '南越国是前203年至前111年存在于岭南地区的一个国家
1717
'历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' +
1818
'它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n';
1919

20-
const input = Uint8Array.from(Buffer.from(s, 'utf8'));
20+
// The length of the buffer should be a multiple of 8
21+
// as required by common.getArrayBufferViews()
22+
const inputBuffer = Buffer.from(s.repeat(8), 'utf8');
2123

22-
fs.writeFileSync(filename, input);
23-
assert.strictEqual(fs.readFileSync(filename, 'utf8'), s);
24+
for (const expectView of common.getArrayBufferViews(inputBuffer)) {
25+
console.log('Sync test for ', expectView[Symbol.toStringTag]);
26+
fs.writeFileSync(filename, expectView);
27+
assert.strictEqual(
28+
fs.readFileSync(filename, 'utf8'),
29+
inputBuffer.toString('utf8')
30+
);
31+
}
2432

25-
fs.writeFile(filename, input, common.mustCall((e) => {
26-
assert.ifError(e);
33+
for (const expectView of common.getArrayBufferViews(inputBuffer)) {
34+
console.log('Async test for ', expectView[Symbol.toStringTag]);
35+
fs.writeFile(filename, expectView, common.mustCall((e) => {
36+
assert.ifError(e);
2737

28-
assert.strictEqual(fs.readFileSync(filename, 'utf8'), s);
29-
}));
38+
fs.readFile(filename, 'utf8', common.mustCall((err, data) => {
39+
assert.ifError(err);
40+
assert.strictEqual(data, inputBuffer.toString('utf8'));
41+
}));
42+
}));
43+
}

0 commit comments

Comments
 (0)