diff options
author | Nikolai Vavilov <vvnicholas@gmail.com> | 2018-06-03 20:30:46 +0300 |
---|---|---|
committer | Matteo Collina <hello@matteocollina.com> | 2019-04-06 20:30:23 +0300 |
commit | 3d8532f851f2f7a2f8380e717281eaa08b02fb35 (patch) | |
tree | 8f6ea826d41b62754b230cb9190fa37ca83c7036 /lib/internal/buffer.js | |
parent | dd89a1182f0f6acfa46d79fbecf65aad9def9a28 (diff) |
buffer: add {read|write}Big[U]Int64{BE|LE} methods
PR-URL: https://github.com/nodejs/node/pull/19691
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'lib/internal/buffer.js')
-rw-r--r-- | lib/internal/buffer.js | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/lib/internal/buffer.js b/lib/internal/buffer.js index 64c026002cc..9a70dd4c89e 100644 --- a/lib/internal/buffer.js +++ b/lib/internal/buffer.js @@ -63,6 +63,82 @@ function boundsError(value, length, type) { } // Read integers. +function readBigUInt64LE(offset = 0) { + validateNumber(offset, 'offset'); + const first = this[offset]; + const last = this[offset + 7]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 8); + + const lo = first + + this[++offset] * 2 ** 8 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 24; + + const hi = this[++offset] + + this[++offset] * 2 ** 8 + + this[++offset] * 2 ** 16 + + last * 2 ** 24; + + return BigInt(lo) + (BigInt(hi) << 32n); +} + +function readBigUInt64BE(offset = 0) { + validateNumber(offset, 'offset'); + const first = this[offset]; + const last = this[offset + 7]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 8); + + const hi = first * 2 ** 24 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + this[++offset]; + + const lo = this[++offset] * 2 ** 24 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + last; + + return (BigInt(hi) << 32n) + BigInt(lo); +} + +function readBigInt64LE(offset = 0) { + validateNumber(offset, 'offset'); + const first = this[offset]; + const last = this[offset + 7]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 8); + + const val = this[offset + 4] + + this[offset + 5] * 2 ** 8 + + this[offset + 6] * 2 ** 16 + + (last << 24); // Overflow + return (BigInt(val) << 32n) + + BigInt(first + + this[++offset] * 2 ** 8 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 24); +} + +function readBigInt64BE(offset = 0) { + validateNumber(offset, 'offset'); + const first = this[offset]; + const last = this[offset + 7]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 8); + + const val = (first << 24) + // Overflow + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + this[++offset]; + return (BigInt(val) << 32n) + + BigInt(this[++offset] * 2 ** 24 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + last); +} + function readUIntLE(offset, byteLength) { if (offset === undefined) throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset); @@ -473,6 +549,68 @@ function readDoubleForwards(offset = 0) { } // Write integers. +function writeBigU_Int64LE(buf, value, offset, min, max) { + checkInt(value, min, max, buf, offset, 7); + + let lo = Number(value & 0xffffffffn); + buf[offset++] = lo; + lo = lo >> 8; + buf[offset++] = lo; + lo = lo >> 8; + buf[offset++] = lo; + lo = lo >> 8; + buf[offset++] = lo; + let hi = Number(value >> 32n & 0xffffffffn); + buf[offset++] = hi; + hi = hi >> 8; + buf[offset++] = hi; + hi = hi >> 8; + buf[offset++] = hi; + hi = hi >> 8; + buf[offset++] = hi; + return offset; +} + +function writeBigUInt64LE(value, offset = 0) { + return writeBigU_Int64LE(this, value, offset, 0n, 0xffffffffffffffffn); +} + +function writeBigU_Int64BE(buf, value, offset, min, max) { + checkInt(value, min, max, buf, offset, 7); + + let lo = Number(value & 0xffffffffn); + buf[offset + 7] = lo; + lo = lo >> 8; + buf[offset + 6] = lo; + lo = lo >> 8; + buf[offset + 5] = lo; + lo = lo >> 8; + buf[offset + 4] = lo; + let hi = Number(value >> 32n & 0xffffffffn); + buf[offset + 3] = hi; + hi = hi >> 8; + buf[offset + 2] = hi; + hi = hi >> 8; + buf[offset + 1] = hi; + hi = hi >> 8; + buf[offset] = hi; + return offset + 8; +} + +function writeBigUInt64BE(value, offset = 0) { + return writeBigU_Int64BE(this, value, offset, 0n, 0xffffffffffffffffn); +} + +function writeBigInt64LE(value, offset = 0) { + return writeBigU_Int64LE( + this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn); +} + +function writeBigInt64BE(value, offset = 0) { + return writeBigU_Int64BE( + this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn); +} + function writeUIntLE(value, offset, byteLength) { if (byteLength === 6) return writeU_Int48LE(this, value, offset, 0, 0xffffffffffff); @@ -790,6 +928,15 @@ function writeFloatBackwards(val, offset = 0) { class FastBuffer extends Uint8Array {} function addBufferPrototypeMethods(proto) { + proto.readBigUInt64LE = readBigUInt64LE, + proto.readBigUInt64BE = readBigUInt64BE, + proto.readBigInt64LE = readBigInt64LE, + proto.readBigInt64BE = readBigInt64BE, + proto.writeBigUInt64LE = writeBigUInt64LE, + proto.writeBigUInt64BE = writeBigUInt64BE, + proto.writeBigInt64LE = writeBigInt64LE, + proto.writeBigInt64BE = writeBigInt64BE, + proto.readUIntLE = readUIntLE; proto.readUInt32LE = readUInt32LE; proto.readUInt16LE = readUInt16LE; |