mirror of
https://github.com/nodejs/node.git
synced 2025-04-30 23:56:58 +00:00

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>
236 lines
6.5 KiB
JavaScript
236 lines
6.5 KiB
JavaScript
'use strict';
|
|
|
|
// Tests to verify signed integers are correctly written
|
|
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const errorOutOfBounds = common.expectsError({
|
|
code: 'ERR_OUT_OF_RANGE',
|
|
type: RangeError,
|
|
message: new RegExp('^The value of "value" is out of range\\. ' +
|
|
'It must be >= -\\d+ and <= \\d+\\. Received .+$')
|
|
}, 10);
|
|
|
|
// Test 8 bit
|
|
{
|
|
const buffer = Buffer.alloc(2);
|
|
|
|
buffer.writeInt8(0x23, 0);
|
|
buffer.writeInt8(-5, 1);
|
|
assert.ok(buffer.equals(new Uint8Array([ 0x23, 0xfb ])));
|
|
|
|
/* Make sure we handle min/max correctly */
|
|
buffer.writeInt8(0x7f, 0);
|
|
buffer.writeInt8(-0x80, 1);
|
|
assert.ok(buffer.equals(new Uint8Array([ 0x7f, 0x80 ])));
|
|
|
|
assert.throws(() => {
|
|
buffer.writeInt8(0x7f + 1, 0);
|
|
}, errorOutOfBounds);
|
|
assert.throws(() => {
|
|
buffer.writeInt8(-0x80 - 1, 0);
|
|
}, errorOutOfBounds);
|
|
|
|
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
|
|
assert.throws(
|
|
() => buffer.writeInt8(23, off),
|
|
{ code: 'ERR_INVALID_ARG_TYPE' });
|
|
});
|
|
|
|
[NaN, Infinity, -1, 1.01].forEach((off) => {
|
|
assert.throws(
|
|
() => buffer.writeInt8(23, off),
|
|
{ code: 'ERR_OUT_OF_RANGE' });
|
|
});
|
|
}
|
|
|
|
// Test 16 bit
|
|
{
|
|
const buffer = Buffer.alloc(4);
|
|
|
|
buffer.writeInt16BE(0x0023, 0);
|
|
buffer.writeInt16LE(0x0023, 2);
|
|
assert.ok(buffer.equals(new Uint8Array([ 0x00, 0x23, 0x23, 0x00 ])));
|
|
|
|
buffer.writeInt16BE(-5, 0);
|
|
buffer.writeInt16LE(-5, 2);
|
|
assert.ok(buffer.equals(new Uint8Array([ 0xff, 0xfb, 0xfb, 0xff ])));
|
|
|
|
buffer.writeInt16BE(-1679, 0);
|
|
buffer.writeInt16LE(-1679, 2);
|
|
assert.ok(buffer.equals(new Uint8Array([ 0xf9, 0x71, 0x71, 0xf9 ])));
|
|
|
|
/* Make sure we handle min/max correctly */
|
|
buffer.writeInt16BE(0x7fff, 0);
|
|
buffer.writeInt16BE(-0x8000, 2);
|
|
assert.ok(buffer.equals(new Uint8Array([ 0x7f, 0xff, 0x80, 0x00 ])));
|
|
|
|
buffer.writeInt16LE(0x7fff, 0);
|
|
buffer.writeInt16LE(-0x8000, 2);
|
|
assert.ok(buffer.equals(new Uint8Array([ 0xff, 0x7f, 0x00, 0x80 ])));
|
|
|
|
['writeInt16BE', 'writeInt16LE'].forEach((fn) => {
|
|
assert.throws(() => {
|
|
buffer[fn](0x7fff + 1, 0);
|
|
}, errorOutOfBounds);
|
|
assert.throws(() => {
|
|
buffer[fn](-0x8000 - 1, 0);
|
|
}, errorOutOfBounds);
|
|
|
|
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
|
|
assert.throws(
|
|
() => buffer[fn](23, off),
|
|
{ code: 'ERR_INVALID_ARG_TYPE' });
|
|
});
|
|
|
|
[NaN, Infinity, -1, 1.01].forEach((off) => {
|
|
assert.throws(
|
|
() => buffer[fn](23, off),
|
|
{ code: 'ERR_OUT_OF_RANGE' });
|
|
});
|
|
});
|
|
}
|
|
|
|
// Test 32 bit
|
|
{
|
|
const buffer = Buffer.alloc(8);
|
|
|
|
buffer.writeInt32BE(0x23, 0);
|
|
buffer.writeInt32LE(0x23, 4);
|
|
assert.ok(buffer.equals(new Uint8Array([
|
|
0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00
|
|
])));
|
|
|
|
buffer.writeInt32BE(-5, 0);
|
|
buffer.writeInt32LE(-5, 4);
|
|
assert.ok(buffer.equals(new Uint8Array([
|
|
0xff, 0xff, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xff
|
|
])));
|
|
|
|
buffer.writeInt32BE(-805306713, 0);
|
|
buffer.writeInt32LE(-805306713, 4);
|
|
assert.ok(buffer.equals(new Uint8Array([
|
|
0xcf, 0xff, 0xfe, 0xa7, 0xa7, 0xfe, 0xff, 0xcf
|
|
])));
|
|
|
|
/* Make sure we handle min/max correctly */
|
|
buffer.writeInt32BE(0x7fffffff, 0);
|
|
buffer.writeInt32BE(-0x80000000, 4);
|
|
assert.ok(buffer.equals(new Uint8Array([
|
|
0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00
|
|
])));
|
|
|
|
buffer.writeInt32LE(0x7fffffff, 0);
|
|
buffer.writeInt32LE(-0x80000000, 4);
|
|
assert.ok(buffer.equals(new Uint8Array([
|
|
0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80
|
|
])));
|
|
|
|
['writeInt32BE', 'writeInt32LE'].forEach((fn) => {
|
|
assert.throws(() => {
|
|
buffer[fn](0x7fffffff + 1, 0);
|
|
}, errorOutOfBounds);
|
|
assert.throws(() => {
|
|
buffer[fn](-0x80000000 - 1, 0);
|
|
}, errorOutOfBounds);
|
|
|
|
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
|
|
assert.throws(
|
|
() => buffer[fn](23, off),
|
|
{ code: 'ERR_INVALID_ARG_TYPE' });
|
|
});
|
|
|
|
[NaN, Infinity, -1, 1.01].forEach((off) => {
|
|
assert.throws(
|
|
() => buffer[fn](23, off),
|
|
{ code: 'ERR_OUT_OF_RANGE' });
|
|
});
|
|
});
|
|
}
|
|
|
|
// Test Int
|
|
{
|
|
const data = Buffer.alloc(8);
|
|
|
|
// Check byteLength.
|
|
['writeIntBE', 'writeIntLE'].forEach((fn) => {
|
|
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
|
|
assert.throws(
|
|
() => data[fn](23, 0, o),
|
|
{ code: 'ERR_INVALID_ARG_TYPE' });
|
|
});
|
|
|
|
[Infinity, -1].forEach((offset) => {
|
|
assert.throws(
|
|
() => data[fn](23, 0, offset),
|
|
{
|
|
code: 'ERR_OUT_OF_RANGE',
|
|
message: 'The value of "byteLength" is out of range. ' +
|
|
`It must be >= 1 and <= 6. Received ${offset}`
|
|
}
|
|
);
|
|
});
|
|
|
|
[NaN, 1.01].forEach((byteLength) => {
|
|
assert.throws(
|
|
() => data[fn](42, 0, byteLength),
|
|
{
|
|
code: 'ERR_OUT_OF_RANGE',
|
|
name: 'RangeError [ERR_OUT_OF_RANGE]',
|
|
message: 'The value of "byteLength" is out of range. ' +
|
|
`It must be an integer. Received ${byteLength}`
|
|
});
|
|
});
|
|
});
|
|
|
|
// Test 1 to 6 bytes.
|
|
for (let i = 1; i < 6; i++) {
|
|
['writeIntBE', 'writeIntLE'].forEach((fn) => {
|
|
const min = -(2 ** (i * 8 - 1));
|
|
const max = 2 ** (i * 8 - 1) - 1;
|
|
|
|
[min - 1, max + 1].forEach((val) => {
|
|
assert.throws(() => {
|
|
data[fn](val, 0, i);
|
|
}, {
|
|
code: 'ERR_OUT_OF_RANGE',
|
|
name: 'RangeError [ERR_OUT_OF_RANGE]',
|
|
message: 'The value of "value" is out of range. ' +
|
|
`It must be >= ${min} and <= ${max}. Received ${val}`
|
|
});
|
|
});
|
|
|
|
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
|
|
assert.throws(
|
|
() => data[fn](min, o, i),
|
|
{
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
name: 'TypeError [ERR_INVALID_ARG_TYPE]'
|
|
});
|
|
});
|
|
|
|
[Infinity, -1, -4294967295].forEach((offset) => {
|
|
assert.throws(
|
|
() => data[fn](min, offset, i),
|
|
{
|
|
code: 'ERR_OUT_OF_RANGE',
|
|
name: 'RangeError [ERR_OUT_OF_RANGE]',
|
|
message: 'The value of "offset" is out of range. ' +
|
|
`It must be >= 0 and <= ${8 - i}. Received ${offset}`
|
|
});
|
|
});
|
|
|
|
[NaN, 1.01].forEach((offset) => {
|
|
assert.throws(
|
|
() => data[fn](max, offset, i),
|
|
{
|
|
code: 'ERR_OUT_OF_RANGE',
|
|
name: 'RangeError [ERR_OUT_OF_RANGE]',
|
|
message: 'The value of "offset" is out of range. ' +
|
|
`It must be an integer. Received ${offset}`
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|