Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
db24641
deps: upgrade npm to 6.13.6
ruyadorno Jan 10, 2020
7eac959
deps: upgrade npm to 6.13.7
Jan 28, 2020
2315270
test: try to stabalize test-child-process-fork-exec-path.js
refack Apr 17, 2019
a8fd8a1
test: mark http2 tests as flaky on 10.x
Feb 20, 2020
4b9a779
test: mark tests as flaky
joaocgreis Dec 8, 2019
f1a8791
test: allow EAI_FAIL in test-http-dns-error.js
cjihrig Apr 30, 2019
1cfb457
tls: support TLS min/max protocol defaults in CLI
sam-github May 28, 2019
64744a2
buffer: add {read|write}Big[U]Int64{BE|LE} methods
GaryGSC Nov 11, 2019
3f9cec3
test: add debugging output to test-net-listen-after-destroy-stdin
Trott Feb 8, 2020
20177b9
n-api: turn NAPI_CALL_INTO_MODULE into a function
addaleax Feb 15, 2019
f29fb14
n-api: add APIs for per-instance state management
Jul 15, 2019
dc61e09
v8: fix load elimination liveness checks
bnoordhuis Feb 1, 2020
9b2b66b
deps: V8: cherry-pick d89f4ef1cd62
Feb 12, 2020
5484e06
test: scale keepalive timeouts for slow machines
bnoordhuis Dec 7, 2019
42af3b8
build,win: fix goto exit in vcbuild
joaocgreis Dec 13, 2019
ffa9f9b
doc: fix changelog for v10.18.1
andrewhughes101 Jan 14, 2020
9bd1317
test: mark empty udp tests flaky on OS X
sam-github Feb 24, 2020
ecbb331
n-api: add napi_get_all_property_names
himself65 Oct 17, 2019
b53ce6e
deps: upgrade to libuv 1.29.1
cjihrig May 15, 2019
7cde563
deps: upgrade to libuv 1.30.0
cjihrig Jun 27, 2019
ed71f55
deps: upgrade to libuv 1.30.1
cjihrig Jul 2, 2019
794abbc
deps: upgrade to libuv 1.31.0
cjihrig Aug 9, 2019
aed7ca4
deps: upgrade to libuv 1.32.0
cjihrig Sep 9, 2019
6826ef0
deps: upgrade to libuv 1.33.1
cjihrig Oct 19, 2019
fff6162
deps: upgrade to libuv 1.34.0
cjihrig Dec 4, 2019
4b1cccc
deps: upgrade to libuv 1.34.1
cjihrig Jan 12, 2020
098704c
deps: upgrade to libuv 1.34.2
cjihrig Jan 23, 2020
61e2d48
tools: use CC instead of CXX when pointing to gcc
Dec 6, 2019
f235eea
tools: unify make-v8.sh for ppc64le and s390x
richardlau Feb 3, 2020
47046aa
deps: openssl: cherry-pick 4dcb150ea30f
AdamMajer Feb 28, 2020
b164a2e
console: add trace-events for time and count
jasnell Oct 16, 2018
05f5b3e
doc: remove em dashes
Trott Mar 4, 2020
a2b0e9e
tls: expose keylog event on TLSSocket
mildsunrise May 11, 2019
8cae4dd
deps: upgrade npm to 6.14.1
isaacs Feb 27, 2020
c2b3cf6
deps: update npm to 6.14.3
MylesBorins Mar 19, 2020
bf26c44
deps: remove *.pyc files from deps/npm
bnoordhuis Mar 20, 2020
c8f5ab2
deps: upgrade openssl sources to 1.1.1e
hassaanp Mar 17, 2020
64c1848
deps: adjust openssl configuration for 1.1.1e
hassaanp Mar 18, 2020
76033c5
deps: update archs files for OpenSSL-1.1.1e
hassaanp Mar 18, 2020
89692ff
test: end tls connection with some data
sam-github Mar 20, 2020
4390674
url: handle quasi-WHATWG URLs in urlToOptions()
cjihrig Feb 21, 2019
aa7d369
doc: update releaser list in README.md
MylesBorins Mar 31, 2020
8d85a43
deps: update term-size with signed version
rvagg Jan 30, 2020
04cd67f
deps: upgrade npm to 6.14.4
ruyadorno Mar 26, 2020
8a0ed8f
build: macOS package notarization
rvagg Jan 22, 2020
239377b
n-api: correct instance data tests
Mar 25, 2020
e9c590e
n-api: define release 6
Mar 3, 2020
34c1c2a
doc: add missing version metadata for Readable.from
addaleax Jul 15, 2019
2e3d511
doc: correct version metadata for Readable.from
kzar Apr 3, 2020
0177464
doc,tools: get altDocs versions from CHANGELOG.md
richardlau May 12, 2019
1ea70d6
test: fix flaky doctool and test
Trott Oct 15, 2019
ac1ea73
tools: make doctool work if no internet available
richardlau Nov 2, 2019
3756be8
tools: add NODE_TEST_NO_INTERNET to the doc builder
joyeecheung Feb 18, 2020
a175b8d
tools: only fetch previous versions when necessary
richardlau Mar 27, 2020
017909b
test: fix tool path in test-doctool-versions.js
richardlau Apr 3, 2020
246eede
2020-04-08, Version 10.20.0 'Dubnium' (LTS)
BethGriggs Feb 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
buffer: add {read|write}Big[U]Int64{BE|LE} methods
Backport-PR-URL: #30361
PR-URL: #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>
  • Loading branch information
