this[offset + 3])
}
+Buffer.prototype.readBigUInt64LE = defineBigIntMethod(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)
+})
+
+Buffer.prototype.readBigUInt64BE = defineBigIntMethod(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)
+})
+
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
offset = offset >>> 0
byteLength = byteLength >>> 0
(this[offset + 3])
}
+Buffer.prototype.readBigInt64LE = defineBigIntMethod(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)
+})
+
+Buffer.prototype.readBigInt64BE = defineBigIntMethod(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)
+})
+
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
offset = offset >>> 0
if (!noAssert) checkOffset(offset, 4, this.length)
return offset + 4
}
+function wrtBigUInt64LE (buf, value, offset, min, max) {
+ checkIntBI(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 wrtBigUInt64BE (buf, value, offset, min, max) {
+ checkIntBI(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
+}
+
+Buffer.prototype.writeBigUInt64LE = defineBigIntMethod(function writeBigUInt64LE (value, offset = 0) {
+ return wrtBigUInt64LE(this, value, offset, 0n, 0xffffffffffffffffn)
+})
+
+Buffer.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE (value, offset = 0) {
+ return wrtBigUInt64BE(this, value, offset, 0n, 0xffffffffffffffffn)
+})
+
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset >>> 0
return offset + 4
}
+Buffer.prototype.writeBigInt64LE = defineBigIntMethod(function writeBigInt64LE (value, offset = 0) {
+ return wrtBigUInt64LE(this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn)
+})
+
+Buffer.prototype.writeBigInt64BE = defineBigIntMethod(function writeBigInt64BE (value, offset = 0) {
+ return wrtBigUInt64BE(this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn)
+})
+
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (offset + ext > buf.length) throw new RangeError('Index out of range')
if (offset < 0) throw new RangeError('Index out of range')
return this
}
+// CUSTOM ERRORS
+// =============
+
+// Simplified versions from Node, changed for Buffer-only usage
+var errors = {}
+function E (sym, getMessage, Base) {
+ errors[sym] = class NodeError extends Base {
+ constructor () {
+ super()
+
+ Object.defineProperty(this, 'message', {
+ value: getMessage.apply(this, arguments),
+ writable: true,
+ configurable: true
+ })
+
+ // Add the error code to the name to include it in the stack trace.
+ this.name = `${this.name} [${sym}]`
+ // Access the stack to generate the error message including the error code
+ // from the name.
+ this.stack // eslint-disable-line no-unused-expressions
+ // Reset the name to the actual name.
+ delete this.name
+ }
+
+ get code () {
+ return sym
+ }
+
+ set code (value) {
+ Object.defineProperty(this, 'code', {
+ configurable: true,
+ enumerable: true,
+ value,
+ writable: true
+ })
+ }
+
+ toString () {
+ return `${this.name} [${sym}]: ${this.message}`
+ }
+ }
+}
+
+E('ERR_BUFFER_OUT_OF_BOUNDS',
+ function (name) {
+ if (name) {
+ return `${name} is outside of buffer bounds`
+ }
+
+ return 'Attempt to access memory outside buffer bounds'
+ }, RangeError)
+E('ERR_INVALID_ARG_TYPE',
+ function (name, actual) {
+ return `The "${name}" argument must be of type number. Received type ${typeof actual}`
+ }, TypeError)
+E('ERR_OUT_OF_RANGE',
+ function (str, range, input) {
+ let msg = `The value of "${str}" is out of range.`
+ let received = input
+ if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) {
+ received = addNumericalSeparator(String(input))
+ } else if (typeof input === 'bigint') {
+ received = String(input)
+ if (input > 2n ** 32n || input < -(2n ** 32n)) {
+ received = addNumericalSeparator(received)
+ }
+ received += 'n'
+ }
+ msg += ` It must be ${range}. Received ${received}`
+ return msg
+ }, RangeError)
+
+function addNumericalSeparator (val) {
+ let res = ''
+ let i = val.length
+ const start = val[0] === '-' ? 1 : 0
+ for (; i >= start + 4; i -= 3) {
+ res = `_${val.slice(i - 3, i)}${res}`
+ }
+ return `${val.slice(0, i)}${res}`
+}
+
+// CHECK FUNCTIONS
+// ===============
+
+function checkBounds (buf, offset, byteLength) {
+ validateNumber(offset, 'offset')
+ if (buf[offset] === undefined || buf[offset + byteLength] === undefined) {
+ boundsError(offset, buf.length - (byteLength + 1))
+ }
+}
+
+function checkIntBI (value, min, max, buf, offset, byteLength) {
+ if (value > max || value < min) {
+ const n = typeof min === 'bigint' ? 'n' : ''
+ let range
+ if (byteLength > 3) {
+ if (min === 0 || min === 0n) {
+ range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}`
+ } else {
+ range = `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and < 2 ** ` +
+ `${(byteLength + 1) * 8 - 1}${n}`
+ }
+ } else {
+ range = `>= ${min}${n} and <= ${max}${n}`
+ }
+ throw new errors.ERR_OUT_OF_RANGE('value', range, value)
+ }
+ checkBounds(buf, offset, byteLength)
+}
+
+function validateNumber (value, name) {
+ if (typeof value !== 'number') {
+ throw new errors.ERR_INVALID_ARG_TYPE(name, 'number', value)
+ }
+}
+
+function boundsError (value, length, type) {
+ if (Math.floor(value) !== value) {
+ validateNumber(value, type)
+ throw new errors.ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value)
+ }
+
+ if (length < 0) {
+ throw new errors.ERR_BUFFER_OUT_OF_BOUNDS()
+ }
+
+ throw new errors.ERR_OUT_OF_RANGE(type || 'offset',
+ `>= ${type ? 1 : 0} and <= ${length}`,
+ value)
+}
+
// HELPER FUNCTIONS
// ================
}
return table
})()
+
+// Return not function with Error if BigInt not supported
+function defineBigIntMethod (fn) {
+ return typeof BigInt === 'undefined' ? BufferBigIntNotDefined : fn
+}
+
+function BufferBigIntNotDefined () {
+ throw new Error('BigInt not supported')
+}
--- /dev/null
+'use strict'
+var Buffer = require('../../').Buffer
+const assert = require('assert')
+
+const buf = Buffer.allocUnsafe(8)
+
+;['LE', 'BE'].forEach(function(endianness) {
+ // Should allow simple BigInts to be written and read
+ let val = 123456789n
+ buf['writeBigInt64' + endianness](val, 0)
+ let rtn = buf['readBigInt64' + endianness](0)
+ assert.strictEqual(val, rtn)
+
+ // Should allow INT64_MAX to be written and read
+ val = 0x7fffffffffffffffn
+ buf['writeBigInt64' + endianness](val, 0)
+ rtn = buf['readBigInt64' + endianness](0)
+ assert.strictEqual(val, rtn)
+
+ // Should read and write a negative signed 64-bit integer
+ val = -123456789n
+ buf['writeBigInt64' + endianness](val, 0)
+ assert.strictEqual(val, buf['readBigInt64' + endianness](0))
+
+ // Should read and write an unsigned 64-bit integer
+ val = 123456789n
+ buf['writeBigUInt64' + endianness](val, 0)
+ assert.strictEqual(val, buf['readBigUInt64' + endianness](0))
+
+ // Should throw a RangeError upon INT64_MAX+1 being written
+ assert.throws(function() {
+ const val = 0x8000000000000000n
+ buf['writeBigInt64' + endianness](val, 0)
+ }, RangeError)
+
+ // Should throw a RangeError upon UINT64_MAX+1 being written
+ assert.throws(function() {
+ const val = 0x10000000000000000n
+ buf['writeBigUInt64' + endianness](val, 0)
+ }, {
+ code: 'ERR_OUT_OF_RANGE',
+ message: 'The value of "value" is out of range. It must be ' +
+ '>= 0n and < 2n ** 64n. Received 18_446_744_073_709_551_616n'
+ })
+
+ // Should throw a TypeError upon invalid input
+ assert.throws(function() {
+ buf['writeBigInt64' + endianness]('bad', 0)
+ }, TypeError)
+
+ // Should throw a TypeError upon invalid input
+ assert.throws(function() {
+ buf['writeBigUInt64' + endianness]('bad', 0)
+ }, TypeError)
+})