-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
buffer: add {read|write}Big[U]Int64{BE|LE} methods #19691
Changes from all commits
ef3b353
b9249a4
47336f3
a914000
702c05e
cc53f0a
aaa6ee5
439f890
a36ac44
173f7cf
86135a2
f50b156
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -1546,6 +1546,46 @@ deprecated: v8.0.0 | |||
|
||||
The `buf.parent` property is a deprecated alias for `buf.buffer`. | ||||
|
||||
### buf.readBigInt64BE([offset]) | ||||
### buf.readBigInt64LE([offset]) | ||||
<!-- YAML | ||||
added: REPLACEME | ||||
--> | ||||
|
||||
* `offset` {integer} Number of bytes to skip before starting to read. Must | ||||
satisfy: `0 <= offset <= buf.length - 8`. **Default:** `0`. | ||||
* Returns: {bigint} | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems MDN have not a BigInt doc yet, but maybe we can add a link to spec or proposal in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's put it off for now. Maybe it will be on MDN when it's time to land. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still not on MDN. What do others think about adding a link to the proposal? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would link to the proposal There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already have a precedent: Line 32 in cd8f06f
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good find. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in #27101 |
||||
|
||||
Reads a signed 64-bit integer from `buf` at the specified `offset` with | ||||
the specified endian format (`readBigInt64BE()` returns big endian, | ||||
`readBigInt64LE()` returns little endian). | ||||
|
||||
Integers read from a `Buffer` are interpreted as two's complement signed values. | ||||
|
||||
### buf.readBigUInt64BE([offset]) | ||||
### buf.readBigUInt64LE([offset]) | ||||
<!-- YAML | ||||
added: REPLACEME | ||||
--> | ||||
|
||||
* `offset` {integer} Number of bytes to skip before starting to read. Must | ||||
satisfy: `0 <= offset <= buf.length - 8`. **Default:** `0`. | ||||
* Returns: {bigint} | ||||
|
||||
Reads an unsigned 64-bit integer from `buf` at the specified `offset` with | ||||
specified endian format (`readBigUInt64BE()` returns big endian, | ||||
`readBigUInt64LE()` returns little endian). | ||||
|
||||
```js | ||||
const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]); | ||||
|
||||
console.log(buf.readBigUInt64BE(0)); | ||||
// Prints: 4294967295n | ||||
|
||||
console.log(buf.readBigUInt64LE(0)); | ||||
// Prints: 18446744069414584320n | ||||
``` | ||||
|
||||
### buf.readDoubleBE([offset]) | ||||
### buf.readDoubleLE([offset]) | ||||
<!-- YAML | ||||
|
@@ -2149,6 +2189,56 @@ console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); | |||
// Prints: 12 bytes: ½ + ¼ = ¾ | ||||
``` | ||||
|
||||
### buf.writeBigInt64BE(value[, offset]) | ||||
### buf.writeBigInt64LE(value[, offset]) | ||||
<!-- YAML | ||||
added: REPLACEME | ||||
--> | ||||
|
||||
* `value` {bigint} Number to be written to `buf`. | ||||
* `offset` {integer} Number of bytes to skip before starting to write. Must | ||||
satisfy: `0 <= offset <= buf.length - 8`. **Default:** `0`. | ||||
* Returns: {integer} `offset` plus the number of bytes written. | ||||
|
||||
Writes `value` to `buf` at the specified `offset` with specified endian | ||||
format (`writeBigInt64BE()` writes big endian, `writeBigInt64LE()` writes little | ||||
endian). | ||||
|
||||
`value` is interpreted and written as a two's complement signed integer. | ||||
|
||||
```js | ||||
const buf = Buffer.allocUnsafe(8); | ||||
BridgeAR marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
|
||||
buf.writeBigInt64BE(0x0102030405060708n, 0); | ||||
|
||||
console.log(buf); | ||||
// Prints: <Buffer 01 02 03 04 05 06 07 08> | ||||
``` | ||||
|
||||
### buf.writeBigUInt64BE(value[, offset]) | ||||
### buf.writeBigUInt64LE(value[, offset]) | ||||
<!-- YAML | ||||
added: REPLACEME | ||||
--> | ||||
|
||||
* `value` {bigint} Number to be written to `buf`. | ||||
* `offset` {integer} Number of bytes to skip before starting to write. Must | ||||
satisfy: `0 <= offset <= buf.length - 8`. **Default:** `0`. | ||||
* Returns: {integer} `offset` plus the number of bytes written. | ||||
|
||||
Writes `value` to `buf` at the specified `offset` with specified endian | ||||
format (`writeBigUInt64BE()` writes big endian, `writeBigUInt64LE()` writes | ||||
little endian). | ||||
|
||||
```js | ||||
const buf = Buffer.allocUnsafe(8); | ||||
|
||||
buf.writeBigUInt64LE(0xdecafafecacefaden, 0); | ||||
|
||||
console.log(buf); | ||||
// Prints: <Buffer de fa ce ca fe fa ca de> | ||||
``` | ||||
|
||||
### buf.writeDoubleBE(value[, offset]) | ||||
### buf.writeDoubleLE(value[, offset]) | ||||
<!-- YAML | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
'use strict'; | ||
require('../common'); | ||
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); | ||
}, RangeError); | ||
|
||
// 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); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's minor, but I had trouble choosing between the following options:
n
andi
are Numbers, converti
to BigInt in the call (BigInt(i) & m
).n
is Number,i
is BigInt, use!=
in the loop.n
andi
are BigInts, convert to Number beforebench.end()
call.It's now using option 3, but I'm not sure it's the best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine to me. You could do
const nn = Number(n)
beforebench.start()
if you're worried about the coercion influencing the benchmark numbers.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's already converted to BigInt in
main()
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean the coercion in
bench.end(Number(n))
.