You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1369 lines
34 KiB

/* eslint-disable require-buffer */
'use strict';
const binding = process.binding('buffer');
const { isArrayBuffer, isSharedArrayBuffer } = process.binding('util');
const bindingObj = {};
const internalUtil = require('internal/util');
class FastBuffer extends Uint8Array {
constructor(arg1, arg2, arg3) {
super(arg1, arg2, arg3);
}
}
FastBuffer.prototype.constructor = Buffer;
Buffer.prototype = FastBuffer.prototype;
exports.Buffer = Buffer;
exports.SlowBuffer = SlowBuffer;
exports.INSPECT_MAX_BYTES = 50;
exports.kMaxLength = binding.kMaxLength;
const kFromErrorMsg = 'First argument must be a string, Buffer, ' +
'ArrayBuffer, Array, or array-like object.';
Buffer.poolSize = 8 * 1024;
var poolSize, poolOffset, allocPool;
binding.setupBufferJS(Buffer.prototype, bindingObj);
// |binding.zeroFill| can be undefined when running inside an isolate where we
// do not own the ArrayBuffer allocator. Zero fill is always on in that case.
const zeroFill = bindingObj.zeroFill || [0];
function createUnsafeBuffer(size) {
buffer: directly use ArrayBuffer as the pool Make the buffer pool an `ArrayBuffer` which is used directly, speeding up allocation noticeably in some cases. The only drawback happens when creating pool-based `Buffer` instances from strings whose byte lengths got overestimated by `Buffer.byteLength`, e.g. for base64-encoded strings containing whitespace, where two `Buffer` instances are being created. This may also be useful when providing Buffer classes in the future. Benchmark results for `benchmark/buffers/buffer-creation.js`: ``` improvement significant p.value len=1024 type="buffer()" 47.11 % *** 5.202555e-12 len=1024 type="fast-alloc" -3.41 % 3.823226e-01 len=1024 type="fast-alloc-fill" 1.11 % 7.985624e-01 len=1024 type="fast-allocUnsafe" 24.37 % *** 4.264084e-05 len=1024 type="slow" 4.81 % 2.634609e-01 len=1024 type="slow-allocUnsafe" 1.28 % 7.864850e-01 len=10 type="buffer()" 59.42 % *** 9.953552e-13 len=10 type="fast-alloc" -6.43 % 1.450524e-01 len=10 type="fast-alloc-fill" -2.96 % 4.873766e-01 len=10 type="fast-allocUnsafe" 33.89 % *** 6.517268e-07 len=10 type="slow" -1.48 % 7.357711e-01 len=10 type="slow-allocUnsafe" 0.04 % 9.939576e-01 len=2048 type="buffer()" 36.34 % *** 3.201045e-10 len=2048 type="fast-alloc" -4.67 % 2.172900e-01 len=2048 type="fast-alloc-fill" -0.15 % 9.732945e-01 len=2048 type="fast-allocUnsafe" 20.13 % *** 2.372115e-04 len=2048 type="slow" 4.35 % 2.831340e-01 len=2048 type="slow-allocUnsafe" 1.13 % 8.055388e-01 len=4096 type="buffer()" 4.90 % 2.495340e-01 len=4096 type="fast-alloc" -2.11 % 5.417520e-01 len=4096 type="fast-alloc-fill" -0.29 % 9.460378e-01 len=4096 type="fast-allocUnsafe" 3.11 % 5.001959e-01 len=4096 type="slow" 0.95 % 8.145888e-01 len=4096 type="slow-allocUnsafe" 3.74 % 4.227627e-01 len=8192 type="buffer()" 5.08 % 2.263029e-01 len=8192 type="fast-alloc" -1.16 % 7.300235e-01 len=8192 type="fast-alloc-fill" 0.40 % 9.179919e-01 len=8192 type="fast-allocUnsafe" 5.16 % 2.591544e-01 len=8192 type="slow" 2.57 % 5.212449e-01 len=8192 type="slow-allocUnsafe" -3.19 % 4.699138e-01 ``` PR-URL: https://github.com/nodejs/node/pull/8302 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
8 years ago
return new FastBuffer(createUnsafeArrayBuffer(size));
}
function createUnsafeArrayBuffer(size) {
zeroFill[0] = 0;
try {
buffer: directly use ArrayBuffer as the pool Make the buffer pool an `ArrayBuffer` which is used directly, speeding up allocation noticeably in some cases. The only drawback happens when creating pool-based `Buffer` instances from strings whose byte lengths got overestimated by `Buffer.byteLength`, e.g. for base64-encoded strings containing whitespace, where two `Buffer` instances are being created. This may also be useful when providing Buffer classes in the future. Benchmark results for `benchmark/buffers/buffer-creation.js`: ``` improvement significant p.value len=1024 type="buffer()" 47.11 % *** 5.202555e-12 len=1024 type="fast-alloc" -3.41 % 3.823226e-01 len=1024 type="fast-alloc-fill" 1.11 % 7.985624e-01 len=1024 type="fast-allocUnsafe" 24.37 % *** 4.264084e-05 len=1024 type="slow" 4.81 % 2.634609e-01 len=1024 type="slow-allocUnsafe" 1.28 % 7.864850e-01 len=10 type="buffer()" 59.42 % *** 9.953552e-13 len=10 type="fast-alloc" -6.43 % 1.450524e-01 len=10 type="fast-alloc-fill" -2.96 % 4.873766e-01 len=10 type="fast-allocUnsafe" 33.89 % *** 6.517268e-07 len=10 type="slow" -1.48 % 7.357711e-01 len=10 type="slow-allocUnsafe" 0.04 % 9.939576e-01 len=2048 type="buffer()" 36.34 % *** 3.201045e-10 len=2048 type="fast-alloc" -4.67 % 2.172900e-01 len=2048 type="fast-alloc-fill" -0.15 % 9.732945e-01 len=2048 type="fast-allocUnsafe" 20.13 % *** 2.372115e-04 len=2048 type="slow" 4.35 % 2.831340e-01 len=2048 type="slow-allocUnsafe" 1.13 % 8.055388e-01 len=4096 type="buffer()" 4.90 % 2.495340e-01 len=4096 type="fast-alloc" -2.11 % 5.417520e-01 len=4096 type="fast-alloc-fill" -0.29 % 9.460378e-01 len=4096 type="fast-allocUnsafe" 3.11 % 5.001959e-01 len=4096 type="slow" 0.95 % 8.145888e-01 len=4096 type="slow-allocUnsafe" 3.74 % 4.227627e-01 len=8192 type="buffer()" 5.08 % 2.263029e-01 len=8192 type="fast-alloc" -1.16 % 7.300235e-01 len=8192 type="fast-alloc-fill" 0.40 % 9.179919e-01 len=8192 type="fast-allocUnsafe" 5.16 % 2.591544e-01 len=8192 type="slow" 2.57 % 5.212449e-01 len=8192 type="slow-allocUnsafe" -3.19 % 4.699138e-01 ``` PR-URL: https://github.com/nodejs/node/pull/8302 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
8 years ago
return new ArrayBuffer(size);
} finally {
zeroFill[0] = 1;
}
}
function createPool() {
poolSize = Buffer.poolSize;
buffer: directly use ArrayBuffer as the pool Make the buffer pool an `ArrayBuffer` which is used directly, speeding up allocation noticeably in some cases. The only drawback happens when creating pool-based `Buffer` instances from strings whose byte lengths got overestimated by `Buffer.byteLength`, e.g. for base64-encoded strings containing whitespace, where two `Buffer` instances are being created. This may also be useful when providing Buffer classes in the future. Benchmark results for `benchmark/buffers/buffer-creation.js`: ``` improvement significant p.value len=1024 type="buffer()" 47.11 % *** 5.202555e-12 len=1024 type="fast-alloc" -3.41 % 3.823226e-01 len=1024 type="fast-alloc-fill" 1.11 % 7.985624e-01 len=1024 type="fast-allocUnsafe" 24.37 % *** 4.264084e-05 len=1024 type="slow" 4.81 % 2.634609e-01 len=1024 type="slow-allocUnsafe" 1.28 % 7.864850e-01 len=10 type="buffer()" 59.42 % *** 9.953552e-13 len=10 type="fast-alloc" -6.43 % 1.450524e-01 len=10 type="fast-alloc-fill" -2.96 % 4.873766e-01 len=10 type="fast-allocUnsafe" 33.89 % *** 6.517268e-07 len=10 type="slow" -1.48 % 7.357711e-01 len=10 type="slow-allocUnsafe" 0.04 % 9.939576e-01 len=2048 type="buffer()" 36.34 % *** 3.201045e-10 len=2048 type="fast-alloc" -4.67 % 2.172900e-01 len=2048 type="fast-alloc-fill" -0.15 % 9.732945e-01 len=2048 type="fast-allocUnsafe" 20.13 % *** 2.372115e-04 len=2048 type="slow" 4.35 % 2.831340e-01 len=2048 type="slow-allocUnsafe" 1.13 % 8.055388e-01 len=4096 type="buffer()" 4.90 % 2.495340e-01 len=4096 type="fast-alloc" -2.11 % 5.417520e-01 len=4096 type="fast-alloc-fill" -0.29 % 9.460378e-01 len=4096 type="fast-allocUnsafe" 3.11 % 5.001959e-01 len=4096 type="slow" 0.95 % 8.145888e-01 len=4096 type="slow-allocUnsafe" 3.74 % 4.227627e-01 len=8192 type="buffer()" 5.08 % 2.263029e-01 len=8192 type="fast-alloc" -1.16 % 7.300235e-01 len=8192 type="fast-alloc-fill" 0.40 % 9.179919e-01 len=8192 type="fast-allocUnsafe" 5.16 % 2.591544e-01 len=8192 type="slow" 2.57 % 5.212449e-01 len=8192 type="slow-allocUnsafe" -3.19 % 4.699138e-01 ``` PR-URL: https://github.com/nodejs/node/pull/8302 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
8 years ago
allocPool = createUnsafeArrayBuffer(poolSize);
poolOffset = 0;
}
createPool();
function alignPool() {
// Ensure aligned slices
if (poolOffset & 0x7) {
poolOffset |= 0x7;
poolOffset++;
}
}
/**
* The Buffer() construtor is "soft deprecated" ... that is, it is deprecated
* in the documentation and should not be used moving forward. Rather,
* developers should use one of the three new factory APIs: Buffer.from(),
* Buffer.allocUnsafe() or Buffer.alloc() based on their specific needs. There
* is no hard deprecation because of the extent to which the Buffer constructor
* is used in the ecosystem currently -- a hard deprecation would introduce too
* much breakage at this time. It's not likely that the Buffer constructors
* would ever actually be removed.
**/
var newBufferWarned = false;
function Buffer(arg, encodingOrOffset, length) {
if (!new.target && !newBufferWarned) {
newBufferWarned = true;
process.emitWarning(
'Using Buffer without `new` will soon stop working. ' +
'Use `new Buffer()`, or preferably ' +
'`Buffer.from()`, `Buffer.allocUnsafe()` or `Buffer.alloc()` instead.',
'DeprecationWarning'
);
}
// Common case.
if (typeof arg === 'number') {
if (typeof encodingOrOffset === 'string') {
throw new Error(
'If encoding is specified then the first argument must be a string'
);
}
return Buffer.allocUnsafe(arg);
}
return Buffer.from(arg, encodingOrOffset, length);
}
/**
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
* if value is a number.
* Buffer.from(str[, encoding])
* Buffer.from(array)
* Buffer.from(buffer)
* Buffer.from(arrayBuffer[, byteOffset[, length]])
**/
Buffer.from = function(value, encodingOrOffset, length) {
if (typeof value === 'number')
throw new TypeError('"value" argument must not be a number');
if (isArrayBuffer(value) || isSharedArrayBuffer(value))
return fromArrayBuffer(value, encodingOrOffset, length);
if (typeof value === 'string')
return fromString(value, encodingOrOffset);
return fromObject(value);
};
Object.setPrototypeOf(Buffer, Uint8Array);
function assertSize(size) {
let err = null;
if (typeof size !== 'number')
err = new TypeError('"size" argument must be a number');
else if (size < 0)
err = new RangeError('"size" argument must not be negative');
if (err) {
// The following hides the 'assertSize' method from the
// callstack. This is done simply to hide the internal
// details of the implementation from bleeding out to users.
Error.captureStackTrace(err, assertSize);
throw err;
}
}
/**
* Creates a new filled Buffer instance.
* alloc(size[, fill[, encoding]])
**/
Buffer.alloc = function(size, fill, encoding) {
assertSize(size);
if (size > 0 && fill !== undefined) {
// Since we are filling anyway, don't zero fill initially.
// Only pay attention to encoding if it's a string. This
// prevents accidentally sending in a number that would
// be interpretted as a start offset.
if (typeof encoding !== 'string')
encoding = undefined;
return createUnsafeBuffer(size).fill(fill, encoding);
}
return new FastBuffer(size);
};
/**
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer
* instance. If `--zero-fill-buffers` is set, will zero-fill the buffer.
**/
Buffer.allocUnsafe = function(size) {
assertSize(size);
return allocate(size);
};
/**
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled
* Buffer instance that is not allocated off the pre-initialized pool.
* If `--zero-fill-buffers` is set, will zero-fill the buffer.
**/
Buffer.allocUnsafeSlow = function(size) {
assertSize(size);
return createUnsafeBuffer(size);
};
// If --zero-fill-buffers command line argument is set, a zero-filled
// buffer is returned.
function SlowBuffer(length) {
if (+length != length)
length = 0;
return createUnsafeBuffer(+length);
}
Object.setPrototypeOf(SlowBuffer.prototype, Uint8Array.prototype);
Object.setPrototypeOf(SlowBuffer, Uint8Array);
function allocate(size) {
if (size <= 0) {
return new FastBuffer();
}
if (size < (Buffer.poolSize >>> 1)) {
if (size > (poolSize - poolOffset))
createPool();
buffer: directly use ArrayBuffer as the pool Make the buffer pool an `ArrayBuffer` which is used directly, speeding up allocation noticeably in some cases. The only drawback happens when creating pool-based `Buffer` instances from strings whose byte lengths got overestimated by `Buffer.byteLength`, e.g. for base64-encoded strings containing whitespace, where two `Buffer` instances are being created. This may also be useful when providing Buffer classes in the future. Benchmark results for `benchmark/buffers/buffer-creation.js`: ``` improvement significant p.value len=1024 type=&#34;buffer()&#34; 47.11 % *** 5.202555e-12 len=1024 type=&#34;fast-alloc&#34; -3.41 % 3.823226e-01 len=1024 type=&#34;fast-alloc-fill&#34; 1.11 % 7.985624e-01 len=1024 type=&#34;fast-allocUnsafe&#34; 24.37 % *** 4.264084e-05 len=1024 type=&#34;slow&#34; 4.81 % 2.634609e-01 len=1024 type=&#34;slow-allocUnsafe&#34; 1.28 % 7.864850e-01 len=10 type=&#34;buffer()&#34; 59.42 % *** 9.953552e-13 len=10 type=&#34;fast-alloc&#34; -6.43 % 1.450524e-01 len=10 type=&#34;fast-alloc-fill&#34; -2.96 % 4.873766e-01 len=10 type=&#34;fast-allocUnsafe&#34; 33.89 % *** 6.517268e-07 len=10 type=&#34;slow&#34; -1.48 % 7.357711e-01 len=10 type=&#34;slow-allocUnsafe&#34; 0.04 % 9.939576e-01 len=2048 type=&#34;buffer()&#34; 36.34 % *** 3.201045e-10 len=2048 type=&#34;fast-alloc&#34; -4.67 % 2.172900e-01 len=2048 type=&#34;fast-alloc-fill&#34; -0.15 % 9.732945e-01 len=2048 type=&#34;fast-allocUnsafe&#34; 20.13 % *** 2.372115e-04 len=2048 type=&#34;slow&#34; 4.35 % 2.831340e-01 len=2048 type=&#34;slow-allocUnsafe&#34; 1.13 % 8.055388e-01 len=4096 type=&#34;buffer()&#34; 4.90 % 2.495340e-01 len=4096 type=&#34;fast-alloc&#34; -2.11 % 5.417520e-01 len=4096 type=&#34;fast-alloc-fill&#34; -0.29 % 9.460378e-01 len=4096 type=&#34;fast-allocUnsafe&#34; 3.11 % 5.001959e-01 len=4096 type=&#34;slow&#34; 0.95 % 8.145888e-01 len=4096 type=&#34;slow-allocUnsafe&#34; 3.74 % 4.227627e-01 len=8192 type=&#34;buffer()&#34; 5.08 % 2.263029e-01 len=8192 type=&#34;fast-alloc&#34; -1.16 % 7.300235e-01 len=8192 type=&#34;fast-alloc-fill&#34; 0.40 % 9.179919e-01 len=8192 type=&#34;fast-allocUnsafe&#34; 5.16 % 2.591544e-01 len=8192 type=&#34;slow&#34; 2.57 % 5.212449e-01 len=8192 type=&#34;slow-allocUnsafe&#34; -3.19 % 4.699138e-01 ``` PR-URL: https://github.com/nodejs/node/pull/8302 Reviewed-By: Trevor Norris &lt;trev.norris@gmail.com&gt; Reviewed-By: James M Snell &lt;jasnell@gmail.com&gt;
8 years ago
var b = new FastBuffer(allocPool, poolOffset, size);
poolOffset += size;
alignPool();
return b;
} else {
return createUnsafeBuffer(size);
}
}
function fromString(string, encoding) {
if (typeof encoding !== 'string' || encoding === '')
encoding = 'utf8';
if (!Buffer.isEncoding(encoding))
throw new TypeError('"encoding" must be a valid string encoding');
if (string.length === 0)
return new FastBuffer();
var length = byteLength(string, encoding);
if (length >= (Buffer.poolSize >>> 1))
return binding.createFromString(string, encoding);
if (length > (poolSize - poolOffset))
createPool();
buffer: directly use ArrayBuffer as the pool Make the buffer pool an `ArrayBuffer` which is used directly, speeding up allocation noticeably in some cases. The only drawback happens when creating pool-based `Buffer` instances from strings whose byte lengths got overestimated by `Buffer.byteLength`, e.g. for base64-encoded strings containing whitespace, where two `Buffer` instances are being created. This may also be useful when providing Buffer classes in the future. Benchmark results for `benchmark/buffers/buffer-creation.js`: ``` improvement significant p.value len=1024 type=&#34;buffer()&#34; 47.11 % *** 5.202555e-12 len=1024 type=&#34;fast-alloc&#34; -3.41 % 3.823226e-01 len=1024 type=&#34;fast-alloc-fill&#34; 1.11 % 7.985624e-01 len=1024 type=&#34;fast-allocUnsafe&#34; 24.37 % *** 4.264084e-05 len=1024 type=&#34;slow&#34; 4.81 % 2.634609e-01 len=1024 type=&#34;slow-allocUnsafe&#34; 1.28 % 7.864850e-01 len=10 type=&#34;buffer()&#34; 59.42 % *** 9.953552e-13 len=10 type=&#34;fast-alloc&#34; -6.43 % 1.450524e-01 len=10 type=&#34;fast-alloc-fill&#34; -2.96 % 4.873766e-01 len=10 type=&#34;fast-allocUnsafe&#34; 33.89 % *** 6.517268e-07 len=10 type=&#34;slow&#34; -1.48 % 7.357711e-01 len=10 type=&#34;slow-allocUnsafe&#34; 0.04 % 9.939576e-01 len=2048 type=&#34;buffer()&#34; 36.34 % *** 3.201045e-10 len=2048 type=&#34;fast-alloc&#34; -4.67 % 2.172900e-01 len=2048 type=&#34;fast-alloc-fill&#34; -0.15 % 9.732945e-01 len=2048 type=&#34;fast-allocUnsafe&#34; 20.13 % *** 2.372115e-04 len=2048 type=&#34;slow&#34; 4.35 % 2.831340e-01 len=2048 type=&#34;slow-allocUnsafe&#34; 1.13 % 8.055388e-01 len=4096 type=&#34;buffer()&#34; 4.90 % 2.495340e-01 len=4096 type=&#34;fast-alloc&#34; -2.11 % 5.417520e-01 len=4096 type=&#34;fast-alloc-fill&#34; -0.29 % 9.460378e-01 len=4096 type=&#34;fast-allocUnsafe&#34; 3.11 % 5.001959e-01 len=4096 type=&#34;slow&#34; 0.95 % 8.145888e-01 len=4096 type=&#34;slow-allocUnsafe&#34; 3.74 % 4.227627e-01 len=8192 type=&#34;buffer()&#34; 5.08 % 2.263029e-01 len=8192 type=&#34;fast-alloc&#34; -1.16 % 7.300235e-01 len=8192 type=&#34;fast-alloc-fill&#34; 0.40 % 9.179919e-01 len=8192 type=&#34;fast-allocUnsafe&#34; 5.16 % 2.591544e-01 len=8192 type=&#34;slow&#34; 2.57 % 5.212449e-01 len=8192 type=&#34;slow-allocUnsafe&#34; -3.19 % 4.699138e-01 ``` PR-URL: https://github.com/nodejs/node/pull/8302 Reviewed-By: Trevor Norris &lt;trev.norris@gmail.com&gt; Reviewed-By: James M Snell &lt;jasnell@gmail.com&gt;
8 years ago
var b = new FastBuffer(allocPool, poolOffset, length);
var actual = b.write(string, encoding);
if (actual !== length) {
// byteLength() may overestimate. That’s a rare case, though.
b = new FastBuffer(allocPool, poolOffset, actual);
}
poolOffset += actual;
alignPool();
return b;
}
function fromArrayLike(obj) {
const length = obj.length;
const b = allocate(length);
for (var i = 0; i < length; i++)
b[i] = obj[i];
return b;
}
function fromArrayBuffer(obj, byteOffset, length) {
byteOffset >>>= 0;
const maxLength = obj.byteLength - byteOffset;
if (maxLength < 0)
throw new RangeError("'offset' is out of bounds");
if (length === undefined) {
length = maxLength;
} else {
length >>>= 0;
if (length > maxLength)
throw new RangeError("'length' is out of bounds");
}
return new FastBuffer(obj, byteOffset, length);
}
function fromObject(obj) {
if (obj instanceof Buffer) {
const b = allocate(obj.length);
if (b.length === 0)
return b;
obj.copy(b, 0, 0, obj.length);
return b;
}
if (obj) {
if ('length' in obj || isArrayBuffer(obj.buffer) ||
isSharedArrayBuffer(obj.buffer)) {
if (typeof obj.length !== 'number' || obj.length !== obj.length) {
return new FastBuffer();
}
return fromArrayLike(obj);
}
if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
return fromArrayLike(obj.data);
}
}
throw new TypeError(kFromErrorMsg);
}
// Static methods
Buffer.isBuffer = function isBuffer(b) {
return b instanceof Buffer;
};
Buffer.compare = function compare(a, b) {
if (!(a instanceof Buffer) ||
!(b instanceof Buffer)) {
throw new TypeError('Arguments must be Buffers');
}
if (a === b) {
return 0;
}
return binding.compare(a, b);
};
Buffer.isEncoding = function(encoding) {
return typeof encoding === 'string' &&
typeof internalUtil.normalizeEncoding(encoding) === 'string';
};
Buffer[internalUtil.kIsEncodingSymbol] = Buffer.isEncoding;
Buffer.concat = function(list, length) {
var i;
if (!Array.isArray(list))
throw new TypeError('"list" argument must be an Array of Buffers');
if (list.length === 0)
return new FastBuffer();
if (length === undefined) {
length = 0;
for (i = 0; i < list.length; i++)
length += list[i].length;
} else {
length = length >>> 0;
}
var buffer = Buffer.allocUnsafe(length);
var pos = 0;
for (i = 0; i < list.length; i++) {
var buf = list[i];
if (!Buffer.isBuffer(buf))
throw new TypeError('"list" argument must be an Array of Buffers');
buf.copy(buffer, pos);
pos += buf.length;
}
// Note: `length` is always equal to `buffer.length` at this point
if (pos < length) {
// Zero-fill the remaining bytes if the specified `length` was more than
// the actual total length, i.e. if we have some remaining allocated bytes
// there were not initialized.
buffer.fill(0, pos, length);
}
return buffer;
};
function base64ByteLength(str, bytes) {
// Handle padding
if (str.charCodeAt(bytes - 1) === 0x3D)
bytes--;
if (bytes > 1 && str.charCodeAt(bytes - 1) === 0x3D)
bytes--;
// Base64 ratio: 3/4
return (bytes * 3) >>> 2;
}
function byteLength(string, encoding) {
if (typeof string !== 'string') {
if (ArrayBuffer.isView(string) || isArrayBuffer(string) ||
isSharedArrayBuffer(string)) {
return string.byteLength;
}
throw new TypeError('"string" must be a string, Buffer, or ArrayBuffer');
}
var len = string.length;
if (len === 0)
return 0;
// Use a for loop to avoid recursion
var loweredCase = false;
for (;;) {
switch (encoding) {
case 'ascii':
case 'latin1':
case 'binary':
return len;
case 'utf8':
case 'utf-8':
case undefined:
return binding.byteLengthUtf8(string);
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2;
case 'hex':
return len >>> 1;
case 'base64':
return base64ByteLength(string, len);
default:
// The C++ binding defaulted to UTF8, we should too.
if (loweredCase)
return binding.byteLengthUtf8(string);
encoding = ('' + encoding).toLowerCase();
loweredCase = true;
}
}
}
Buffer.byteLength = byteLength;
// For backwards compatibility.
Object.defineProperty(Buffer.prototype, 'parent', {
enumerable: true,
get: function() {
if (!(this instanceof Buffer))
return undefined;
return this.buffer;
}
});
Object.defineProperty(Buffer.prototype, 'offset', {
enumerable: true,
get: function() {
if (!(this instanceof Buffer))
return undefined;
return this.byteOffset;
}
});
function slowToString(encoding, start, end) {
var loweredCase = false;
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
// undefined is handled specially as per ECMA-262 6th Edition,
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
if (start === undefined || start < 0)
start = 0;
// Return early if start > this.length. Done here to prevent potential uint32
// coercion fail below.
if (start > this.length)
return '';
if (end === undefined || end > this.length)
end = this.length;
if (end <= 0)
return '';
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
end >>>= 0;
start >>>= 0;
if (end <= start)
return '';
if (!encoding) encoding = 'utf8';
while (true) {
switch (encoding) {
case 'hex':
return this.hexSlice(start, end);
case 'utf8':
case 'utf-8':
return this.utf8Slice(start, end);
case 'ascii':
return this.asciiSlice(start, end);
case 'latin1':
case 'binary':
return this.latin1Slice(start, end);
case 'base64':
return this.base64Slice(start, end);
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return this.ucs2Slice(start, end);
default:
if (loweredCase)
throw new TypeError('Unknown encoding: ' + encoding);
encoding = (encoding + '').toLowerCase();
loweredCase = true;
}
}
}
Buffer.prototype.toString = function() {
let result;
if (arguments.length === 0) {
result = this.utf8Slice(0, this.length);
} else {
result = slowToString.apply(this, arguments);
}
if (result === undefined)
throw new Error('"toString()" failed');
return result;
};
Buffer.prototype.equals = function equals(b) {
if (!(b instanceof Buffer))
throw new TypeError('Argument must be a Buffer');
if (this === b)
return true;
return binding.compare(this, b) === 0;
};
// Override how buffers are presented by util.inspect().
Buffer.prototype[internalUtil.customInspectSymbol] = function inspect() {
var str = '';
var max = exports.INSPECT_MAX_BYTES;
if (this.length > 0) {
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ');
if (this.length > max)
str += ' ... ';
}
return '<' + this.constructor.name + ' ' + str + '>';
};
Buffer.prototype.inspect = Buffer.prototype[internalUtil.customInspectSymbol];
Buffer.prototype.compare = function compare(target,
start,
end,
thisStart,
thisEnd) {
if (!(target instanceof Buffer))
throw new TypeError('Argument must be a Buffer');
if (start === undefined)
start = 0;
if (end === undefined)
end = target.length;
if (thisStart === undefined)
thisStart = 0;
if (thisEnd === undefined)
thisEnd = this.length;
if (start < 0 ||
end > target.length ||
thisStart < 0 ||
thisEnd > this.length) {
throw new RangeError('out of range index');
}
if (thisStart >= thisEnd && start >= end)
return 0;
if (thisStart >= thisEnd)
return -1;
if (start >= end)
return 1;
start >>>= 0;
end >>>= 0;
thisStart >>>= 0;
thisEnd >>>= 0;
return binding.compareOffset(this, target, start, thisStart, end, thisEnd);
};
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
if (typeof byteOffset === 'string') {
encoding = byteOffset;
byteOffset = undefined;
} else if (byteOffset > 0x7fffffff) {
byteOffset = 0x7fffffff;
} else if (byteOffset < -0x80000000) {
byteOffset = -0x80000000;
}
byteOffset = +byteOffset; // Coerce to Number.
if (isNaN(byteOffset)) {
// If the offset is undefined, null, NaN, "foo", etc, search whole buffer.
byteOffset = dir ? 0 : (buffer.length - 1);
}
dir = !!dir; // Cast to bool.
if (typeof val === 'string') {
if (encoding === undefined) {
return binding.indexOfString(buffer, val, byteOffset, encoding, dir);
}
return slowIndexOf(buffer, val, byteOffset, encoding, dir);
} else if (val instanceof Buffer) {
return binding.indexOfBuffer(buffer, val, byteOffset, encoding, dir);
} else if (typeof val === 'number') {
return binding.indexOfNumber(buffer, val, byteOffset, dir);
}
throw new TypeError('"val" argument must be string, number or Buffer');
}
function slowIndexOf(buffer, val, byteOffset, encoding, dir) {
var loweredCase = false;
for (;;) {
switch (encoding) {
case 'utf8':
case 'utf-8':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
case 'latin1':
case 'binary':
return binding.indexOfString(buffer, val, byteOffset, encoding, dir);
case 'base64':
case 'ascii':
case 'hex':
return binding.indexOfBuffer(
buffer, Buffer.from(val, encoding), byteOffset, encoding, dir);
default:
if (loweredCase) {
throw new TypeError('Unknown encoding: ' + encoding);
}
encoding = ('' + encoding).toLowerCase();
loweredCase = true;
}
}
}
Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
};
Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
};
Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
return this.indexOf(val, byteOffset, encoding) !== -1;
};
// Usage:
// buffer.fill(number[, offset[, end]])
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill(val, start, end, encoding) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
encoding = start;
start = 0;
end = this.length;
} else if (typeof end === 'string') {
encoding = end;
end = this.length;
}
if (val.length === 1) {
var code = val.charCodeAt(0);
if (code < 256)
val = code;
}
if (val.length === 0) {
// Previously, if val === '', the Buffer would not fill,
// which is rather surprising.
val = 0;
}
if (encoding !== undefined && typeof encoding !== 'string') {
throw new TypeError('encoding must be a string');
}
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding);
}
} else if (typeof val === 'number') {
val = val & 255;
}
// Invalid ranges are not set to a default, so can range check early.
if (start < 0 || end > this.length)
throw new RangeError('Out of range index');
if (end <= start)
return this;
start = start >>> 0;
end = end === undefined ? this.length : end >>> 0;
binding.fill(this, val, start, end, encoding);
return this;
};
Buffer.prototype.write = function(string, offset, length, encoding) {
// Buffer#write(string);
if (offset === undefined) {
encoding = 'utf8';
length = this.length;
offset = 0;
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset;
length = this.length;
offset = 0;
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset >>> 0;
if (isFinite(length)) {
length = length >>> 0;
if (encoding === undefined)
encoding = 'utf8';
} else {
encoding = length;
length = undefined;
}
} else {
// if someone is still calling the obsolete form of write(), tell them.
// we don't want eg buf.write("foo", "utf8", 10) to silently turn into
// buf.write("foo", "utf8"), so we can't ignore extra args
throw new Error('Buffer.write(string, encoding, offset[, length]) ' +
'is no longer supported');
}
var remaining = this.length - offset;
if (length === undefined || length > remaining)
length = remaining;
if (string.length > 0 && (length < 0 || offset < 0))
throw new RangeError('Attempt to write outside buffer bounds');
if (!encoding)
encoding = 'utf8';
var loweredCase = false;
for (;;) {
switch (encoding) {
case 'hex':
return this.hexWrite(string, offset, length);
case 'utf8':
case 'utf-8':
return this.utf8Write(string, offset, length);
case 'ascii':
return this.asciiWrite(string, offset, length);
case 'latin1':
case 'binary':
return this.latin1Write(string, offset, length);
case 'base64':
// Warning: maxLength not taken into account in base64Write
return this.base64Write(string, offset, length);
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return this.ucs2Write(string, offset, length);
default:
if (loweredCase)
throw new TypeError('Unknown encoding: ' + encoding);
encoding = ('' + encoding).toLowerCase();
loweredCase = true;
}
}
};
Buffer.prototype.toJSON = function() {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this, 0)
};
};
function adjustOffset(offset, length) {
// Use Math.trunc() to convert offset to an integer value that can be larger
// than an Int32. Hence, don't use offset | 0 or similar techniques.
offset = Math.trunc(offset);
if (offset === 0 || Number.isNaN(offset)) {
return 0;
buffer: coerce slice parameters consistently As shown in https://github.com/nodejs/node/issues/9096, the offset and end value of the `slice` call are coerced to numbers and then passed to `FastBuffer`, which internally truncates the mantissa part if the number is actually a floating point number. This actually affects the new length of the slice calculation. For example, &gt; const original = Buffer.from(&#39;abcd&#39;); undefined &gt; original.slice(original.length / 3).toString() &#39;bc&#39; This happens because, starting value of the slice is 4 / 3, which is 1.33 (approximately). Now, the length of the slice is calculated as the difference between the actual length of the buffer and the starting offset. So, it becomes 2.67 (4 - 1.33). Now, a new `FastBuffer` is constructed, with the following values as parameters, 1. actual buffer object, 2. starting value, which is 1.33 and 3. the length 2.67. The underlying C++ code truncates the numbers and they become 1 and 2. That is why the result is just `bc`. This patch makes sure that all the offsets are coerced to integers before any calculations are done. Fixes: https://github.com/nodejs/node/issues/9096 PR-URL: https://github.com/nodejs/node/pull/9101 Reviewed-By: James M Snell &lt;jasnell@gmail.com&gt; Reviewed-By: Michaël Zasso &lt;targos@protonmail.com&gt; Reviewed-By: Anna Henningsen &lt;anna@addaleax.net&gt; Reviewed-By: Franziska Hinkelmann &lt;franziska.hinkelmann@gmail.com&gt; Reviewed-By: Colin Ihrig &lt;cjihrig@gmail.com&gt; Reviewed-By: Luigi Pinca &lt;luigipinca@gmail.com&gt; Reviewed-By: Brian White &lt;mscdex@mscdex.net&gt;
8 years ago
} else if (offset < 0) {
offset += length;
return offset > 0 ? offset : 0;
} else {
return offset < length ? offset : length;
}
}
Buffer.prototype.slice = function slice(start, end) {
const srcLength = this.length;
start = adjustOffset(start, srcLength);
end = end !== undefined ? adjustOffset(end, srcLength) : srcLength;
const newLength = end > start ? end - start : 0;
return new FastBuffer(this.buffer, this.byteOffset + start, newLength);
};
function checkOffset(offset, ext, length) {
if (offset + ext > length)
throw new RangeError('Index out of range');
}
Buffer.prototype.readUIntLE = function(offset, byteLength, noAssert) {
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert)
checkOffset(offset, byteLength, this.length);
var val = this[offset];
var mul = 1;
var i = 0;
while (++i < byteLength && (mul *= 0x100))
val += this[offset + i] * mul;
return val;
};
Buffer.prototype.readUIntBE = function(offset, byteLength, noAssert) {
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert)
checkOffset(offset, byteLength, this.length);
var val = this[offset + --byteLength];
var mul = 1;
while (byteLength > 0 && (mul *= 0x100))
val += this[offset + --byteLength] * mul;
return val;
};
Buffer.prototype.readUInt8 = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 1, this.length);
return this[offset];
};
Buffer.prototype.readUInt16LE = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 2, this.length);
return this[offset] | (this[offset + 1] << 8);
};
Buffer.prototype.readUInt16BE = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 2, this.length);
return (this[offset] << 8) | this[offset + 1];
};
Buffer.prototype.readUInt32LE = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 4, this.length);
return ((this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16)) +
(this[offset + 3] * 0x1000000);
};
Buffer.prototype.readUInt32BE = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 4, this.length);
return (this[offset] * 0x1000000) +
((this[offset + 1] << 16) |
(this[offset + 2] << 8) |
this[offset + 3]);
};
Buffer.prototype.readIntLE = function(offset, byteLength, noAssert) {
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert)
checkOffset(offset, byteLength, this.length);
var val = this[offset];
var mul = 1;
var i = 0;
while (++i < byteLength && (mul *= 0x100))
val += this[offset + i] * mul;
mul *= 0x80;
if (val >= mul)
val -= Math.pow(2, 8 * byteLength);
return val;
};
Buffer.prototype.readIntBE = function(offset, byteLength, noAssert) {
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert)
checkOffset(offset, byteLength, this.length);
var i = byteLength;
var mul = 1;
var val = this[offset + --i];
while (i > 0 && (mul *= 0x100))
val += this[offset + --i] * mul;
mul *= 0x80;
if (val >= mul)
val -= Math.pow(2, 8 * byteLength);
return val;
};
Buffer.prototype.readInt8 = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 1, this.length);
var val = this[offset];
return !(val & 0x80) ? val : (0xff - val + 1) * -1;
};
Buffer.prototype.readInt16LE = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 2, this.length);
var val = this[offset] | (this[offset + 1] << 8);
return (val & 0x8000) ? val | 0xFFFF0000 : val;
};
Buffer.prototype.readInt16BE = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 2, this.length);
var val = this[offset + 1] | (this[offset] << 8);
return (val & 0x8000) ? val | 0xFFFF0000 : val;
};
Buffer.prototype.readInt32LE = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 4, this.length);
return (this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16) |
(this[offset + 3] << 24);
};
Buffer.prototype.readInt32BE = function(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 4, this.length);
return (this[offset] << 24) |
(this[offset + 1] << 16) |
(this[offset + 2] << 8) |
(this[offset + 3]);
};
Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 4, this.length);
return binding.readFloatLE(this, offset);
};
Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 4, this.length);
return binding.readFloatBE(this, offset);
};
Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 8, this.length);
return binding.readDoubleLE(this, offset);
};
Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
offset = offset >>> 0;
if (!noAssert)
checkOffset(offset, 8, this.length);
return binding.readDoubleBE(this, offset);
};
function checkInt(buffer, value, offset, ext, max, min) {
if (!(buffer instanceof Buffer))
throw new TypeError('"buffer" argument must be a Buffer instance');
if (value > max || value < min)
throw new TypeError('"value" argument is out of bounds');
if (offset + ext > buffer.length)
throw new RangeError('Index out of range');
}
Buffer.prototype.writeUIntLE = function(value, offset, byteLength, noAssert) {
value = +value;
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert) {
const maxBytes = Math.pow(2, 8 * byteLength) - 1;
checkInt(this, value, offset, byteLength, maxBytes, 0);
}
var mul = 1;
var i = 0;
this[offset] = value;
while (++i < byteLength && (mul *= 0x100))
this[offset + i] = (value / mul) >>> 0;
return offset + byteLength;
};
Buffer.prototype.writeUIntBE = function(value, offset, byteLength, noAssert) {
value = +value;
offset = offset >>> 0;
byteLength = byteLength >>> 0;
if (!noAssert) {
const maxBytes = Math.pow(2, 8 * byteLength) - 1;
checkInt(this, value, offset, byteLength, maxBytes, 0);
}
var i = byteLength - 1;
var mul = 1;
this[offset + i] = value;
while (--i >= 0 && (mul *= 0x100))
this[offset + i] = (value / mul) >>> 0;
return offset + byteLength;
};
Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 1, 0xff, 0);
this[offset] = value;
return offset + 1;
};
Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 2, 0xffff, 0);
this[offset] = value;
this[offset + 1] = (value >>> 8);
return offset + 2;
};
Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 2, 0xffff, 0);
this[offset] = (value >>> 8);
this[offset + 1] = value;
return offset + 2;
};
Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 4, 0xffffffff, 0);
this[offset + 3] = (value >>> 24);
this[offset + 2] = (value >>> 16);
this[offset + 1] = (value >>> 8);
this[offset] = value;
return offset + 4;
};
Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 4, 0xffffffff, 0);
this[offset] = (value >>> 24);
this[offset + 1] = (value >>> 16);
this[offset + 2] = (value >>> 8);
this[offset + 3] = value;
return offset + 4;
};
Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) {
checkInt(this,
value,
offset,
byteLength,
Math.pow(2, 8 * byteLength - 1) - 1,
-Math.pow(2, 8 * byteLength - 1));
}
var i = 0;
var mul = 1;
var sub = 0;
this[offset] = value;
while (++i < byteLength && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0)
sub = 1;
this[offset + i] = ((value / mul) >> 0) - sub;
}
return offset + byteLength;
};
Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert) {
checkInt(this,
value,
offset,
byteLength,
Math.pow(2, 8 * byteLength - 1) - 1,
-Math.pow(2, 8 * byteLength - 1));
}
var i = byteLength - 1;
var mul = 1;
var sub = 0;
this[offset + i] = value;
while (--i >= 0 && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0)
sub = 1;
this[offset + i] = ((value / mul) >> 0) - sub;
}
return offset + byteLength;
};
Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 1, 0x7f, -0x80);
this[offset] = value;
return offset + 1;
};
Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 2, 0x7fff, -0x8000);
this[offset] = value;
this[offset + 1] = (value >>> 8);
return offset + 2;
};
Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 2, 0x7fff, -0x8000);
this[offset] = (value >>> 8);
this[offset + 1] = value;
return offset + 2;
};
Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
this[offset] = value;
this[offset + 1] = (value >>> 8);
this[offset + 2] = (value >>> 16);
this[offset + 3] = (value >>> 24);
return offset + 4;
};
Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
value = +value;
offset = offset >>> 0;
if (!noAssert)
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
this[offset] = (value >>> 24);
this[offset + 1] = (value >>> 16);
this[offset + 2] = (value >>> 8);
this[offset + 3] = value;
return offset + 4;
};
Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) {
val = +val;
offset = offset >>> 0;
if (!noAssert)
binding.writeFloatLE(this, val, offset);
else
binding.writeFloatLE(this, val, offset, true);
return offset + 4;
};
Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
val = +val;
offset = offset >>> 0;
if (!noAssert)
binding.writeFloatBE(this, val, offset);
else
binding.writeFloatBE(this, val, offset, true);
return offset + 4;
};
Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
val = +val;
offset = offset >>> 0;
if (!noAssert)
binding.writeDoubleLE(this, val, offset);
else
binding.writeDoubleLE(this, val, offset, true);
return offset + 8;
};
Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
val = +val;
offset = offset >>> 0;
if (!noAssert)
binding.writeDoubleBE(this, val, offset);
else
binding.writeDoubleBE(this, val, offset, true);
return offset + 8;
};
const swap16n = binding.swap16;
const swap32n = binding.swap32;
const swap64n = binding.swap64;
function swap(b, n, m) {
const i = b[n];
b[n] = b[m];
b[m] = i;
}
Buffer.prototype.swap16 = function swap16() {
// For Buffer.length < 128, it's generally faster to
// do the swap in javascript. For larger buffers,
// dropping down to the native code is faster.
const len = this.length;
if (len % 2 !== 0)
throw new RangeError('Buffer size must be a multiple of 16-bits');
if (len < 128) {
for (var i = 0; i < len; i += 2)
swap(this, i, i + 1);
return this;
}
return swap16n(this);
};
Buffer.prototype.swap32 = function swap32() {
// For Buffer.length < 192, it's generally faster to
// do the swap in javascript. For larger buffers,
// dropping down to the native code is faster.
const len = this.length;
if (len % 4 !== 0)
throw new RangeError('Buffer size must be a multiple of 32-bits');
if (len < 192) {
for (var i = 0; i < len; i += 4) {
swap(this, i, i + 3);
swap(this, i + 1, i + 2);
}
return this;
}
return swap32n(this);
};
Buffer.prototype.swap64 = function swap64() {
// For Buffer.length < 192, it's generally faster to
// do the swap in javascript. For larger buffers,
// dropping down to the native code is faster.
const len = this.length;
if (len % 8 !== 0)
throw new RangeError('Buffer size must be a multiple of 64-bits');
if (len < 192) {
for (var i = 0; i < len; i += 8) {
swap(this, i, i + 7);
swap(this, i + 1, i + 6);
swap(this, i + 2, i + 5);
swap(this, i + 3, i + 4);
}
return this;
}
return swap64n(this);
};
Buffer.prototype.toLocaleString = Buffer.prototype.toString;
// Put this at the end because internal/buffer has a circular
// dependency on Buffer.
exports.transcode = require('internal/buffer').transcode;