140 lines
5.0 KiB
JavaScript
140 lines
5.0 KiB
JavaScript
"use strict";
|
|
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.fsCreateReadStream = exports.fsStat = void 0;
|
|
exports.streamToBuffer = streamToBuffer;
|
|
exports.streamToBuffer2 = streamToBuffer2;
|
|
exports.streamToBuffer3 = streamToBuffer3;
|
|
exports.readStreamToLocalFile = readStreamToLocalFile;
|
|
const tslib_1 = require("tslib");
|
|
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
const node_util_1 = tslib_1.__importDefault(require("node:util"));
|
|
const constants_js_1 = require("./constants.js");
|
|
/**
|
|
* Reads a readable stream into buffer. Fill the buffer from offset to end.
|
|
*
|
|
* @param stream - A Node.js Readable stream
|
|
* @param buffer - Buffer to be filled, length must greater than or equal to offset
|
|
* @param offset - From which position in the buffer to be filled, inclusive
|
|
* @param end - To which position in the buffer to be filled, exclusive
|
|
* @param encoding - Encoding of the Readable stream
|
|
*/
|
|
async function streamToBuffer(stream, buffer, offset, end, encoding) {
|
|
let pos = 0; // Position in stream
|
|
const count = end - offset; // Total amount of data needed in stream
|
|
return new Promise((resolve, reject) => {
|
|
const timeout = setTimeout(() => reject(new Error(`The operation cannot be completed in timeout.`)), constants_js_1.REQUEST_TIMEOUT);
|
|
stream.on("readable", () => {
|
|
if (pos >= count) {
|
|
clearTimeout(timeout);
|
|
resolve();
|
|
return;
|
|
}
|
|
let chunk = stream.read();
|
|
if (!chunk) {
|
|
return;
|
|
}
|
|
if (typeof chunk === "string") {
|
|
chunk = Buffer.from(chunk, encoding);
|
|
}
|
|
// How much data needed in this chunk
|
|
const chunkLength = pos + chunk.length > count ? count - pos : chunk.length;
|
|
buffer.fill(chunk.slice(0, chunkLength), offset + pos, offset + pos + chunkLength);
|
|
pos += chunkLength;
|
|
});
|
|
stream.on("end", () => {
|
|
clearTimeout(timeout);
|
|
if (pos < count) {
|
|
reject(new Error(`Stream drains before getting enough data needed. Data read: ${pos}, data need: ${count}`));
|
|
}
|
|
resolve();
|
|
});
|
|
stream.on("error", (msg) => {
|
|
clearTimeout(timeout);
|
|
reject(msg);
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Reads a readable stream into buffer entirely.
|
|
*
|
|
* @param stream - A Node.js Readable stream
|
|
* @param buffer - Buffer to be filled, length must greater than or equal to offset
|
|
* @param encoding - Encoding of the Readable stream
|
|
* @returns with the count of bytes read.
|
|
* @throws `RangeError` If buffer size is not big enough.
|
|
*/
|
|
async function streamToBuffer2(stream, buffer, encoding) {
|
|
let pos = 0; // Position in stream
|
|
const bufferSize = buffer.length;
|
|
return new Promise((resolve, reject) => {
|
|
stream.on("readable", () => {
|
|
let chunk = stream.read();
|
|
if (!chunk) {
|
|
return;
|
|
}
|
|
if (typeof chunk === "string") {
|
|
chunk = Buffer.from(chunk, encoding);
|
|
}
|
|
if (pos + chunk.length > bufferSize) {
|
|
reject(new Error(`Stream exceeds buffer size. Buffer size: ${bufferSize}`));
|
|
return;
|
|
}
|
|
buffer.fill(chunk, pos, pos + chunk.length);
|
|
pos += chunk.length;
|
|
});
|
|
stream.on("end", () => {
|
|
resolve(pos);
|
|
});
|
|
stream.on("error", reject);
|
|
});
|
|
}
|
|
/**
|
|
* Reads a readable stream into a buffer.
|
|
*
|
|
* @param stream - A Node.js Readable stream
|
|
* @param encoding - Encoding of the Readable stream
|
|
* @returns with the count of bytes read.
|
|
*/
|
|
async function streamToBuffer3(readableStream, encoding) {
|
|
return new Promise((resolve, reject) => {
|
|
const chunks = [];
|
|
readableStream.on("data", (data) => {
|
|
chunks.push(typeof data === "string" ? Buffer.from(data, encoding) : data);
|
|
});
|
|
readableStream.on("end", () => {
|
|
resolve(Buffer.concat(chunks));
|
|
});
|
|
readableStream.on("error", reject);
|
|
});
|
|
}
|
|
/**
|
|
* ONLY AVAILABLE IN NODE.JS RUNTIME.
|
|
*
|
|
* Writes the content of a readstream to a local file. Returns a Promise which is completed after the file handle is closed.
|
|
*
|
|
* @param rs - The read stream.
|
|
* @param file - Destination file path.
|
|
*/
|
|
async function readStreamToLocalFile(rs, file) {
|
|
return new Promise((resolve, reject) => {
|
|
const ws = node_fs_1.default.createWriteStream(file);
|
|
rs.on("error", (err) => {
|
|
reject(err);
|
|
});
|
|
ws.on("error", (err) => {
|
|
reject(err);
|
|
});
|
|
ws.on("close", resolve);
|
|
rs.pipe(ws);
|
|
});
|
|
}
|
|
/**
|
|
* ONLY AVAILABLE IN NODE.JS RUNTIME.
|
|
*
|
|
* Promisified version of fs.stat().
|
|
*/
|
|
exports.fsStat = node_util_1.default.promisify(node_fs_1.default.stat);
|
|
exports.fsCreateReadStream = node_fs_1.default.createReadStream;
|
|
//# sourceMappingURL=utils.js.map
|