1'use strict'; 2 3const { 4 BigInt, 5 Float32Array, 6 Float64Array, 7 MathFloor, 8 Number, 9 Uint8Array, 10} = primordials; 11 12const { 13 ERR_BUFFER_OUT_OF_BOUNDS, 14 ERR_INVALID_ARG_TYPE, 15 ERR_OUT_OF_RANGE, 16} = require('internal/errors').codes; 17const { validateNumber } = require('internal/validators'); 18const { 19 asciiSlice, 20 base64Slice, 21 base64urlSlice, 22 latin1Slice, 23 hexSlice, 24 ucs2Slice, 25 utf8Slice, 26 asciiWrite, 27 base64Write, 28 base64urlWrite, 29 latin1Write, 30 hexWrite, 31 ucs2Write, 32 utf8Write, 33 getZeroFillToggle, 34} = internalBinding('buffer'); 35 36const { 37 privateSymbols: { 38 untransferable_object_private_symbol, 39 }, 40} = internalBinding('util'); 41 42// Temporary buffers to convert numbers. 43const float32Array = new Float32Array(1); 44const uInt8Float32Array = new Uint8Array(float32Array.buffer); 45const float64Array = new Float64Array(1); 46const uInt8Float64Array = new Uint8Array(float64Array.buffer); 47 48// Check endianness. 49float32Array[0] = -1; // 0xBF800000 50// Either it is [0, 0, 128, 191] or [191, 128, 0, 0]. It is not possible to 51// check this with `os.endianness()` because that is determined at compile time. 52const bigEndian = uInt8Float32Array[3] === 0; 53 54function checkBounds(buf, offset, byteLength) { 55 validateNumber(offset, 'offset'); 56 if (buf[offset] === undefined || buf[offset + byteLength] === undefined) 57 boundsError(offset, buf.length - (byteLength + 1)); 58} 59 60function checkInt(value, min, max, buf, offset, byteLength) { 61 if (value > max || value < min) { 62 const n = typeof min === 'bigint' ? 'n' : ''; 63 let range; 64 if (byteLength > 3) { 65 if (min === 0 || min === 0n) { 66 range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}`; 67 } else { 68 range = `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and ` + 69 `< 2${n} ** ${(byteLength + 1) * 8 - 1}${n}`; 70 } 71 } else { 72 range = `>= ${min}${n} and <= ${max}${n}`; 73 } 74 throw new ERR_OUT_OF_RANGE('value', range, value); 75 } 76 checkBounds(buf, offset, byteLength); 77} 78 79function boundsError(value, length, type) { 80 if (MathFloor(value) !== value) { 81 validateNumber(value, type); 82 throw new ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value); 83 } 84 85 if (length < 0) 86 throw new ERR_BUFFER_OUT_OF_BOUNDS(); 87 88 throw new ERR_OUT_OF_RANGE(type || 'offset', 89 `>= ${type ? 1 : 0} and <= ${length}`, 90 value); 91} 92 93// Read integers. 94function readBigUInt64LE(offset = 0) { 95 validateNumber(offset, 'offset'); 96 const first = this[offset]; 97 const last = this[offset + 7]; 98 if (first === undefined || last === undefined) 99 boundsError(offset, this.length - 8); 100 101 const lo = first + 102 this[++offset] * 2 ** 8 + 103 this[++offset] * 2 ** 16 + 104 this[++offset] * 2 ** 24; 105 106 const hi = this[++offset] + 107 this[++offset] * 2 ** 8 + 108 this[++offset] * 2 ** 16 + 109 last * 2 ** 24; 110 111 return BigInt(lo) + (BigInt(hi) << 32n); 112} 113 114function readBigUInt64BE(offset = 0) { 115 validateNumber(offset, 'offset'); 116 const first = this[offset]; 117 const last = this[offset + 7]; 118 if (first === undefined || last === undefined) 119 boundsError(offset, this.length - 8); 120 121 const hi = first * 2 ** 24 + 122 this[++offset] * 2 ** 16 + 123 this[++offset] * 2 ** 8 + 124 this[++offset]; 125 126 const lo = this[++offset] * 2 ** 24 + 127 this[++offset] * 2 ** 16 + 128 this[++offset] * 2 ** 8 + 129 last; 130 131 return (BigInt(hi) << 32n) + BigInt(lo); 132} 133 134function readBigInt64LE(offset = 0) { 135 validateNumber(offset, 'offset'); 136 const first = this[offset]; 137 const last = this[offset + 7]; 138 if (first === undefined || last === undefined) 139 boundsError(offset, this.length - 8); 140 141 const val = this[offset + 4] + 142 this[offset + 5] * 2 ** 8 + 143 this[offset + 6] * 2 ** 16 + 144 (last << 24); // Overflow 145 return (BigInt(val) << 32n) + 146 BigInt(first + 147 this[++offset] * 2 ** 8 + 148 this[++offset] * 2 ** 16 + 149 this[++offset] * 2 ** 24); 150} 151 152function readBigInt64BE(offset = 0) { 153 validateNumber(offset, 'offset'); 154 const first = this[offset]; 155 const last = this[offset + 7]; 156 if (first === undefined || last === undefined) 157 boundsError(offset, this.length - 8); 158 159 const val = (first << 24) + // Overflow 160 this[++offset] * 2 ** 16 + 161 this[++offset] * 2 ** 8 + 162 this[++offset]; 163 return (BigInt(val) << 32n) + 164 BigInt(this[++offset] * 2 ** 24 + 165 this[++offset] * 2 ** 16 + 166 this[++offset] * 2 ** 8 + 167 last); 168} 169 170function readUIntLE(offset, byteLength) { 171 if (offset === undefined) 172 throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset); 173 if (byteLength === 6) 174 return readUInt48LE(this, offset); 175 if (byteLength === 5) 176 return readUInt40LE(this, offset); 177 if (byteLength === 3) 178 return readUInt24LE(this, offset); 179 if (byteLength === 4) 180 return this.readUInt32LE(offset); 181 if (byteLength === 2) 182 return this.readUInt16LE(offset); 183 if (byteLength === 1) 184 return this.readUInt8(offset); 185 186 boundsError(byteLength, 6, 'byteLength'); 187} 188 189function readUInt48LE(buf, offset = 0) { 190 validateNumber(offset, 'offset'); 191 const first = buf[offset]; 192 const last = buf[offset + 5]; 193 if (first === undefined || last === undefined) 194 boundsError(offset, buf.length - 6); 195 196 return first + 197 buf[++offset] * 2 ** 8 + 198 buf[++offset] * 2 ** 16 + 199 buf[++offset] * 2 ** 24 + 200 (buf[++offset] + last * 2 ** 8) * 2 ** 32; 201} 202 203function readUInt40LE(buf, offset = 0) { 204 validateNumber(offset, 'offset'); 205 const first = buf[offset]; 206 const last = buf[offset + 4]; 207 if (first === undefined || last === undefined) 208 boundsError(offset, buf.length - 5); 209 210 return first + 211 buf[++offset] * 2 ** 8 + 212 buf[++offset] * 2 ** 16 + 213 buf[++offset] * 2 ** 24 + 214 last * 2 ** 32; 215} 216 217function readUInt32LE(offset = 0) { 218 validateNumber(offset, 'offset'); 219 const first = this[offset]; 220 const last = this[offset + 3]; 221 if (first === undefined || last === undefined) 222 boundsError(offset, this.length - 4); 223 224 return first + 225 this[++offset] * 2 ** 8 + 226 this[++offset] * 2 ** 16 + 227 last * 2 ** 24; 228} 229 230function readUInt24LE(buf, offset = 0) { 231 validateNumber(offset, 'offset'); 232 const first = buf[offset]; 233 const last = buf[offset + 2]; 234 if (first === undefined || last === undefined) 235 boundsError(offset, buf.length - 3); 236 237 return first + buf[++offset] * 2 ** 8 + last * 2 ** 16; 238} 239 240function readUInt16LE(offset = 0) { 241 validateNumber(offset, 'offset'); 242 const first = this[offset]; 243 const last = this[offset + 1]; 244 if (first === undefined || last === undefined) 245 boundsError(offset, this.length - 2); 246 247 return first + last * 2 ** 8; 248} 249 250function readUInt8(offset = 0) { 251 validateNumber(offset, 'offset'); 252 const val = this[offset]; 253 if (val === undefined) 254 boundsError(offset, this.length - 1); 255 256 return val; 257} 258 259function readUIntBE(offset, byteLength) { 260 if (offset === undefined) 261 throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset); 262 if (byteLength === 6) 263 return readUInt48BE(this, offset); 264 if (byteLength === 5) 265 return readUInt40BE(this, offset); 266 if (byteLength === 3) 267 return readUInt24BE(this, offset); 268 if (byteLength === 4) 269 return this.readUInt32BE(offset); 270 if (byteLength === 2) 271 return this.readUInt16BE(offset); 272 if (byteLength === 1) 273 return this.readUInt8(offset); 274 275 boundsError(byteLength, 6, 'byteLength'); 276} 277 278function readUInt48BE(buf, offset = 0) { 279 validateNumber(offset, 'offset'); 280 const first = buf[offset]; 281 const last = buf[offset + 5]; 282 if (first === undefined || last === undefined) 283 boundsError(offset, buf.length - 6); 284 285 return (first * 2 ** 8 + buf[++offset]) * 2 ** 32 + 286 buf[++offset] * 2 ** 24 + 287 buf[++offset] * 2 ** 16 + 288 buf[++offset] * 2 ** 8 + 289 last; 290} 291 292function readUInt40BE(buf, offset = 0) { 293 validateNumber(offset, 'offset'); 294 const first = buf[offset]; 295 const last = buf[offset + 4]; 296 if (first === undefined || last === undefined) 297 boundsError(offset, buf.length - 5); 298 299 return first * 2 ** 32 + 300 buf[++offset] * 2 ** 24 + 301 buf[++offset] * 2 ** 16 + 302 buf[++offset] * 2 ** 8 + 303 last; 304} 305 306function readUInt32BE(offset = 0) { 307 validateNumber(offset, 'offset'); 308 const first = this[offset]; 309 const last = this[offset + 3]; 310 if (first === undefined || last === undefined) 311 boundsError(offset, this.length - 4); 312 313 return first * 2 ** 24 + 314 this[++offset] * 2 ** 16 + 315 this[++offset] * 2 ** 8 + 316 last; 317} 318 319function readUInt24BE(buf, offset = 0) { 320 validateNumber(offset, 'offset'); 321 const first = buf[offset]; 322 const last = buf[offset + 2]; 323 if (first === undefined || last === undefined) 324 boundsError(offset, buf.length - 3); 325 326 return first * 2 ** 16 + buf[++offset] * 2 ** 8 + last; 327} 328 329function readUInt16BE(offset = 0) { 330 validateNumber(offset, 'offset'); 331 const first = this[offset]; 332 const last = this[offset + 1]; 333 if (first === undefined || last === undefined) 334 boundsError(offset, this.length - 2); 335 336 return first * 2 ** 8 + last; 337} 338 339function readIntLE(offset, byteLength) { 340 if (offset === undefined) 341 throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset); 342 if (byteLength === 6) 343 return readInt48LE(this, offset); 344 if (byteLength === 5) 345 return readInt40LE(this, offset); 346 if (byteLength === 3) 347 return readInt24LE(this, offset); 348 if (byteLength === 4) 349 return this.readInt32LE(offset); 350 if (byteLength === 2) 351 return this.readInt16LE(offset); 352 if (byteLength === 1) 353 return this.readInt8(offset); 354 355 boundsError(byteLength, 6, 'byteLength'); 356} 357 358function readInt48LE(buf, offset = 0) { 359 validateNumber(offset, 'offset'); 360 const first = buf[offset]; 361 const last = buf[offset + 5]; 362 if (first === undefined || last === undefined) 363 boundsError(offset, buf.length - 6); 364 365 const val = buf[offset + 4] + last * 2 ** 8; 366 return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 + 367 first + 368 buf[++offset] * 2 ** 8 + 369 buf[++offset] * 2 ** 16 + 370 buf[++offset] * 2 ** 24; 371} 372 373function readInt40LE(buf, offset = 0) { 374 validateNumber(offset, 'offset'); 375 const first = buf[offset]; 376 const last = buf[offset + 4]; 377 if (first === undefined || last === undefined) 378 boundsError(offset, buf.length - 5); 379 380 return (last | (last & 2 ** 7) * 0x1fffffe) * 2 ** 32 + 381 first + 382 buf[++offset] * 2 ** 8 + 383 buf[++offset] * 2 ** 16 + 384 buf[++offset] * 2 ** 24; 385} 386 387function readInt32LE(offset = 0) { 388 validateNumber(offset, 'offset'); 389 const first = this[offset]; 390 const last = this[offset + 3]; 391 if (first === undefined || last === undefined) 392 boundsError(offset, this.length - 4); 393 394 return first + 395 this[++offset] * 2 ** 8 + 396 this[++offset] * 2 ** 16 + 397 (last << 24); // Overflow 398} 399 400function readInt24LE(buf, offset = 0) { 401 validateNumber(offset, 'offset'); 402 const first = buf[offset]; 403 const last = buf[offset + 2]; 404 if (first === undefined || last === undefined) 405 boundsError(offset, buf.length - 3); 406 407 const val = first + buf[++offset] * 2 ** 8 + last * 2 ** 16; 408 return val | (val & 2 ** 23) * 0x1fe; 409} 410 411function readInt16LE(offset = 0) { 412 validateNumber(offset, 'offset'); 413 const first = this[offset]; 414 const last = this[offset + 1]; 415 if (first === undefined || last === undefined) 416 boundsError(offset, this.length - 2); 417 418 const val = first + last * 2 ** 8; 419 return val | (val & 2 ** 15) * 0x1fffe; 420} 421 422function readInt8(offset = 0) { 423 validateNumber(offset, 'offset'); 424 const val = this[offset]; 425 if (val === undefined) 426 boundsError(offset, this.length - 1); 427 428 return val | (val & 2 ** 7) * 0x1fffffe; 429} 430 431function readIntBE(offset, byteLength) { 432 if (offset === undefined) 433 throw new ERR_INVALID_ARG_TYPE('offset', 'number', offset); 434 if (byteLength === 6) 435 return readInt48BE(this, offset); 436 if (byteLength === 5) 437 return readInt40BE(this, offset); 438 if (byteLength === 3) 439 return readInt24BE(this, offset); 440 if (byteLength === 4) 441 return this.readInt32BE(offset); 442 if (byteLength === 2) 443 return this.readInt16BE(offset); 444 if (byteLength === 1) 445 return this.readInt8(offset); 446 447 boundsError(byteLength, 6, 'byteLength'); 448} 449 450function readInt48BE(buf, offset = 0) { 451 validateNumber(offset, 'offset'); 452 const first = buf[offset]; 453 const last = buf[offset + 5]; 454 if (first === undefined || last === undefined) 455 boundsError(offset, buf.length - 6); 456 457 const val = buf[++offset] + first * 2 ** 8; 458 return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 + 459 buf[++offset] * 2 ** 24 + 460 buf[++offset] * 2 ** 16 + 461 buf[++offset] * 2 ** 8 + 462 last; 463} 464 465function readInt40BE(buf, offset = 0) { 466 validateNumber(offset, 'offset'); 467 const first = buf[offset]; 468 const last = buf[offset + 4]; 469 if (first === undefined || last === undefined) 470 boundsError(offset, buf.length - 5); 471 472 return (first | (first & 2 ** 7) * 0x1fffffe) * 2 ** 32 + 473 buf[++offset] * 2 ** 24 + 474 buf[++offset] * 2 ** 16 + 475 buf[++offset] * 2 ** 8 + 476 last; 477} 478 479function readInt32BE(offset = 0) { 480 validateNumber(offset, 'offset'); 481 const first = this[offset]; 482 const last = this[offset + 3]; 483 if (first === undefined || last === undefined) 484 boundsError(offset, this.length - 4); 485 486 return (first << 24) + // Overflow 487 this[++offset] * 2 ** 16 + 488 this[++offset] * 2 ** 8 + 489 last; 490} 491 492function readInt24BE(buf, offset = 0) { 493 validateNumber(offset, 'offset'); 494 const first = buf[offset]; 495 const last = buf[offset + 2]; 496 if (first === undefined || last === undefined) 497 boundsError(offset, buf.length - 3); 498 499 const val = first * 2 ** 16 + buf[++offset] * 2 ** 8 + last; 500 return val | (val & 2 ** 23) * 0x1fe; 501} 502 503function readInt16BE(offset = 0) { 504 validateNumber(offset, 'offset'); 505 const first = this[offset]; 506 const last = this[offset + 1]; 507 if (first === undefined || last === undefined) 508 boundsError(offset, this.length - 2); 509 510 const val = first * 2 ** 8 + last; 511 return val | (val & 2 ** 15) * 0x1fffe; 512} 513 514// Read floats 515function readFloatBackwards(offset = 0) { 516 validateNumber(offset, 'offset'); 517 const first = this[offset]; 518 const last = this[offset + 3]; 519 if (first === undefined || last === undefined) 520 boundsError(offset, this.length - 4); 521 522 uInt8Float32Array[3] = first; 523 uInt8Float32Array[2] = this[++offset]; 524 uInt8Float32Array[1] = this[++offset]; 525 uInt8Float32Array[0] = last; 526 return float32Array[0]; 527} 528 529function readFloatForwards(offset = 0) { 530 validateNumber(offset, 'offset'); 531 const first = this[offset]; 532 const last = this[offset + 3]; 533 if (first === undefined || last === undefined) 534 boundsError(offset, this.length - 4); 535 536 uInt8Float32Array[0] = first; 537 uInt8Float32Array[1] = this[++offset]; 538 uInt8Float32Array[2] = this[++offset]; 539 uInt8Float32Array[3] = last; 540 return float32Array[0]; 541} 542 543function readDoubleBackwards(offset = 0) { 544 validateNumber(offset, 'offset'); 545 const first = this[offset]; 546 const last = this[offset + 7]; 547 if (first === undefined || last === undefined) 548 boundsError(offset, this.length - 8); 549 550 uInt8Float64Array[7] = first; 551 uInt8Float64Array[6] = this[++offset]; 552 uInt8Float64Array[5] = this[++offset]; 553 uInt8Float64Array[4] = this[++offset]; 554 uInt8Float64Array[3] = this[++offset]; 555 uInt8Float64Array[2] = this[++offset]; 556 uInt8Float64Array[1] = this[++offset]; 557 uInt8Float64Array[0] = last; 558 return float64Array[0]; 559} 560 561function readDoubleForwards(offset = 0) { 562 validateNumber(offset, 'offset'); 563 const first = this[offset]; 564 const last = this[offset + 7]; 565 if (first === undefined || last === undefined) 566 boundsError(offset, this.length - 8); 567 568 uInt8Float64Array[0] = first; 569 uInt8Float64Array[1] = this[++offset]; 570 uInt8Float64Array[2] = this[++offset]; 571 uInt8Float64Array[3] = this[++offset]; 572 uInt8Float64Array[4] = this[++offset]; 573 uInt8Float64Array[5] = this[++offset]; 574 uInt8Float64Array[6] = this[++offset]; 575 uInt8Float64Array[7] = last; 576 return float64Array[0]; 577} 578 579// Write integers. 580function writeBigU_Int64LE(buf, value, offset, min, max) { 581 checkInt(value, min, max, buf, offset, 7); 582 583 let lo = Number(value & 0xffffffffn); 584 buf[offset++] = lo; 585 lo = lo >> 8; 586 buf[offset++] = lo; 587 lo = lo >> 8; 588 buf[offset++] = lo; 589 lo = lo >> 8; 590 buf[offset++] = lo; 591 let hi = Number(value >> 32n & 0xffffffffn); 592 buf[offset++] = hi; 593 hi = hi >> 8; 594 buf[offset++] = hi; 595 hi = hi >> 8; 596 buf[offset++] = hi; 597 hi = hi >> 8; 598 buf[offset++] = hi; 599 return offset; 600} 601 602function writeBigUInt64LE(value, offset = 0) { 603 return writeBigU_Int64LE(this, value, offset, 0n, 0xffffffffffffffffn); 604} 605 606function writeBigU_Int64BE(buf, value, offset, min, max) { 607 checkInt(value, min, max, buf, offset, 7); 608 609 let lo = Number(value & 0xffffffffn); 610 buf[offset + 7] = lo; 611 lo = lo >> 8; 612 buf[offset + 6] = lo; 613 lo = lo >> 8; 614 buf[offset + 5] = lo; 615 lo = lo >> 8; 616 buf[offset + 4] = lo; 617 let hi = Number(value >> 32n & 0xffffffffn); 618 buf[offset + 3] = hi; 619 hi = hi >> 8; 620 buf[offset + 2] = hi; 621 hi = hi >> 8; 622 buf[offset + 1] = hi; 623 hi = hi >> 8; 624 buf[offset] = hi; 625 return offset + 8; 626} 627 628function writeBigUInt64BE(value, offset = 0) { 629 return writeBigU_Int64BE(this, value, offset, 0n, 0xffffffffffffffffn); 630} 631 632function writeBigInt64LE(value, offset = 0) { 633 return writeBigU_Int64LE( 634 this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn); 635} 636 637function writeBigInt64BE(value, offset = 0) { 638 return writeBigU_Int64BE( 639 this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn); 640} 641 642function writeUIntLE(value, offset, byteLength) { 643 if (byteLength === 6) 644 return writeU_Int48LE(this, value, offset, 0, 0xffffffffffff); 645 if (byteLength === 5) 646 return writeU_Int40LE(this, value, offset, 0, 0xffffffffff); 647 if (byteLength === 3) 648 return writeU_Int24LE(this, value, offset, 0, 0xffffff); 649 if (byteLength === 4) 650 return writeU_Int32LE(this, value, offset, 0, 0xffffffff); 651 if (byteLength === 2) 652 return writeU_Int16LE(this, value, offset, 0, 0xffff); 653 if (byteLength === 1) 654 return writeU_Int8(this, value, offset, 0, 0xff); 655 656 boundsError(byteLength, 6, 'byteLength'); 657} 658 659function writeU_Int48LE(buf, value, offset, min, max) { 660 value = +value; 661 checkInt(value, min, max, buf, offset, 5); 662 663 const newVal = MathFloor(value * 2 ** -32); 664 buf[offset++] = value; 665 value = value >>> 8; 666 buf[offset++] = value; 667 value = value >>> 8; 668 buf[offset++] = value; 669 value = value >>> 8; 670 buf[offset++] = value; 671 buf[offset++] = newVal; 672 buf[offset++] = (newVal >>> 8); 673 return offset; 674} 675 676function writeU_Int40LE(buf, value, offset, min, max) { 677 value = +value; 678 checkInt(value, min, max, buf, offset, 4); 679 680 const newVal = value; 681 buf[offset++] = value; 682 value = value >>> 8; 683 buf[offset++] = value; 684 value = value >>> 8; 685 buf[offset++] = value; 686 value = value >>> 8; 687 buf[offset++] = value; 688 buf[offset++] = MathFloor(newVal * 2 ** -32); 689 return offset; 690} 691 692function writeU_Int32LE(buf, value, offset, min, max) { 693 value = +value; 694 checkInt(value, min, max, buf, offset, 3); 695 696 buf[offset++] = value; 697 value = value >>> 8; 698 buf[offset++] = value; 699 value = value >>> 8; 700 buf[offset++] = value; 701 value = value >>> 8; 702 buf[offset++] = value; 703 return offset; 704} 705 706function writeUInt32LE(value, offset = 0) { 707 return writeU_Int32LE(this, value, offset, 0, 0xffffffff); 708} 709 710function writeU_Int24LE(buf, value, offset, min, max) { 711 value = +value; 712 checkInt(value, min, max, buf, offset, 2); 713 714 buf[offset++] = value; 715 value = value >>> 8; 716 buf[offset++] = value; 717 value = value >>> 8; 718 buf[offset++] = value; 719 return offset; 720} 721 722function writeU_Int16LE(buf, value, offset, min, max) { 723 value = +value; 724 checkInt(value, min, max, buf, offset, 1); 725 726 buf[offset++] = value; 727 buf[offset++] = (value >>> 8); 728 return offset; 729} 730 731function writeUInt16LE(value, offset = 0) { 732 return writeU_Int16LE(this, value, offset, 0, 0xffff); 733} 734 735function writeU_Int8(buf, value, offset, min, max) { 736 value = +value; 737 // `checkInt()` can not be used here because it checks two entries. 738 validateNumber(offset, 'offset'); 739 if (value > max || value < min) { 740 throw new ERR_OUT_OF_RANGE('value', `>= ${min} and <= ${max}`, value); 741 } 742 if (buf[offset] === undefined) 743 boundsError(offset, buf.length - 1); 744 745 buf[offset] = value; 746 return offset + 1; 747} 748 749function writeUInt8(value, offset = 0) { 750 return writeU_Int8(this, value, offset, 0, 0xff); 751} 752 753function writeUIntBE(value, offset, byteLength) { 754 if (byteLength === 6) 755 return writeU_Int48BE(this, value, offset, 0, 0xffffffffffff); 756 if (byteLength === 5) 757 return writeU_Int40BE(this, value, offset, 0, 0xffffffffff); 758 if (byteLength === 3) 759 return writeU_Int24BE(this, value, offset, 0, 0xffffff); 760 if (byteLength === 4) 761 return writeU_Int32BE(this, value, offset, 0, 0xffffffff); 762 if (byteLength === 2) 763 return writeU_Int16BE(this, value, offset, 0, 0xffff); 764 if (byteLength === 1) 765 return writeU_Int8(this, value, offset, 0, 0xff); 766 767 boundsError(byteLength, 6, 'byteLength'); 768} 769 770function writeU_Int48BE(buf, value, offset, min, max) { 771 value = +value; 772 checkInt(value, min, max, buf, offset, 5); 773 774 const newVal = MathFloor(value * 2 ** -32); 775 buf[offset++] = (newVal >>> 8); 776 buf[offset++] = newVal; 777 buf[offset + 3] = value; 778 value = value >>> 8; 779 buf[offset + 2] = value; 780 value = value >>> 8; 781 buf[offset + 1] = value; 782 value = value >>> 8; 783 buf[offset] = value; 784 return offset + 4; 785} 786 787function writeU_Int40BE(buf, value, offset, min, max) { 788 value = +value; 789 checkInt(value, min, max, buf, offset, 4); 790 791 buf[offset++] = MathFloor(value * 2 ** -32); 792 buf[offset + 3] = value; 793 value = value >>> 8; 794 buf[offset + 2] = value; 795 value = value >>> 8; 796 buf[offset + 1] = value; 797 value = value >>> 8; 798 buf[offset] = value; 799 return offset + 4; 800} 801 802function writeU_Int32BE(buf, value, offset, min, max) { 803 value = +value; 804 checkInt(value, min, max, buf, offset, 3); 805 806 buf[offset + 3] = value; 807 value = value >>> 8; 808 buf[offset + 2] = value; 809 value = value >>> 8; 810 buf[offset + 1] = value; 811 value = value >>> 8; 812 buf[offset] = value; 813 return offset + 4; 814} 815 816function writeUInt32BE(value, offset = 0) { 817 return writeU_Int32BE(this, value, offset, 0, 0xffffffff); 818} 819 820function writeU_Int24BE(buf, value, offset, min, max) { 821 value = +value; 822 checkInt(value, min, max, buf, offset, 2); 823 824 buf[offset + 2] = value; 825 value = value >>> 8; 826 buf[offset + 1] = value; 827 value = value >>> 8; 828 buf[offset] = value; 829 return offset + 3; 830} 831 832function writeU_Int16BE(buf, value, offset, min, max) { 833 value = +value; 834 checkInt(value, min, max, buf, offset, 1); 835 836 buf[offset++] = (value >>> 8); 837 buf[offset++] = value; 838 return offset; 839} 840 841function writeUInt16BE(value, offset = 0) { 842 return writeU_Int16BE(this, value, offset, 0, 0xffff); 843} 844 845function writeIntLE(value, offset, byteLength) { 846 if (byteLength === 6) 847 return writeU_Int48LE(this, value, offset, -0x800000000000, 0x7fffffffffff); 848 if (byteLength === 5) 849 return writeU_Int40LE(this, value, offset, -0x8000000000, 0x7fffffffff); 850 if (byteLength === 3) 851 return writeU_Int24LE(this, value, offset, -0x800000, 0x7fffff); 852 if (byteLength === 4) 853 return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff); 854 if (byteLength === 2) 855 return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff); 856 if (byteLength === 1) 857 return writeU_Int8(this, value, offset, -0x80, 0x7f); 858 859 boundsError(byteLength, 6, 'byteLength'); 860} 861 862function writeInt32LE(value, offset = 0) { 863 return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff); 864} 865 866function writeInt16LE(value, offset = 0) { 867 return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff); 868} 869 870function writeInt8(value, offset = 0) { 871 return writeU_Int8(this, value, offset, -0x80, 0x7f); 872} 873 874function writeIntBE(value, offset, byteLength) { 875 if (byteLength === 6) 876 return writeU_Int48BE(this, value, offset, -0x800000000000, 0x7fffffffffff); 877 if (byteLength === 5) 878 return writeU_Int40BE(this, value, offset, -0x8000000000, 0x7fffffffff); 879 if (byteLength === 3) 880 return writeU_Int24BE(this, value, offset, -0x800000, 0x7fffff); 881 if (byteLength === 4) 882 return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff); 883 if (byteLength === 2) 884 return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff); 885 if (byteLength === 1) 886 return writeU_Int8(this, value, offset, -0x80, 0x7f); 887 888 boundsError(byteLength, 6, 'byteLength'); 889} 890 891function writeInt32BE(value, offset = 0) { 892 return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff); 893} 894 895function writeInt16BE(value, offset = 0) { 896 return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff); 897} 898 899// Write floats. 900function writeDoubleForwards(val, offset = 0) { 901 val = +val; 902 checkBounds(this, offset, 7); 903 904 float64Array[0] = val; 905 this[offset++] = uInt8Float64Array[0]; 906 this[offset++] = uInt8Float64Array[1]; 907 this[offset++] = uInt8Float64Array[2]; 908 this[offset++] = uInt8Float64Array[3]; 909 this[offset++] = uInt8Float64Array[4]; 910 this[offset++] = uInt8Float64Array[5]; 911 this[offset++] = uInt8Float64Array[6]; 912 this[offset++] = uInt8Float64Array[7]; 913 return offset; 914} 915 916function writeDoubleBackwards(val, offset = 0) { 917 val = +val; 918 checkBounds(this, offset, 7); 919 920 float64Array[0] = val; 921 this[offset++] = uInt8Float64Array[7]; 922 this[offset++] = uInt8Float64Array[6]; 923 this[offset++] = uInt8Float64Array[5]; 924 this[offset++] = uInt8Float64Array[4]; 925 this[offset++] = uInt8Float64Array[3]; 926 this[offset++] = uInt8Float64Array[2]; 927 this[offset++] = uInt8Float64Array[1]; 928 this[offset++] = uInt8Float64Array[0]; 929 return offset; 930} 931 932function writeFloatForwards(val, offset = 0) { 933 val = +val; 934 checkBounds(this, offset, 3); 935 936 float32Array[0] = val; 937 this[offset++] = uInt8Float32Array[0]; 938 this[offset++] = uInt8Float32Array[1]; 939 this[offset++] = uInt8Float32Array[2]; 940 this[offset++] = uInt8Float32Array[3]; 941 return offset; 942} 943 944function writeFloatBackwards(val, offset = 0) { 945 val = +val; 946 checkBounds(this, offset, 3); 947 948 float32Array[0] = val; 949 this[offset++] = uInt8Float32Array[3]; 950 this[offset++] = uInt8Float32Array[2]; 951 this[offset++] = uInt8Float32Array[1]; 952 this[offset++] = uInt8Float32Array[0]; 953 return offset; 954} 955 956class FastBuffer extends Uint8Array { 957 // Using an explicit constructor here is necessary to avoid relying on 958 // `Array.prototype[Symbol.iterator]`, which can be mutated by users. 959 // eslint-disable-next-line no-useless-constructor 960 constructor(bufferOrLength, byteOffset, length) { 961 super(bufferOrLength, byteOffset, length); 962 } 963} 964 965function addBufferPrototypeMethods(proto) { 966 proto.readBigUInt64LE = readBigUInt64LE; 967 proto.readBigUInt64BE = readBigUInt64BE; 968 proto.readBigUint64LE = readBigUInt64LE; 969 proto.readBigUint64BE = readBigUInt64BE; 970 proto.readBigInt64LE = readBigInt64LE; 971 proto.readBigInt64BE = readBigInt64BE; 972 proto.writeBigUInt64LE = writeBigUInt64LE; 973 proto.writeBigUInt64BE = writeBigUInt64BE; 974 proto.writeBigUint64LE = writeBigUInt64LE; 975 proto.writeBigUint64BE = writeBigUInt64BE; 976 proto.writeBigInt64LE = writeBigInt64LE; 977 proto.writeBigInt64BE = writeBigInt64BE; 978 979 proto.readUIntLE = readUIntLE; 980 proto.readUInt32LE = readUInt32LE; 981 proto.readUInt16LE = readUInt16LE; 982 proto.readUInt8 = readUInt8; 983 proto.readUIntBE = readUIntBE; 984 proto.readUInt32BE = readUInt32BE; 985 proto.readUInt16BE = readUInt16BE; 986 proto.readUintLE = readUIntLE; 987 proto.readUint32LE = readUInt32LE; 988 proto.readUint16LE = readUInt16LE; 989 proto.readUint8 = readUInt8; 990 proto.readUintBE = readUIntBE; 991 proto.readUint32BE = readUInt32BE; 992 proto.readUint16BE = readUInt16BE; 993 proto.readIntLE = readIntLE; 994 proto.readInt32LE = readInt32LE; 995 proto.readInt16LE = readInt16LE; 996 proto.readInt8 = readInt8; 997 proto.readIntBE = readIntBE; 998 proto.readInt32BE = readInt32BE; 999 proto.readInt16BE = readInt16BE; 1000 1001 proto.writeUIntLE = writeUIntLE; 1002 proto.writeUInt32LE = writeUInt32LE; 1003 proto.writeUInt16LE = writeUInt16LE; 1004 proto.writeUInt8 = writeUInt8; 1005 proto.writeUIntBE = writeUIntBE; 1006 proto.writeUInt32BE = writeUInt32BE; 1007 proto.writeUInt16BE = writeUInt16BE; 1008 proto.writeUintLE = writeUIntLE; 1009 proto.writeUint32LE = writeUInt32LE; 1010 proto.writeUint16LE = writeUInt16LE; 1011 proto.writeUint8 = writeUInt8; 1012 proto.writeUintBE = writeUIntBE; 1013 proto.writeUint32BE = writeUInt32BE; 1014 proto.writeUint16BE = writeUInt16BE; 1015 proto.writeIntLE = writeIntLE; 1016 proto.writeInt32LE = writeInt32LE; 1017 proto.writeInt16LE = writeInt16LE; 1018 proto.writeInt8 = writeInt8; 1019 proto.writeIntBE = writeIntBE; 1020 proto.writeInt32BE = writeInt32BE; 1021 proto.writeInt16BE = writeInt16BE; 1022 1023 proto.readFloatLE = bigEndian ? readFloatBackwards : readFloatForwards; 1024 proto.readFloatBE = bigEndian ? readFloatForwards : readFloatBackwards; 1025 proto.readDoubleLE = bigEndian ? readDoubleBackwards : readDoubleForwards; 1026 proto.readDoubleBE = bigEndian ? readDoubleForwards : readDoubleBackwards; 1027 proto.writeFloatLE = bigEndian ? writeFloatBackwards : writeFloatForwards; 1028 proto.writeFloatBE = bigEndian ? writeFloatForwards : writeFloatBackwards; 1029 proto.writeDoubleLE = bigEndian ? writeDoubleBackwards : writeDoubleForwards; 1030 proto.writeDoubleBE = bigEndian ? writeDoubleForwards : writeDoubleBackwards; 1031 1032 proto.asciiSlice = asciiSlice; 1033 proto.base64Slice = base64Slice; 1034 proto.base64urlSlice = base64urlSlice; 1035 proto.latin1Slice = latin1Slice; 1036 proto.hexSlice = hexSlice; 1037 proto.ucs2Slice = ucs2Slice; 1038 proto.utf8Slice = utf8Slice; 1039 proto.asciiWrite = asciiWrite; 1040 proto.base64Write = base64Write; 1041 proto.base64urlWrite = base64urlWrite; 1042 proto.latin1Write = latin1Write; 1043 proto.hexWrite = hexWrite; 1044 proto.ucs2Write = ucs2Write; 1045 proto.utf8Write = utf8Write; 1046} 1047 1048// This would better be placed in internal/worker/io.js, but that doesn't work 1049// because Buffer needs this and that would introduce a cyclic dependency. 1050function markAsUntransferable(obj) { 1051 if ((typeof obj !== 'object' && typeof obj !== 'function') || obj === null) 1052 return; // This object is a primitive and therefore already untransferable. 1053 obj[untransferable_object_private_symbol] = true; 1054} 1055 1056// A toggle used to access the zero fill setting of the array buffer allocator 1057// in C++. 1058// |zeroFill| can be undefined when running inside an isolate where we 1059// do not own the ArrayBuffer allocator. Zero fill is always on in that case. 1060let zeroFill = getZeroFillToggle(); 1061function createUnsafeBuffer(size) { 1062 zeroFill[0] = 0; 1063 try { 1064 return new FastBuffer(size); 1065 } finally { 1066 zeroFill[0] = 1; 1067 } 1068} 1069 1070// The connection between the JS land zero fill toggle and the 1071// C++ one in the NodeArrayBufferAllocator gets lost if the toggle 1072// is deserialized from the snapshot, because V8 owns the underlying 1073// memory of this toggle. This resets the connection. 1074function reconnectZeroFillToggle() { 1075 zeroFill = getZeroFillToggle(); 1076} 1077 1078module.exports = { 1079 FastBuffer, 1080 addBufferPrototypeMethods, 1081 markAsUntransferable, 1082 createUnsafeBuffer, 1083 readUInt16BE, 1084 readUInt32BE, 1085 reconnectZeroFillToggle, 1086}; 1087