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