mirror of
https://github.com/nodejs/node.git
synced 2025-05-07 13:47:16 +00:00

The Buffer#(read|write)U?Int(B|L)E functions should not use a default value. This is very likely a bug and it was never documented that way. Besides that this also improves the tests by adding more tests and by refactoring them to less code lines. PR-URL: https://github.com/nodejs/node/pull/20054 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
828 lines
22 KiB
JavaScript
828 lines
22 KiB
JavaScript
'use strict';
|
|
|
|
const binding = process.binding('buffer');
|
|
const {
|
|
ERR_BUFFER_OUT_OF_BOUNDS,
|
|
ERR_INVALID_ARG_TYPE,
|
|
ERR_OUT_OF_RANGE
|
|
} = require('internal/errors').codes;
|
|
const { setupBufferJS } = binding;
|
|
|
|
// Remove from the binding so that function is only available as exported here.
|
|
// (That is, for internal use only.)
|
|
delete binding.setupBufferJS;
|
|
|
|
// Temporary buffers to convert numbers.
|
|
const float32Array = new Float32Array(1);
|
|
const uInt8Float32Array = new Uint8Array(float32Array.buffer);
|
|
const float64Array = new Float64Array(1);
|
|
const uInt8Float64Array = new Uint8Array(float64Array.buffer);
|
|
|
|
// Check endianness.
|
|
float32Array[0] = -1; // 0xBF800000
|
|
// Either it is [0, 0, 128, 191] or [191, 128, 0, 0]. It is not possible to
|
|
// check this with `os.endianness()` because that is determined at compile time.
|
|
const bigEndian = uInt8Float32Array[3] === 0;
|
|
|
|
function checkBounds(buf, offset, byteLength) {
|
|
checkNumberType(offset);
|
|
if (buf[offset] === undefined || buf[offset + byteLength] === undefined)
|
|
boundsError(offset, buf.length - (byteLength + 1));
|
|
}
|
|
|
|
function checkInt(value, min, max, buf, offset, byteLength) {
|
|
if (value > max || value < min) {
|
|
throw new ERR_OUT_OF_RANGE('value', `>= ${min} and <= ${max}`, value);
|
|
}
|
|
checkBounds(buf, offset, byteLength);
|
|
}
|
|
|
|
function checkNumberType(value, type) {
|
|
if (typeof value !== 'number') {
|
|
throw new ERR_INVALID_ARG_TYPE(type || 'offset', 'number', value);
|
|
}
|
|
}
|
|
|
|
function boundsError(value, length, type) {
|
|
if (Math.floor(value) !== value) {
|
|
checkNumberType(value, type);
|
|
throw new ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value);
|
|
}
|
|
|
|
if (length < 0)
|
|
throw new ERR_BUFFER_OUT_OF_BOUNDS();
|
|
|
|
throw new ERR_OUT_OF_RANGE(type || 'offset',
|
|
`>= ${type ? 1 : 0} and <= ${length}`,
|
|
value);
|
|
}
|
|
|
|
// Read integers.
|
|
function readUIntLE(offset, byteLength) {
|
|
if (offset === undefined)
|
|
throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
|
|
if (byteLength === 6)
|
|
return readUInt48LE(this, offset);
|
|
if (byteLength === 5)
|
|
return readUInt40LE(this, offset);
|
|
if (byteLength === 3)
|
|
return readUInt24LE(this, offset);
|
|
if (byteLength === 4)
|
|
return this.readUInt32LE(offset);
|
|
if (byteLength === 2)
|
|
return this.readUInt16LE(offset);
|
|
if (byteLength === 1)
|
|
return this.readUInt8(offset);
|
|
|
|
boundsError(byteLength, 6, 'byteLength');
|
|
}
|
|
|
|
function readUInt48LE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 5];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 6);
|
|
|
|
return first +
|
|
buf[++offset] * 2 ** 8 +
|
|
buf[++offset] * 2 ** 16 +
|
|
buf[++offset] * 2 ** 24 +
|
|
(buf[++offset] + last * 2 ** 8) * 2 ** 32;
|
|
}
|
|
|
|
function readUInt40LE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 4];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 5);
|
|
|
|
return first +
|
|
buf[++offset] * 2 ** 8 +
|
|
buf[++offset] * 2 ** 16 +
|
|
buf[++offset] * 2 ** 24 +
|
|
last * 2 ** 32;
|
|
}
|
|
|
|
function readUInt32LE(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 3];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 4);
|
|
|
|
return first +
|
|
this[++offset] * 2 ** 8 +
|
|
this[++offset] * 2 ** 16 +
|
|
last * 2 ** 24;
|
|
}
|
|
|
|
function readUInt24LE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 2];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 3);
|
|
|
|
return first + buf[++offset] * 2 ** 8 + last * 2 ** 16;
|
|
}
|
|
|
|
function readUInt16LE(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 1];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 2);
|
|
|
|
return first + last * 2 ** 8;
|
|
}
|
|
|
|
function readUInt8(offset = 0) {
|
|
checkNumberType(offset);
|
|
const val = this[offset];
|
|
if (val === undefined)
|
|
boundsError(offset, this.length - 1);
|
|
|
|
return val;
|
|
}
|
|
|
|
function readUIntBE(offset, byteLength) {
|
|
if (offset === undefined)
|
|
throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
|
|
if (byteLength === 6)
|
|
return readUInt48BE(this, offset);
|
|
if (byteLength === 5)
|
|
return readUInt40BE(this, offset);
|
|
if (byteLength === 3)
|
|
return readUInt24BE(this, offset);
|
|
if (byteLength === 4)
|
|
return this.readUInt32BE(offset);
|
|
if (byteLength === 2)
|
|
return this.readUInt16BE(offset);
|
|
if (byteLength === 1)
|
|
return this.readUInt8(offset);
|
|
|
|
boundsError(byteLength, 6, 'byteLength');
|
|
}
|
|
|
|
function readUInt48BE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 5];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 6);
|
|
|
|
return (first * 2 ** 8 + buf[++offset]) * 2 ** 32 +
|
|
buf[++offset] * 2 ** 24 +
|
|
buf[++offset] * 2 ** 16 +
|
|
buf[++offset] * 2 ** 8 +
|
|
last;
|
|
}
|
|
|
|
function readUInt40BE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 4];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 5);
|
|
|
|
return first * 2 ** 32 +
|
|
buf[++offset] * 2 ** 24 +
|
|
buf[++offset] * 2 ** 16 +
|
|
buf[++offset] * 2 ** 8 +
|
|
last;
|
|
}
|
|
|
|
function readUInt32BE(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 3];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 4);
|
|
|
|
return first * 2 ** 24 +
|
|
this[++offset] * 2 ** 16 +
|
|
this[++offset] * 2 ** 8 +
|
|
last;
|
|
}
|
|
|
|
function readUInt24BE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 2];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 3);
|
|
|
|
return first * 2 ** 16 + buf[++offset] * 2 ** 8 + last;
|
|
}
|
|
|
|
function readUInt16BE(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 1];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 2);
|
|
|
|
return first * 2 ** 8 + last;
|
|
}
|
|
|
|
function readIntLE(offset, byteLength) {
|
|
if (offset === undefined)
|
|
throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
|
|
if (byteLength === 6)
|
|
return readInt48LE(this, offset);
|
|
if (byteLength === 5)
|
|
return readInt40LE(this, offset);
|
|
if (byteLength === 3)
|
|
return readInt24LE(this, offset);
|
|
if (byteLength === 4)
|
|
return this.readInt32LE(offset);
|
|
if (byteLength === 2)
|
|
return this.readInt16LE(offset);
|
|
if (byteLength === 1)
|
|
return this.readInt8(offset);
|
|
|
|
boundsError(byteLength, 6, 'byteLength');
|
|
}
|
|
|
|
function readInt48LE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 5];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 6);
|
|
|
|
const val = buf[offset + 4] + last * 2 ** 8;
|
|
return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 +
|
|
first +
|
|
buf[++offset] * 2 ** 8 +
|
|
buf[++offset] * 2 ** 16 +
|
|
buf[++offset] * 2 ** 24;
|
|
}
|
|
|
|
function readInt40LE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 4];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 5);
|
|
|
|
return (last | (last & 2 ** 7) * 0x1fffffe) * 2 ** 32 +
|
|
first +
|
|
buf[++offset] * 2 ** 8 +
|
|
buf[++offset] * 2 ** 16 +
|
|
buf[++offset] * 2 ** 24;
|
|
}
|
|
|
|
function readInt32LE(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 3];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 4);
|
|
|
|
return first +
|
|
this[++offset] * 2 ** 8 +
|
|
this[++offset] * 2 ** 16 +
|
|
(last << 24); // Overflow
|
|
}
|
|
|
|
function readInt24LE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 2];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 3);
|
|
|
|
const val = first + buf[++offset] * 2 ** 8 + last * 2 ** 16;
|
|
return val | (val & 2 ** 23) * 0x1fe;
|
|
}
|
|
|
|
function readInt16LE(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 1];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 2);
|
|
|
|
const val = first + last * 2 ** 8;
|
|
return val | (val & 2 ** 15) * 0x1fffe;
|
|
}
|
|
|
|
function readInt8(offset = 0) {
|
|
checkNumberType(offset);
|
|
const val = this[offset];
|
|
if (val === undefined)
|
|
boundsError(offset, this.length - 1);
|
|
|
|
return val | (val & 2 ** 7) * 0x1fffffe;
|
|
}
|
|
|
|
function readIntBE(offset, byteLength) {
|
|
if (offset === undefined)
|
|
throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset);
|
|
if (byteLength === 6)
|
|
return readInt48BE(this, offset);
|
|
if (byteLength === 5)
|
|
return readInt40BE(this, offset);
|
|
if (byteLength === 3)
|
|
return readInt24BE(this, offset);
|
|
if (byteLength === 4)
|
|
return this.readInt32BE(offset);
|
|
if (byteLength === 2)
|
|
return this.readInt16BE(offset);
|
|
if (byteLength === 1)
|
|
return this.readInt8(offset);
|
|
|
|
boundsError(byteLength, 6, 'byteLength');
|
|
}
|
|
|
|
function readInt48BE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 5];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 6);
|
|
|
|
const val = buf[++offset] + first * 2 ** 8;
|
|
return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 +
|
|
buf[++offset] * 2 ** 24 +
|
|
buf[++offset] * 2 ** 16 +
|
|
buf[++offset] * 2 ** 8 +
|
|
last;
|
|
}
|
|
|
|
function readInt40BE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 4];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 5);
|
|
|
|
return (first | (first & 2 ** 7) * 0x1fffffe) * 2 ** 32 +
|
|
buf[++offset] * 2 ** 24 +
|
|
buf[++offset] * 2 ** 16 +
|
|
buf[++offset] * 2 ** 8 +
|
|
last;
|
|
}
|
|
|
|
function readInt32BE(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 3];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 4);
|
|
|
|
return (first << 24) + // Overflow
|
|
this[++offset] * 2 ** 16 +
|
|
this[++offset] * 2 ** 8 +
|
|
last;
|
|
}
|
|
|
|
function readInt24BE(buf, offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = buf[offset];
|
|
const last = buf[offset + 2];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, buf.length - 3);
|
|
|
|
const val = first * 2 ** 16 + buf[++offset] * 2 ** 8 + last;
|
|
return val | (val & 2 ** 23) * 0x1fe;
|
|
}
|
|
|
|
function readInt16BE(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 1];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 2);
|
|
|
|
const val = first * 2 ** 8 + last;
|
|
return val | (val & 2 ** 15) * 0x1fffe;
|
|
}
|
|
|
|
// Read floats
|
|
function readFloatBackwards(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 3];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 4);
|
|
|
|
uInt8Float32Array[3] = first;
|
|
uInt8Float32Array[2] = this[++offset];
|
|
uInt8Float32Array[1] = this[++offset];
|
|
uInt8Float32Array[0] = last;
|
|
return float32Array[0];
|
|
}
|
|
|
|
function readFloatForwards(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 3];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 4);
|
|
|
|
uInt8Float32Array[0] = first;
|
|
uInt8Float32Array[1] = this[++offset];
|
|
uInt8Float32Array[2] = this[++offset];
|
|
uInt8Float32Array[3] = last;
|
|
return float32Array[0];
|
|
}
|
|
|
|
function readDoubleBackwards(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 7];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 8);
|
|
|
|
uInt8Float64Array[7] = first;
|
|
uInt8Float64Array[6] = this[++offset];
|
|
uInt8Float64Array[5] = this[++offset];
|
|
uInt8Float64Array[4] = this[++offset];
|
|
uInt8Float64Array[3] = this[++offset];
|
|
uInt8Float64Array[2] = this[++offset];
|
|
uInt8Float64Array[1] = this[++offset];
|
|
uInt8Float64Array[0] = last;
|
|
return float64Array[0];
|
|
}
|
|
|
|
function readDoubleForwards(offset = 0) {
|
|
checkNumberType(offset);
|
|
const first = this[offset];
|
|
const last = this[offset + 7];
|
|
if (first === undefined || last === undefined)
|
|
boundsError(offset, this.length - 8);
|
|
|
|
uInt8Float64Array[0] = first;
|
|
uInt8Float64Array[1] = this[++offset];
|
|
uInt8Float64Array[2] = this[++offset];
|
|
uInt8Float64Array[3] = this[++offset];
|
|
uInt8Float64Array[4] = this[++offset];
|
|
uInt8Float64Array[5] = this[++offset];
|
|
uInt8Float64Array[6] = this[++offset];
|
|
uInt8Float64Array[7] = last;
|
|
return float64Array[0];
|
|
}
|
|
|
|
// Write integers.
|
|
function writeUIntLE(value, offset, byteLength) {
|
|
if (byteLength === 6)
|
|
return writeU_Int48LE(this, value, offset, 0, 0xffffffffffff);
|
|
if (byteLength === 5)
|
|
return writeU_Int40LE(this, value, offset, 0, 0xffffffffff);
|
|
if (byteLength === 3)
|
|
return writeU_Int24LE(this, value, offset, 0, 0xffffff);
|
|
if (byteLength === 4)
|
|
return writeU_Int32LE(this, value, offset, 0, 0xffffffff);
|
|
if (byteLength === 2)
|
|
return writeU_Int16LE(this, value, offset, 0, 0xffff);
|
|
if (byteLength === 1)
|
|
return writeU_Int8(this, value, offset, 0, 0xff);
|
|
|
|
boundsError(byteLength, 6, 'byteLength');
|
|
}
|
|
|
|
function writeU_Int48LE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 5);
|
|
|
|
const newVal = Math.floor(value * 2 ** -32);
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
buf[offset++] = newVal;
|
|
buf[offset++] = (newVal >>> 8);
|
|
return offset;
|
|
}
|
|
|
|
function writeU_Int40LE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 4);
|
|
|
|
const newVal = value;
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
buf[offset++] = Math.floor(newVal * 2 ** -32);
|
|
return offset;
|
|
}
|
|
|
|
function writeU_Int32LE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 3);
|
|
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
return offset;
|
|
}
|
|
|
|
function writeUInt32LE(value, offset = 0) {
|
|
return writeU_Int32LE(this, value, offset, 0, 0xffffffff);
|
|
}
|
|
|
|
function writeU_Int24LE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 2);
|
|
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
value = value >>> 8;
|
|
buf[offset++] = value;
|
|
return offset;
|
|
}
|
|
|
|
function writeU_Int16LE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 1);
|
|
|
|
buf[offset++] = value;
|
|
buf[offset++] = (value >>> 8);
|
|
return offset;
|
|
}
|
|
|
|
function writeUInt16LE(value, offset = 0) {
|
|
return writeU_Int16LE(this, value, offset, 0, 0xffff);
|
|
}
|
|
|
|
function writeU_Int8(buf, value, offset, min, max) {
|
|
value = +value;
|
|
// `checkInt()` can not be used here because it checks two entries.
|
|
checkNumberType(offset);
|
|
if (value > max || value < min) {
|
|
throw new ERR_OUT_OF_RANGE('value', `>= ${min} and <= ${max}`, value);
|
|
}
|
|
if (buf[offset] === undefined)
|
|
boundsError(offset, buf.length - 1);
|
|
|
|
buf[offset] = value;
|
|
return offset + 1;
|
|
}
|
|
|
|
function writeUInt8(value, offset = 0) {
|
|
return writeU_Int8(this, value, offset, 0, 0xff);
|
|
}
|
|
|
|
function writeUIntBE(value, offset, byteLength) {
|
|
if (byteLength === 6)
|
|
return writeU_Int48BE(this, value, offset, 0, 0xffffffffffffff);
|
|
if (byteLength === 5)
|
|
return writeU_Int40BE(this, value, offset, 0, 0xffffffffff);
|
|
if (byteLength === 3)
|
|
return writeU_Int24BE(this, value, offset, 0, 0xffffff);
|
|
if (byteLength === 4)
|
|
return writeU_Int32BE(this, value, offset, 0, 0xffffffff);
|
|
if (byteLength === 2)
|
|
return writeU_Int16BE(this, value, offset, 0, 0xffff);
|
|
if (byteLength === 1)
|
|
return writeU_Int8(this, value, offset, 0, 0xff);
|
|
|
|
boundsError(byteLength, 6, 'byteLength');
|
|
}
|
|
|
|
function writeU_Int48BE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 5);
|
|
|
|
const newVal = Math.floor(value * 2 ** -32);
|
|
buf[offset++] = (newVal >>> 8);
|
|
buf[offset++] = newVal;
|
|
buf[offset + 3] = value;
|
|
value = value >>> 8;
|
|
buf[offset + 2] = value;
|
|
value = value >>> 8;
|
|
buf[offset + 1] = value;
|
|
value = value >>> 8;
|
|
buf[offset] = value;
|
|
return offset + 4;
|
|
}
|
|
|
|
function writeU_Int40BE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 4);
|
|
|
|
buf[offset++] = Math.floor(value * 2 ** -32);
|
|
buf[offset + 3] = value;
|
|
value = value >>> 8;
|
|
buf[offset + 2] = value;
|
|
value = value >>> 8;
|
|
buf[offset + 1] = value;
|
|
value = value >>> 8;
|
|
buf[offset] = value;
|
|
return offset + 4;
|
|
}
|
|
|
|
function writeU_Int32BE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 3);
|
|
|
|
buf[offset + 3] = value;
|
|
value = value >>> 8;
|
|
buf[offset + 2] = value;
|
|
value = value >>> 8;
|
|
buf[offset + 1] = value;
|
|
value = value >>> 8;
|
|
buf[offset] = value;
|
|
return offset + 4;
|
|
}
|
|
|
|
function writeUInt32BE(value, offset = 0) {
|
|
return writeU_Int32BE(this, value, offset, 0, 0xffffffff);
|
|
}
|
|
|
|
function writeU_Int24BE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 2);
|
|
|
|
buf[offset + 2] = value;
|
|
value = value >>> 8;
|
|
buf[offset + 1] = value;
|
|
value = value >>> 8;
|
|
buf[offset] = value;
|
|
return offset + 3;
|
|
}
|
|
|
|
function writeU_Int16BE(buf, value, offset, min, max) {
|
|
value = +value;
|
|
checkInt(value, min, max, buf, offset, 1);
|
|
|
|
buf[offset++] = (value >>> 8);
|
|
buf[offset++] = value;
|
|
return offset;
|
|
}
|
|
|
|
function writeUInt16BE(value, offset = 0) {
|
|
return writeU_Int16BE(this, value, offset, 0, 0xffffffff);
|
|
}
|
|
|
|
function writeIntLE(value, offset, byteLength) {
|
|
if (byteLength === 6)
|
|
return writeU_Int48LE(this, value, offset, -0x800000000000, 0x7fffffffffff);
|
|
if (byteLength === 5)
|
|
return writeU_Int40LE(this, value, offset, -0x8000000000, 0x7fffffffff);
|
|
if (byteLength === 3)
|
|
return writeU_Int24LE(this, value, offset, -0x800000, 0x7fffff);
|
|
if (byteLength === 4)
|
|
return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff);
|
|
if (byteLength === 2)
|
|
return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff);
|
|
if (byteLength === 1)
|
|
return writeU_Int8(this, value, offset, -0x80, 0x7f);
|
|
|
|
boundsError(byteLength, 6, 'byteLength');
|
|
}
|
|
|
|
function writeInt32LE(value, offset = 0) {
|
|
return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff);
|
|
}
|
|
|
|
function writeInt16LE(value, offset = 0) {
|
|
return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff);
|
|
}
|
|
|
|
function writeInt8(value, offset = 0) {
|
|
return writeU_Int8(this, value, offset, -0x80, 0x7f);
|
|
}
|
|
|
|
function writeIntBE(value, offset, byteLength) {
|
|
if (byteLength === 6)
|
|
return writeU_Int48BE(this, value, offset, -0x800000000000, 0x7fffffffffff);
|
|
if (byteLength === 5)
|
|
return writeU_Int40BE(this, value, offset, -0x8000000000, 0x7fffffffff);
|
|
if (byteLength === 3)
|
|
return writeU_Int24BE(this, value, offset, -0x800000, 0x7fffff);
|
|
if (byteLength === 4)
|
|
return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff);
|
|
if (byteLength === 2)
|
|
return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff);
|
|
if (byteLength === 1)
|
|
return writeU_Int8(this, value, offset, -0x80, 0x7f);
|
|
|
|
boundsError(byteLength, 6, 'byteLength');
|
|
}
|
|
|
|
function writeInt32BE(value, offset = 0) {
|
|
return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff);
|
|
}
|
|
|
|
function writeInt16BE(value, offset = 0) {
|
|
return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff);
|
|
}
|
|
|
|
// Write floats.
|
|
function writeDoubleForwards(val, offset = 0) {
|
|
val = +val;
|
|
checkBounds(this, offset, 7);
|
|
|
|
float64Array[0] = val;
|
|
this[offset++] = uInt8Float64Array[0];
|
|
this[offset++] = uInt8Float64Array[1];
|
|
this[offset++] = uInt8Float64Array[2];
|
|
this[offset++] = uInt8Float64Array[3];
|
|
this[offset++] = uInt8Float64Array[4];
|
|
this[offset++] = uInt8Float64Array[5];
|
|
this[offset++] = uInt8Float64Array[6];
|
|
this[offset++] = uInt8Float64Array[7];
|
|
return offset;
|
|
}
|
|
|
|
function writeDoubleBackwards(val, offset = 0) {
|
|
val = +val;
|
|
checkBounds(this, offset, 7);
|
|
|
|
float64Array[0] = val;
|
|
this[offset++] = uInt8Float64Array[7];
|
|
this[offset++] = uInt8Float64Array[6];
|
|
this[offset++] = uInt8Float64Array[5];
|
|
this[offset++] = uInt8Float64Array[4];
|
|
this[offset++] = uInt8Float64Array[3];
|
|
this[offset++] = uInt8Float64Array[2];
|
|
this[offset++] = uInt8Float64Array[1];
|
|
this[offset++] = uInt8Float64Array[0];
|
|
return offset;
|
|
}
|
|
|
|
function writeFloatForwards(val, offset = 0) {
|
|
val = +val;
|
|
checkBounds(this, offset, 3);
|
|
|
|
float32Array[0] = val;
|
|
this[offset++] = uInt8Float32Array[0];
|
|
this[offset++] = uInt8Float32Array[1];
|
|
this[offset++] = uInt8Float32Array[2];
|
|
this[offset++] = uInt8Float32Array[3];
|
|
return offset;
|
|
}
|
|
|
|
function writeFloatBackwards(val, offset = 0) {
|
|
val = +val;
|
|
checkBounds(this, offset, 3);
|
|
|
|
float32Array[0] = val;
|
|
this[offset++] = uInt8Float32Array[3];
|
|
this[offset++] = uInt8Float32Array[2];
|
|
this[offset++] = uInt8Float32Array[1];
|
|
this[offset++] = uInt8Float32Array[0];
|
|
return offset;
|
|
}
|
|
|
|
// FastBuffer wil be inserted here by lib/buffer.js
|
|
module.exports = {
|
|
setupBufferJS,
|
|
// Container to export all read write functions.
|
|
readWrites: {
|
|
readUIntLE,
|
|
readUInt32LE,
|
|
readUInt16LE,
|
|
readUInt8,
|
|
readUIntBE,
|
|
readUInt32BE,
|
|
readUInt16BE,
|
|
readIntLE,
|
|
readInt32LE,
|
|
readInt16LE,
|
|
readInt8,
|
|
readIntBE,
|
|
readInt32BE,
|
|
readInt16BE,
|
|
writeUIntLE,
|
|
writeUInt32LE,
|
|
writeUInt16LE,
|
|
writeUInt8,
|
|
writeUIntBE,
|
|
writeUInt32BE,
|
|
writeUInt16BE,
|
|
writeIntLE,
|
|
writeInt32LE,
|
|
writeInt16LE,
|
|
writeInt8,
|
|
writeIntBE,
|
|
writeInt32BE,
|
|
writeInt16BE,
|
|
readFloatLE: bigEndian ? readFloatBackwards : readFloatForwards,
|
|
readFloatBE: bigEndian ? readFloatForwards : readFloatBackwards,
|
|
readDoubleLE: bigEndian ? readDoubleBackwards : readDoubleForwards,
|
|
readDoubleBE: bigEndian ? readDoubleForwards : readDoubleBackwards,
|
|
writeFloatLE: bigEndian ? writeFloatBackwards : writeFloatForwards,
|
|
writeFloatBE: bigEndian ? writeFloatForwards : writeFloatBackwards,
|
|
writeDoubleLE: bigEndian ? writeDoubleBackwards : writeDoubleForwards,
|
|
writeDoubleBE: bigEndian ? writeDoubleForwards : writeDoubleBackwards
|
|
}
|
|
};
|