‘use strict’;
const { EMPTY_BUFFER } = require(‘./constants’);
/**
* Merges an array of buffers into a new buffer. * * @param {Buffer[]} list The array of buffers to concat * @param {Number} totalLength The total length of buffers in the list * @return {Buffer} The resulting buffer * @public */
function concat(list, totalLength) {
if (list.length === 0) return EMPTY_BUFFER; if (list.length === 1) return list[0]; const target = Buffer.allocUnsafe(totalLength); let offset = 0; for (let i = 0; i < list.length; i++) { const buf = list[i]; target.set(buf, offset); offset += buf.length; } if (offset < totalLength) return target.slice(0, offset); return target;
}
/**
* Masks a buffer using the given mask. * * @param {Buffer} source The buffer to mask * @param {Buffer} mask The mask to use * @param {Buffer} output The buffer where to store the result * @param {Number} offset The offset at which to start writing * @param {Number} length The number of bytes to mask. * @public */
function _mask(source, mask, output, offset, length) {
for (let i = 0; i < length; i++) { output[offset + i] = source[i] ^ mask[i & 3]; }
}
/**
* Unmasks a buffer using the given mask. * * @param {Buffer} buffer The buffer to unmask * @param {Buffer} mask The mask to use * @public */
function _unmask(buffer, mask) {
// Required until https://github.com/nodejs/node/issues/9006 is resolved. const length = buffer.length; for (let i = 0; i < length; i++) { buffer[i] ^= mask[i & 3]; }
}
/**
* Converts a buffer to an `ArrayBuffer`. * * @param {Buffer} buf The buffer to convert * @return {ArrayBuffer} Converted buffer * @public */
function toArrayBuffer(buf) {
if (buf.byteLength === buf.buffer.byteLength) { return buf.buffer; } return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
}
/**
* Converts `data` to a `Buffer`. * * @param {*} data The data to convert * @return {Buffer} The buffer * @throws {TypeError} * @public */
function toBuffer(data) {
toBuffer.readOnly = true; if (Buffer.isBuffer(data)) return data; let buf; if (data instanceof ArrayBuffer) { buf = Buffer.from(data); } else if (ArrayBuffer.isView(data)) { buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength); } else { buf = Buffer.from(data); toBuffer.readOnly = false; } return buf;
}
try {
const bufferUtil = require('bufferutil'); const bu = bufferUtil.BufferUtil || bufferUtil; module.exports = { concat, mask(source, mask, output, offset, length) { if (length < 48) _mask(source, mask, output, offset, length); else bu.mask(source, mask, output, offset, length); }, toArrayBuffer, toBuffer, unmask(buffer, mask) { if (buffer.length < 32) _unmask(buffer, mask); else bu.unmask(buffer, mask); } };
} catch (e) /* istanbul ignore next */ {
module.exports = { concat, mask: _mask, toArrayBuffer, toBuffer, unmask: _unmask };
}