summaryrefslogtreecommitdiff
path: root/lib/internal/buffer.js
diff options
context:
space:
mode:
authorRuben Bridgewater <ruben@bridgewater.de>2018-01-30 17:34:25 +0100
committerRuben Bridgewater <ruben@bridgewater.de>2018-03-02 19:29:46 +0000
commite8bb1f35df079cf0111fc18a8a24ec0a2d66eb3e (patch)
tree635c3c8e56a123fb45ab1f3136739aade631ba9c /lib/internal/buffer.js
parenta6c490cc8e8c848d6c4d5b8739827198055fe40f (diff)
downloadandroid-node-v8-e8bb1f35df079cf0111fc18a8a24ec0a2d66eb3e.tar.gz
android-node-v8-e8bb1f35df079cf0111fc18a8a24ec0a2d66eb3e.tar.bz2
android-node-v8-e8bb1f35df079cf0111fc18a8a24ec0a2d66eb3e.zip
buffer: refactor all read/write functions
There are a lot of changes in this commit: 1) Remove the `noAssert` argument from all read and write functions. 2) Improve the performance of all read floating point functions significantly. This is done by switching to TypedArrays as the write floating point write functions. 3) No implicit type coercion for offset and byteLength anymore. 4) Adds a lot of tests. 5) Moves the read and write functions to the internal buffer file to split the files in smaller chunks. 6) Reworked a lot of existing tests. 7) Improve the performane of all all read write functions by using a faster input validation and by improving function logic. 8) Significantly improved the performance of all read int functions. This is done by using a implementation without a loop. 9) Improved error handling. 10) Rename test file to use the correct subsystem. PR-URL: https://github.com/nodejs/node/pull/18395 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'lib/internal/buffer.js')
-rw-r--r--lib/internal/buffer.js786
1 files changed, 785 insertions, 1 deletions
diff --git a/lib/internal/buffer.js b/lib/internal/buffer.js
index 105ff4132a..b5da69a5b3 100644
--- a/lib/internal/buffer.js
+++ b/lib/internal/buffer.js
@@ -1,13 +1,797 @@
'use strict';
const binding = process.binding('buffer');
+const { TypeError, RangeError } = require('internal/errors');
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;
+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 RangeError('ERR_OUT_OF_RANGE',
+ 'value', `>= ${min} and <= ${max}`, value);
+ }
+ checkBounds(buf, offset, byteLength);
+}
+
+function checkNumberType(value, type) {
+ if (typeof value !== 'number') {
+ throw new TypeError('ERR_INVALID_ARG_TYPE',
+ type || 'offset', 'number', value);
+ }
+}
+
+function boundsError(value, length, type) {
+ if (Math.floor(value) !== value) {
+ checkNumberType(value, type);
+ throw new RangeError('ERR_OUT_OF_RANGE',
+ type || 'offset', 'an integer', value);
+ }
+
+ if (length < 0)
+ throw new RangeError('ERR_BUFFER_OUT_OF_BOUNDS', null, true);
+
+ throw new RangeError('ERR_OUT_OF_RANGE',
+ type || 'offset',
+ `>= ${type ? 1 : 0} and <= ${length}`,
+ value);
+}
+
+// Read integers.
+function readUIntLE(offset, byteLength) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ checkNumberType(offset);
+ const val = this[offset];
+ if (val === undefined)
+ boundsError(offset, this.length - 1);
+
+ return val;
+}
+
+function readUIntBE(offset, byteLength) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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 (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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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 (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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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;
+ buf[offset++] = (value >>> 8);
+ buf[offset++] = (value >>> 16);
+ buf[offset++] = (value >>> 24);
+ 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;
+ buf[offset++] = (value >>> 8);
+ buf[offset++] = (value >>> 16);
+ buf[offset++] = (value >>> 24);
+ 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;
+ buf[offset++] = (value >>> 8);
+ buf[offset++] = (value >>> 16);
+ buf[offset++] = (value >>> 24);
+ return offset;
+}
+
+function writeUInt32LE(value, offset) {
+ 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;
+ buf[offset++] = (value >>> 8);
+ buf[offset++] = (value >>> 16);
+ 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) {
+ 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 RangeError('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) {
+ 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++] = (value >>> 24);
+ buf[offset++] = (value >>> 16);
+ buf[offset++] = (value >>> 8);
+ buf[offset++] = value;
+ return offset;
+}
+
+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++] = (value >>> 24);
+ buf[offset++] = (value >>> 16);
+ buf[offset++] = (value >>> 8);
+ buf[offset++] = value;
+ return offset;
+}
+
+function writeU_Int32BE(buf, value, offset, min, max) {
+ value = +value;
+ checkInt(value, min, max, buf, offset, 3);
+
+ buf[offset++] = (value >>> 24);
+ buf[offset++] = (value >>> 16);
+ buf[offset++] = (value >>> 8);
+ buf[offset++] = value;
+ return offset;
+}
+
+function writeUInt32BE(value, offset) {
+ 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++] = (value >>> 16);
+ buf[offset++] = (value >>> 8);
+ buf[offset++] = value;
+ return offset;
+}
+
+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) {
+ 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) {
+ return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff);
+}
+
+function writeInt16LE(value, offset) {
+ return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff);
+}
+
+function writeInt8(value, offset) {
+ 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) {
+ return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff);
+}
+
+function writeInt16BE(value, offset) {
+ return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff);
+}
+
+// Write floats.
+function writeDoubleForwards(val, offset) {
+ 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) {
+ 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) {
+ 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) {
+ 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
+ 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
+ }
};