summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2019-08-17 14:56:13 -0400
committercjihrig <cjihrig@gmail.com>2019-08-19 15:34:25 -0400
commit3273d0e9514da750405cc2e3662d72dcbb489380 (patch)
treea4b120f260dfc643a99dbfc6fa78b20901cb4ddd
parent9f9a201cc67d09c7c61169f9e274a76afd4159fe (diff)
downloadandroid-node-v8-3273d0e9514da750405cc2e3662d72dcbb489380.tar.gz
android-node-v8-3273d0e9514da750405cc2e3662d72dcbb489380.tar.bz2
android-node-v8-3273d0e9514da750405cc2e3662d72dcbb489380.zip
fs: add writev() promises version
https://github.com/nodejs/node/pull/25925 added fs.writev() and fs.writevSync(), but did not include a Promises based equivalent. This commit adds the missing method. Refs: https://github.com/nodejs/node/pull/25925 PR-URL: https://github.com/nodejs/node/pull/29186 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
-rw-r--r--doc/api/fs.md26
-rw-r--r--lib/internal/fs/promises.js17
-rw-r--r--lib/internal/fs/utils.js14
-rw-r--r--test/parallel/test-fs-writev-promises.js51
4 files changed, 108 insertions, 0 deletions
diff --git a/doc/api/fs.md b/doc/api/fs.md
index d71f8afd82..58b17c3b21 100644
--- a/doc/api/fs.md
+++ b/doc/api/fs.md
@@ -4274,6 +4274,32 @@ If one or more `filehandle.write()` calls are made on a file handle and then a
current position till the end of the file. It doesn't always write from the
beginning of the file.
+#### filehandle.writev(buffers[, position])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `buffers` {ArrayBufferView[]}
+* `position` {integer}
+* Returns: {Promise}
+
+Write an array of `ArrayBufferView`s to the file.
+
+The `Promise` is resolved with an object containing a `bytesWritten` property
+identifying the number of bytes written, and a `buffers` property containing
+a reference to the `buffers` input.
+
+`position` is the offset from the beginning of the file where this data
+should be written. If `typeof position !== 'number'`, the data will be written
+at the current position.
+
+It is unsafe to call `writev()` multiple times on the same file without waiting
+for the previous operation to complete.
+
+On Linux, positional writes don't work when the file is opened in append mode.
+The kernel ignores the position argument and always appends the data to
+the end of the file.
+
### fsPromises.access(path[, mode])
<!-- YAML
added: v10.0.0
diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js
index e796520b26..7e6fae9273 100644
--- a/lib/internal/fs/promises.js
+++ b/lib/internal/fs/promises.js
@@ -29,6 +29,7 @@ const {
stringToFlags,
stringToSymlinkType,
toUnixTimestamp,
+ validateBufferArray,
validateOffsetLengthRead,
validateOffsetLengthWrite,
warnOnNonPortableTemplate
@@ -104,6 +105,10 @@ class FileHandle {
return write(this, buffer, offset, length, position);
}
+ writev(buffers, position) {
+ return writev(this, buffers, position);
+ }
+
writeFile(data, options) {
return writeFile(this, data, options);
}
@@ -263,6 +268,18 @@ async function write(handle, buffer, offset, length, position) {
return { bytesWritten, buffer };
}
+async function writev(handle, buffers, position) {
+ validateFileHandle(handle);
+ validateBufferArray(buffers);
+
+ if (typeof position !== 'number')
+ position = null;
+
+ const bytesWritten = (await binding.writeBuffers(handle.fd, buffers, position,
+ kUsePromises)) || 0;
+ return { bytesWritten, buffers };
+}
+
async function rename(oldPath, newPath) {
oldPath = getValidatedPath(oldPath, 'oldPath');
newPath = getValidatedPath(newPath, 'newPath');
diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js
index 2924f7582e..600d118db3 100644
--- a/lib/internal/fs/utils.js
+++ b/lib/internal/fs/utils.js
@@ -15,6 +15,7 @@ const {
hideStackFrames
} = require('internal/errors');
const {
+ isArrayBufferView,
isUint8Array,
isDate,
isBigUint64Array
@@ -500,6 +501,18 @@ const getValidatedPath = hideStackFrames((fileURLOrPath, propName = 'path') => {
return path;
});
+const validateBufferArray = hideStackFrames((buffers, propName = 'buffers') => {
+ if (!Array.isArray(buffers))
+ throw new ERR_INVALID_ARG_TYPE(propName, 'ArrayBufferView[]', buffers);
+
+ for (let i = 0; i < buffers.length; i++) {
+ if (!isArrayBufferView(buffers[i]))
+ throw new ERR_INVALID_ARG_TYPE(propName, 'ArrayBufferView[]', buffers);
+ }
+
+ return buffers;
+});
+
let nonPortableTemplateWarn = true;
function warnOnNonPortableTemplate(template) {
@@ -528,6 +541,7 @@ module.exports = {
stringToSymlinkType,
Stats,
toUnixTimestamp,
+ validateBufferArray,
validateOffsetLengthRead,
validateOffsetLengthWrite,
validatePath,
diff --git a/test/parallel/test-fs-writev-promises.js b/test/parallel/test-fs-writev-promises.js
new file mode 100644
index 0000000000..ea349796cc
--- /dev/null
+++ b/test/parallel/test-fs-writev-promises.js
@@ -0,0 +1,51 @@
+'use strict';
+
+require('../common');
+const assert = require('assert');
+const path = require('path');
+const fs = require('fs').promises;
+const tmpdir = require('../common/tmpdir');
+const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف';
+let cnt = 0;
+
+function getFileName() {
+ return path.join(tmpdir.path, `writev_promises_${++cnt}.txt`);
+}
+
+tmpdir.refresh();
+
+(async () => {
+ {
+ const filename = getFileName();
+ const handle = await fs.open(filename, 'w');
+ const buffer = Buffer.from(expected);
+ const bufferArr = [buffer, buffer];
+ const expectedLength = bufferArr.length * buffer.byteLength;
+ let { bytesWritten, buffers } = await handle.writev([Buffer.from('')],
+ null);
+ assert.deepStrictEqual(bytesWritten, 0);
+ assert.deepStrictEqual(buffers, [Buffer.from('')]);
+ ({ bytesWritten, buffers } = await handle.writev(bufferArr, null));
+ assert.deepStrictEqual(bytesWritten, expectedLength);
+ assert.deepStrictEqual(buffers, bufferArr);
+ assert(Buffer.concat(bufferArr).equals(await fs.readFile(filename)));
+ handle.close();
+ }
+
+ // fs.promises.writev() with an array of buffers without position.
+ {
+ const filename = getFileName();
+ const handle = await fs.open(filename, 'w');
+ const buffer = Buffer.from(expected);
+ const bufferArr = [buffer, buffer, buffer];
+ const expectedLength = bufferArr.length * buffer.byteLength;
+ let { bytesWritten, buffers } = await handle.writev([Buffer.from('')]);
+ assert.deepStrictEqual(bytesWritten, 0);
+ assert.deepStrictEqual(buffers, [Buffer.from('')]);
+ ({ bytesWritten, buffers } = await handle.writev(bufferArr));
+ assert.deepStrictEqual(bytesWritten, expectedLength);
+ assert.deepStrictEqual(buffers, bufferArr);
+ assert(Buffer.concat(bufferArr).equals(await fs.readFile(filename)));
+ handle.close();
+ }
+})();