GaryGSC authored and BethGriggs committed Feb 25, 2020
commit 64744a282e661a426d2092901bb7f4f02a0cb746
4 changes: 4 additions & 0 deletions benchmark/buffers/buffer-read.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
const common = require('../common.js');

const types = [
'BigUInt64LE',
'BigUInt64BE',
'BigInt64LE',
'BigInt64BE',
'UInt8',
'UInt16LE',
'UInt16BE',
Expand Down
21 changes: 21 additions & 0 deletions benchmark/buffers/buffer-write.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
const common = require('../common.js');

const types = [
'BigUInt64LE',
'BigUInt64BE',
'BigInt64LE',
'BigInt64BE',
'UInt8',
'UInt16LE',
'UInt16BE',
Expand Down Expand Up @@ -32,11 +36,17 @@ const INT8 = 0x7f;
const INT16 = 0x7fff;
const INT32 = 0x7fffffff;
const INT48 = 0x7fffffffffff;
const INT64 = 0x7fffffffffffffffn;
const UINT8 = 0xff;
const UINT16 = 0xffff;
const UINT32 = 0xffffffff;
const UINT64 = 0xffffffffffffffffn;

const mod = {
writeBigInt64BE: INT64,
writeBigInt64LE: INT64,
writeBigUInt64BE: UINT64,
writeBigUInt64LE: UINT64,
writeInt8: INT8,
writeInt16BE: INT16,
writeInt16LE: INT16,
Expand Down Expand Up @@ -67,12 +77,23 @@ function main({ n, buf, type }) {

if (!/\d/.test(fn))
benchSpecialInt(buff, fn, n);
else if (/BigU?Int/.test(fn))
benchBigInt(buff, fn, BigInt(n));
else if (/Int/.test(fn))
benchInt(buff, fn, n);
else
benchFloat(buff, fn, n);
}

function benchBigInt(buff, fn, n) {
const m = mod[fn];
bench.start();
for (var i = 0n; i !== n; i++) {
buff[fn](i & m, 0);
}
bench.end(Number(n));
}

function benchInt(buff, fn, n) {
const m = mod[fn];
bench.start();
Expand Down
91 changes: 91 additions & 0 deletions doc/api/buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,47 @@ 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}

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
Expand Down Expand Up @@ -2132,6 +2173,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);

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
Expand Down
146 changes: 146 additions & 0 deletions lib/internal/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,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 (byteLength === 6)
return readUInt48LE(this, offset);
Expand Down Expand Up @@ -454,6 +530,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 = 0, byteLength) {
if (byteLength === 6)
return writeU_Int48LE(this, value, offset, 0, 0xffffffffffff);
Expand Down Expand Up @@ -773,6 +911,14 @@ module.exports = {
setupBufferJS,
// Container to export all read write functions.
readWrites: {
readBigUInt64LE,
readBigUInt64BE,
readBigInt64LE,
readBigInt64BE,
writeBigUInt64LE,
writeBigUInt64BE,
writeBigInt64LE,
writeBigInt64BE,
readUIntLE,
readUInt32LE,
readUInt16LE,
Expand Down
51 changes: 51 additions & 0 deletions test/parallel/test-buffer-bigint64.js
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);
});