1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16package escompat; 17 18export final class DataView implements ArrayBufferView { 19 /** Underlying buffer */ 20 private readonly buffer_: ArrayBufferLike 21 /** Count of bytes in a view */ 22 private readonly byteLength_: int 23 /** Offset from start of {@link buffer} */ 24 private readonly byteOffset_: int 25 26 public get buffer(): ArrayBufferLike { 27 return this.buffer_ 28 } 29 30 public get byteLength(): number { 31 return this.byteLength_ 32 } 33 34 public get byteOffset(): number { 35 return this.byteOffset_ 36 } 37 38 private readonly actualBuffer: Buffer 39 40 /** 41 * Constructs view 42 * @param buffer underlying buffer 43 * @param byteOffset offset to start from 44 * @throws RangeError if offset is out of array 45 */ 46 public constructor(buffer: ArrayBufferLike, byteOffset: int) { 47 this(buffer, byteOffset, (buffer as Buffer).getByteLength() - byteOffset) 48 } 49 50 /** 51 * Constructs view 52 * @param buffer underlying buffer 53 * @param byteOffset offset to start from 54 * @param byteLength lenth of bytes to take 55 * @throws RangeError if provided indicies are invalid 56 */ 57 public constructor(buffer: ArrayBufferLike, byteOffset: int, byteLength: int) { 58 this.buffer_ = buffer 59 this.actualBuffer = buffer 60 const bufLen = this.actualBuffer.getByteLength() 61 if (byteOffset < 0 || byteLength < 0 || byteOffset > bufLen || byteOffset + byteLength > bufLen) { 62 throw new RangeError("invalid arguments") 63 } 64 this.byteOffset_ = byteOffset 65 this.byteLength_ = byteLength 66 } 67 68 /** 69 * Constructs view 70 * @param buffer underlying buffer 71 * @param byteOffset offset to start from 72 * @param byteLength lenth of bytes to take 73 * @throws RangeError if provided indicies are invalid 74 */ 75 public constructor(buffer: ArrayBufferLike, byteOffset?: Number, byteLength?: Number) { 76 this(buffer, asIntOrDefault(byteOffset, 0), asIntOrDefault(byteLength, (buffer as Buffer).getByteLength())) 77 } 78 // === Int8 === 79 80 /** 81 * Read bytes as they represent given type 82 * @param byteOffset zero index to read 83 * @returns read value (big endian) 84 */ 85 public getInt8(byteOffset: int): int { 86 return this.getInt8Big(byteOffset) 87 } 88 89 /** 90 * Sets bytes as they represent given type 91 * @param byteOffset zero index to write (big endian) 92 */ 93 public setInt8(byteOffset: int, value: int): void { 94 this.setInt8Big(byteOffset, value) 95 } 96 97 /** 98 * Read bytes as they represent given type 99 * @param byteOffset zero index to read 100 * @returns read value (big endian) 101 */ 102 public getInt8(byteOffset: number): number { 103 return this.getInt8Big(byteOffset) 104 } 105 106 /** 107 * Sets bytes as they represent given type 108 * @param byteOffset zero index to write (big endian) 109 */ 110 public setInt8(byteOffset: number, value: number): void { 111 this.setInt8Big(byteOffset, value) 112 } 113 private getInt8Big(byteOffset: int): int { 114 if (byteOffset + 1 > this.byteLength_) { 115 throw new RangeError("wrong index") 116 } 117 let res: int = 0; 118 const startByte = this.byteOffset_ + byteOffset 119 for (let i = 0; i < 1; i++) { 120 let byteVal = this.actualBuffer.at(startByte + 0 - i) as int; 121 byteVal &= 0xff 122 res = (res | byteVal << (8 * i)) as int; 123 } 124 return (res as byte) as int 125 } 126 private getInt8Big(byteOffset: number): number { 127 let res = this.getInt8Big(byteOffset as int) 128 return res; 129 } 130 131 private setInt8Big(byteOffset: int, value: int): void { 132 if (byteOffset < 0 || byteOffset + 1.0 > this.byteLength_) { 133 throw new RangeError("wrong index") 134 } 135 let bits = value; 136 const startByte = this.byteOffset_ + byteOffset 137 for (let i = 0; i < 1; i++) { 138 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 139 this.actualBuffer.set(startByte + 0 - i, byteVal) 140 } 141 } 142 private setInt8Big(byteOffset: number, value: number): void { 143 const val: int = value as int; 144 this.setInt8Big(byteOffset as int, val) 145 } 146 // === Uint8 === 147 148 /** 149 * Read bytes as they represent given type 150 * @param byteOffset zero index to read 151 * @returns read value (big endian) 152 */ 153 public getUint8(byteOffset: int): int { 154 return this.getUint8Big(byteOffset) 155 } 156 157 /** 158 * Sets bytes as they represent given type 159 * @param byteOffset zero index to write (big endian) 160 */ 161 public setUint8(byteOffset: int, value: int): void { 162 this.setUint8Big(byteOffset, value) 163 } 164 165 /** 166 * Read bytes as they represent given type 167 * @param byteOffset zero index to read 168 * @returns read value (big endian) 169 */ 170 public getUint8(byteOffset: number): number { 171 return this.getUint8Big(byteOffset) 172 } 173 174 /** 175 * Sets bytes as they represent given type 176 * @param byteOffset zero index to write (big endian) 177 */ 178 public setUint8(byteOffset: number, value: number): void { 179 this.setUint8Big(byteOffset, value) 180 } 181 private getUint8Big(byteOffset: int): int { 182 if (byteOffset + 1 > this.byteLength_) { 183 throw new RangeError("wrong index") 184 } 185 let res: int = 0; 186 const startByte = this.byteOffset_ + byteOffset 187 for (let i = 0; i < 1; i++) { 188 let byteVal = this.actualBuffer.at(startByte + 0 - i) as int; 189 byteVal &= 0xff 190 res = (res | byteVal << (8 * i)) as int; 191 } 192 return res 193 } 194 private getUint8Big(byteOffset: number): number { 195 let res = this.getUint8Big(byteOffset as int) 196 return res; 197 } 198 199 private setUint8Big(byteOffset: int, value: int): void { 200 if (byteOffset < 0 || byteOffset + 1.0 > this.byteLength_) { 201 throw new RangeError("wrong index") 202 } 203 let bits = value; 204 const startByte = this.byteOffset_ + byteOffset 205 for (let i = 0; i < 1; i++) { 206 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 207 this.actualBuffer.set(startByte + 0 - i, byteVal) 208 } 209 } 210 private setUint8Big(byteOffset: number, value: number): void { 211 const val: int = value as int; 212 this.setUint8Big(byteOffset as int, val) 213 } 214 // === Int16 === 215 216 /** 217 * Read bytes as they represent given type 218 * @param byteOffset zero index to read 219 * @returns read value (big endian) 220 */ 221 public getInt16(byteOffset: int): int { 222 return this.getInt16Big(byteOffset) 223 } 224 225 /** 226 * Sets bytes as they represent given type 227 * @param byteOffset zero index to write (big endian) 228 */ 229 public setInt16(byteOffset: int, value: int): void { 230 this.setInt16Big(byteOffset, value) 231 } 232 /** 233 * Sets bytes as they represent given type 234 * @param byteOffset zero index to write 235 * @param littleEndian read as little or big endian 236 */ 237 public setInt16(byteOffset: number, value: number, littleEndian?: boolean): void { 238 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 239 this.setInt16Little(byteOffset, value) 240 } else { 241 this.setInt16Big(byteOffset, value) 242 } 243 } 244 245 /** 246 * Sets bytes as they represent given type 247 * @param byteOffset zero index to write 248 * @param littleEndian read as little or big endian 249 */ 250 public setInt16(byteOffset: int, value: int, littleEndian: boolean): void { 251 if (littleEndian) { 252 this.setInt16Little(byteOffset, value) 253 } else { 254 this.setInt16Big(byteOffset, value) 255 } 256 } 257 258 /** 259 * Read bytes as they represent given type 260 * @param byteOffset zero index to read 261 * @param littleEndian read as little or big endian 262 * @returns read value 263 */ 264 public getInt16(byteOffset: number, littleEndian?: boolean): number { 265 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 266 return this.getInt16Little(byteOffset) 267 } else { 268 return this.getInt16Big(byteOffset) 269 } 270 } 271 272 /** 273 * Read bytes as they represent given type 274 * @param byteOffset zero index to read 275 * @param littleEndian read as little or big endian 276 * @returns read value 277 */ 278 public getInt16(byteOffset: int, littleEndian: boolean): int { 279 if (littleEndian) { 280 return this.getInt16Little(byteOffset) 281 } else { 282 return this.getInt16Big(byteOffset) 283 } 284 } 285 private getInt16Little(byteOffset: int): int { 286 if (byteOffset + 2 > this.byteLength_) { 287 throw new RangeError("wrong index") 288 } 289 let res: int = 0; 290 const startByte = this.byteOffset_ + byteOffset 291 for (let i = 0; i < 2; i++) { 292 let byteVal = this.actualBuffer.at(startByte + i) as int; 293 byteVal &= 0xff 294 res = (res | byteVal << (8 * i)) as int; 295 } 296 return (res as short) as int 297 } 298 private getInt16Little(byteOffset: number): number { 299 let res = this.getInt16Little(byteOffset as int) 300 return res; 301 } 302 303 private setInt16Little(byteOffset: int, value: int): void { 304 if (byteOffset < 0 || byteOffset + 2.0 > this.byteLength_) { 305 throw new RangeError("wrong index") 306 } 307 let bits = value; 308 const startByte = this.byteOffset_ + byteOffset 309 for (let i = 0; i < 2; i++) { 310 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 311 this.actualBuffer.set(startByte + i, byteVal) 312 } 313 } 314 private setInt16Little(byteOffset: number, value: number): void { 315 const val: int = value as int; 316 this.setInt16Little(byteOffset as int, val) 317 } 318 private getInt16Big(byteOffset: int): int { 319 if (byteOffset + 2 > this.byteLength_) { 320 throw new RangeError("wrong index") 321 } 322 let res: int = 0; 323 const startByte = this.byteOffset_ + byteOffset 324 for (let i = 0; i < 2; i++) { 325 let byteVal = this.actualBuffer.at(startByte + 1 - i) as int; 326 byteVal &= 0xff 327 res = (res | byteVal << (8 * i)) as int; 328 } 329 return (res as short) as int 330 } 331 private getInt16Big(byteOffset: number): number { 332 let res = this.getInt16Big(byteOffset as int) 333 return res; 334 } 335 336 private setInt16Big(byteOffset: int, value: int): void { 337 if (byteOffset < 0 || byteOffset + 2.0 > this.byteLength_) { 338 throw new RangeError("wrong index") 339 } 340 let bits = value; 341 const startByte = this.byteOffset_ + byteOffset 342 for (let i = 0; i < 2; i++) { 343 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 344 this.actualBuffer.set(startByte + 1 - i, byteVal) 345 } 346 } 347 private setInt16Big(byteOffset: number, value: number): void { 348 const val: int = value as int; 349 this.setInt16Big(byteOffset as int, val) 350 } 351 // === Uint16 === 352 353 /** 354 * Read bytes as they represent given type 355 * @param byteOffset zero index to read 356 * @returns read value (big endian) 357 */ 358 public getUint16(byteOffset: int): int { 359 return this.getUint16Big(byteOffset) 360 } 361 362 /** 363 * Sets bytes as they represent given type 364 * @param byteOffset zero index to write (big endian) 365 */ 366 public setUint16(byteOffset: int, value: int): void { 367 this.setUint16Big(byteOffset, value) 368 } 369 /** 370 * Sets bytes as they represent given type 371 * @param byteOffset zero index to write 372 * @param littleEndian read as little or big endian 373 */ 374 public setUint16(byteOffset: number, value: number, littleEndian?: boolean): void { 375 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 376 this.setUint16Little(byteOffset, value) 377 } else { 378 this.setUint16Big(byteOffset, value) 379 } 380 } 381 382 /** 383 * Sets bytes as they represent given type 384 * @param byteOffset zero index to write 385 * @param littleEndian read as little or big endian 386 */ 387 public setUint16(byteOffset: int, value: int, littleEndian: boolean): void { 388 if (littleEndian) { 389 this.setUint16Little(byteOffset, value) 390 } else { 391 this.setUint16Big(byteOffset, value) 392 } 393 } 394 395 /** 396 * Read bytes as they represent given type 397 * @param byteOffset zero index to read 398 * @param littleEndian read as little or big endian 399 * @returns read value 400 */ 401 public getUint16(byteOffset: number, littleEndian?: boolean): number { 402 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 403 return this.getUint16Little(byteOffset) 404 } else { 405 return this.getUint16Big(byteOffset) 406 } 407 } 408 409 /** 410 * Read bytes as they represent given type 411 * @param byteOffset zero index to read 412 * @param littleEndian read as little or big endian 413 * @returns read value 414 */ 415 public getUint16(byteOffset: int, littleEndian: boolean): int { 416 if (littleEndian) { 417 return this.getUint16Little(byteOffset) 418 } else { 419 return this.getUint16Big(byteOffset) 420 } 421 } 422 private getUint16Little(byteOffset: int): int { 423 if (byteOffset + 2 > this.byteLength_) { 424 throw new RangeError("wrong index") 425 } 426 let res: int = 0; 427 const startByte = this.byteOffset_ + byteOffset 428 for (let i = 0; i < 2; i++) { 429 let byteVal = this.actualBuffer.at(startByte + i) as int; 430 byteVal &= 0xff 431 res = (res | byteVal << (8 * i)) as int; 432 } 433 return res 434 } 435 private getUint16Little(byteOffset: number): number { 436 let res = this.getUint16Little(byteOffset as int) 437 return res; 438 } 439 440 private setUint16Little(byteOffset: int, value: int): void { 441 if (byteOffset < 0 || byteOffset + 2.0 > this.byteLength_) { 442 throw new RangeError("wrong index") 443 } 444 let bits = value; 445 const startByte = this.byteOffset_ + byteOffset 446 for (let i = 0; i < 2; i++) { 447 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 448 this.actualBuffer.set(startByte + i, byteVal) 449 } 450 } 451 private setUint16Little(byteOffset: number, value: number): void { 452 const val: int = value as int; 453 this.setUint16Little(byteOffset as int, val) 454 } 455 private getUint16Big(byteOffset: int): int { 456 if (byteOffset + 2 > this.byteLength_) { 457 throw new RangeError("wrong index") 458 } 459 let res: int = 0; 460 const startByte = this.byteOffset_ + byteOffset 461 for (let i = 0; i < 2; i++) { 462 let byteVal = this.actualBuffer.at(startByte + 1 - i) as int; 463 byteVal &= 0xff 464 res = (res | byteVal << (8 * i)) as int; 465 } 466 return res 467 } 468 private getUint16Big(byteOffset: number): number { 469 let res = this.getUint16Big(byteOffset as int) 470 return res; 471 } 472 473 private setUint16Big(byteOffset: int, value: int): void { 474 if (byteOffset < 0 || byteOffset + 2.0 > this.byteLength_) { 475 throw new RangeError("wrong index") 476 } 477 let bits = value; 478 const startByte = this.byteOffset_ + byteOffset 479 for (let i = 0; i < 2; i++) { 480 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 481 this.actualBuffer.set(startByte + 1 - i, byteVal) 482 } 483 } 484 private setUint16Big(byteOffset: number, value: number): void { 485 const val: int = value as int; 486 this.setUint16Big(byteOffset as int, val) 487 } 488 // === Int32 === 489 490 /** 491 * Read bytes as they represent given type 492 * @param byteOffset zero index to read 493 * @returns read value (big endian) 494 */ 495 public getInt32(byteOffset: int): int { 496 return this.getInt32Big(byteOffset) 497 } 498 499 /** 500 * Sets bytes as they represent given type 501 * @param byteOffset zero index to write (big endian) 502 */ 503 public setInt32(byteOffset: int, value: int): void { 504 this.setInt32Big(byteOffset, value) 505 } 506 /** 507 * Sets bytes as they represent given type 508 * @param byteOffset zero index to write 509 * @param littleEndian read as little or big endian 510 */ 511 public setInt32(byteOffset: number, value: number, littleEndian?: boolean): void { 512 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 513 this.setInt32Little(byteOffset, value) 514 } else { 515 this.setInt32Big(byteOffset, value) 516 } 517 } 518 519 /** 520 * Sets bytes as they represent given type 521 * @param byteOffset zero index to write 522 * @param littleEndian read as little or big endian 523 */ 524 public setInt32(byteOffset: int, value: int, littleEndian: boolean): void { 525 if (littleEndian) { 526 this.setInt32Little(byteOffset, value) 527 } else { 528 this.setInt32Big(byteOffset, value) 529 } 530 } 531 532 /** 533 * Read bytes as they represent given type 534 * @param byteOffset zero index to read 535 * @param littleEndian read as little or big endian 536 * @returns read value 537 */ 538 public getInt32(byteOffset: number, littleEndian?: boolean): number { 539 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 540 return this.getInt32Little(byteOffset) 541 } else { 542 return this.getInt32Big(byteOffset) 543 } 544 } 545 546 /** 547 * Read bytes as they represent given type 548 * @param byteOffset zero index to read 549 * @param littleEndian read as little or big endian 550 * @returns read value 551 */ 552 public getInt32(byteOffset: int, littleEndian: boolean): int { 553 if (littleEndian) { 554 return this.getInt32Little(byteOffset) 555 } else { 556 return this.getInt32Big(byteOffset) 557 } 558 } 559 private getInt32Little(byteOffset: int): int { 560 if (byteOffset + 4 > this.byteLength_) { 561 throw new RangeError("wrong index") 562 } 563 let res: int = 0; 564 const startByte = this.byteOffset_ + byteOffset 565 for (let i = 0; i < 4; i++) { 566 let byteVal = this.actualBuffer.at(startByte + i) as int; 567 byteVal &= 0xff 568 res = (res | byteVal << (8 * i)) as int; 569 } 570 return (res as int) as int 571 } 572 private getInt32Little(byteOffset: number): number { 573 let res = this.getInt32Little(byteOffset as int) 574 return res; 575 } 576 577 private setInt32Little(byteOffset: int, value: int): void { 578 if (byteOffset < 0 || byteOffset + 4.0 > this.byteLength_) { 579 throw new RangeError("wrong index") 580 } 581 let bits = value; 582 const startByte = this.byteOffset_ + byteOffset 583 for (let i = 0; i < 4; i++) { 584 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 585 this.actualBuffer.set(startByte + i, byteVal) 586 } 587 } 588 private setInt32Little(byteOffset: number, value: number): void { 589 const val: int = value as int; 590 this.setInt32Little(byteOffset as int, val) 591 } 592 private getInt32Big(byteOffset: int): int { 593 if (byteOffset + 4 > this.byteLength_) { 594 throw new RangeError("wrong index") 595 } 596 let res: int = 0; 597 const startByte = this.byteOffset_ + byteOffset 598 for (let i = 0; i < 4; i++) { 599 let byteVal = this.actualBuffer.at(startByte + 3 - i) as int; 600 byteVal &= 0xff 601 res = (res | byteVal << (8 * i)) as int; 602 } 603 return (res as int) as int 604 } 605 private getInt32Big(byteOffset: number): number { 606 let res = this.getInt32Big(byteOffset as int) 607 return res; 608 } 609 610 private setInt32Big(byteOffset: int, value: int): void { 611 if (byteOffset < 0 || byteOffset + 4.0 > this.byteLength_) { 612 throw new RangeError("wrong index") 613 } 614 let bits = value; 615 const startByte = this.byteOffset_ + byteOffset 616 for (let i = 0; i < 4; i++) { 617 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 618 this.actualBuffer.set(startByte + 3 - i, byteVal) 619 } 620 } 621 private setInt32Big(byteOffset: number, value: number): void { 622 const val: int = value as int; 623 this.setInt32Big(byteOffset as int, val) 624 } 625 // === Uint32 === 626 627 /** 628 * Read bytes as they represent given type 629 * @param byteOffset zero index to read 630 * @returns read value (big endian) 631 */ 632 public getUint32(byteOffset: int): long { 633 return this.getUint32Big(byteOffset) 634 } 635 636 /** 637 * Sets bytes as they represent given type 638 * @param byteOffset zero index to write (big endian) 639 */ 640 public setUint32(byteOffset: int, value: long): void { 641 this.setUint32Big(byteOffset, value) 642 } 643 /** 644 * Sets bytes as they represent given type 645 * @param byteOffset zero index to write 646 * @param littleEndian read as little or big endian 647 */ 648 public setUint32(byteOffset: number, value: number, littleEndian?: boolean): void { 649 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 650 this.setUint32Little(byteOffset, value) 651 } else { 652 this.setUint32Big(byteOffset, value) 653 } 654 } 655 656 /** 657 * Sets bytes as they represent given type 658 * @param byteOffset zero index to write 659 * @param littleEndian read as little or big endian 660 */ 661 public setUint32(byteOffset: int, value: long, littleEndian: boolean): void { 662 if (littleEndian) { 663 this.setUint32Little(byteOffset, value) 664 } else { 665 this.setUint32Big(byteOffset, value) 666 } 667 } 668 669 /** 670 * Read bytes as they represent given type 671 * @param byteOffset zero index to read 672 * @param littleEndian read as little or big endian 673 * @returns read value 674 */ 675 public getUint32(byteOffset: number, littleEndian?: boolean): number { 676 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 677 return this.getUint32Little(byteOffset) 678 } else { 679 return this.getUint32Big(byteOffset) 680 } 681 } 682 683 /** 684 * Read bytes as they represent given type 685 * @param byteOffset zero index to read 686 * @param littleEndian read as little or big endian 687 * @returns read value 688 */ 689 public getUint32(byteOffset: int, littleEndian: boolean): long { 690 if (littleEndian) { 691 return this.getUint32Little(byteOffset) 692 } else { 693 return this.getUint32Big(byteOffset) 694 } 695 } 696 private getUint32Little(byteOffset: int): long { 697 if (byteOffset + 4 > this.byteLength_) { 698 throw new RangeError("wrong index") 699 } 700 let res: long = 0; 701 const startByte = this.byteOffset_ + byteOffset 702 for (let i = 0; i < 4; i++) { 703 let byteVal = this.actualBuffer.at(startByte + i) as long; 704 byteVal &= 0xff 705 res = (res | byteVal << (8 * i)) as long; 706 } 707 return res 708 } 709 private getUint32Little(byteOffset: number): number { 710 let res = this.getUint32Little(byteOffset as int) 711 return res; 712 } 713 714 private setUint32Little(byteOffset: int, value: long): void { 715 if (byteOffset < 0 || byteOffset + 4.0 > this.byteLength_) { 716 throw new RangeError("wrong index") 717 } 718 let bits = value; 719 const startByte = this.byteOffset_ + byteOffset 720 for (let i = 0; i < 4; i++) { 721 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 722 this.actualBuffer.set(startByte + i, byteVal) 723 } 724 } 725 private setUint32Little(byteOffset: number, value: number): void { 726 const val: long = value as long; 727 this.setUint32Little(byteOffset as int, val) 728 } 729 private getUint32Big(byteOffset: int): long { 730 if (byteOffset + 4 > this.byteLength_) { 731 throw new RangeError("wrong index") 732 } 733 let res: long = 0; 734 const startByte = this.byteOffset_ + byteOffset 735 for (let i = 0; i < 4; i++) { 736 let byteVal = this.actualBuffer.at(startByte + 3 - i) as long; 737 byteVal &= 0xff 738 res = (res | byteVal << (8 * i)) as long; 739 } 740 return res 741 } 742 private getUint32Big(byteOffset: number): number { 743 let res = this.getUint32Big(byteOffset as int) 744 return res; 745 } 746 747 private setUint32Big(byteOffset: int, value: long): void { 748 if (byteOffset < 0 || byteOffset + 4.0 > this.byteLength_) { 749 throw new RangeError("wrong index") 750 } 751 let bits = value; 752 const startByte = this.byteOffset_ + byteOffset 753 for (let i = 0; i < 4; i++) { 754 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 755 this.actualBuffer.set(startByte + 3 - i, byteVal) 756 } 757 } 758 private setUint32Big(byteOffset: number, value: number): void { 759 const val: long = value as long; 760 this.setUint32Big(byteOffset as int, val) 761 } 762 // === Float32 === 763 764 /** 765 * Read bytes as they represent given type 766 * @param byteOffset zero index to read 767 * @returns read value (big endian) 768 */ 769 public getFloat32(byteOffset: int): float { 770 return this.getFloat32Big(byteOffset) 771 } 772 773 /** 774 * Sets bytes as they represent given type 775 * @param byteOffset zero index to write (big endian) 776 */ 777 public setFloat32(byteOffset: int, value: float): void { 778 this.setFloat32Big(byteOffset, value) 779 } 780 /** 781 * Sets bytes as they represent given type 782 * @param byteOffset zero index to write 783 * @param littleEndian read as little or big endian 784 */ 785 public setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void { 786 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 787 this.setFloat32Little(byteOffset, value) 788 } else { 789 this.setFloat32Big(byteOffset, value) 790 } 791 } 792 793 /** 794 * Sets bytes as they represent given type 795 * @param byteOffset zero index to write 796 * @param littleEndian read as little or big endian 797 */ 798 public setFloat32(byteOffset: int, value: float, littleEndian: boolean): void { 799 if (littleEndian) { 800 this.setFloat32Little(byteOffset, value) 801 } else { 802 this.setFloat32Big(byteOffset, value) 803 } 804 } 805 806 /** 807 * Read bytes as they represent given type 808 * @param byteOffset zero index to read 809 * @param littleEndian read as little or big endian 810 * @returns read value 811 */ 812 public getFloat32(byteOffset: number, littleEndian?: boolean): number { 813 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 814 return this.getFloat32Little(byteOffset) 815 } else { 816 return this.getFloat32Big(byteOffset) 817 } 818 } 819 820 /** 821 * Read bytes as they represent given type 822 * @param byteOffset zero index to read 823 * @param littleEndian read as little or big endian 824 * @returns read value 825 */ 826 public getFloat32(byteOffset: int, littleEndian: boolean): float { 827 if (littleEndian) { 828 return this.getFloat32Little(byteOffset) 829 } else { 830 return this.getFloat32Big(byteOffset) 831 } 832 } 833 private getFloat32Little(byteOffset: int): float { 834 if (byteOffset + 4 > this.byteLength_) { 835 throw new RangeError("wrong index") 836 } 837 let res: int = 0; 838 const startByte = this.byteOffset_ + byteOffset 839 for (let i = 0; i < 4; i++) { 840 let byteVal = this.actualBuffer.at(startByte + i) as int; 841 byteVal &= 0xff 842 res = (res | byteVal << (8 * i)) as int; 843 } 844 return Float.bitCastFromInt(res) 845 } 846 private getFloat32Little(byteOffset: number): number { 847 let res = this.getFloat32Little(byteOffset as int) 848 return res; 849 } 850 851 private setFloat32Little(byteOffset: int, value: float): void { 852 if (byteOffset < 0 || byteOffset + 4.0 > this.byteLength_) { 853 throw new RangeError("wrong index") 854 } 855 let bits = Float.bitCastToInt(value); 856 const startByte = this.byteOffset_ + byteOffset 857 for (let i = 0; i < 4; i++) { 858 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 859 this.actualBuffer.set(startByte + i, byteVal) 860 } 861 } 862 private setFloat32Little(byteOffset: number, value: number): void { 863 const val: float = value as float; 864 this.setFloat32Little(byteOffset as int, val) 865 } 866 private getFloat32Big(byteOffset: int): float { 867 if (byteOffset + 4 > this.byteLength_) { 868 throw new RangeError("wrong index") 869 } 870 let res: int = 0; 871 const startByte = this.byteOffset_ + byteOffset 872 for (let i = 0; i < 4; i++) { 873 let byteVal = this.actualBuffer.at(startByte + 3 - i) as int; 874 byteVal &= 0xff 875 res = (res | byteVal << (8 * i)) as int; 876 } 877 return Float.bitCastFromInt(res) 878 } 879 private getFloat32Big(byteOffset: number): number { 880 let res = this.getFloat32Big(byteOffset as int) 881 return res; 882 } 883 884 private setFloat32Big(byteOffset: int, value: float): void { 885 if (byteOffset < 0 || byteOffset + 4.0 > this.byteLength_) { 886 throw new RangeError("wrong index") 887 } 888 let bits = Float.bitCastToInt(value); 889 const startByte = this.byteOffset_ + byteOffset 890 for (let i = 0; i < 4; i++) { 891 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 892 this.actualBuffer.set(startByte + 3 - i, byteVal) 893 } 894 } 895 private setFloat32Big(byteOffset: number, value: number): void { 896 const val: float = value as float; 897 this.setFloat32Big(byteOffset as int, val) 898 } 899 // === Int64 === 900 901 /** 902 * Read bytes as they represent given type 903 * @param byteOffset zero index to read 904 * @returns read value (big endian) 905 */ 906 public getBigInt64(byteOffset: int): long { 907 return this.getBigInt64Big(byteOffset) 908 } 909 910 /** 911 * Sets bytes as they represent given type 912 * @param byteOffset zero index to write (big endian) 913 */ 914 public setBigInt64(byteOffset: int, value: long): void { 915 this.setBigInt64Big(byteOffset, value) 916 } 917 /** 918 * Sets bytes as they represent given type 919 * @param byteOffset zero index to write 920 * @param littleEndian read as little or big endian 921 */ 922 public setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void { 923 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 924 this.setBigInt64Little(byteOffset, value) 925 } else { 926 this.setBigInt64Big(byteOffset, value) 927 } 928 } 929 930 /** 931 * Sets bytes as they represent given type 932 * @param byteOffset zero index to write 933 * @param littleEndian read as little or big endian 934 */ 935 public setBigInt64(byteOffset: int, value: long, littleEndian: boolean): void { 936 if (littleEndian) { 937 this.setBigInt64Little(byteOffset, value) 938 } else { 939 this.setBigInt64Big(byteOffset, value) 940 } 941 } 942 943 /** 944 * Read bytes as they represent given type 945 * @param byteOffset zero index to read 946 * @param littleEndian read as little or big endian 947 * @returns read value 948 */ 949 public getBigInt64(byteOffset: number, littleEndian?: boolean): bigint { 950 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 951 return this.getBigInt64Little(byteOffset) 952 } else { 953 return this.getBigInt64Big(byteOffset) 954 } 955 } 956 957 /** 958 * Read bytes as they represent given type 959 * @param byteOffset zero index to read 960 * @param littleEndian read as little or big endian 961 * @returns read value 962 */ 963 public getBigInt64(byteOffset: int, littleEndian: boolean): long { 964 if (littleEndian) { 965 return this.getBigInt64Little(byteOffset) 966 } else { 967 return this.getBigInt64Big(byteOffset) 968 } 969 } 970 private getBigInt64Little(byteOffset: int): long { 971 if (byteOffset + 8 > this.byteLength_) { 972 throw new RangeError("wrong index") 973 } 974 let res: long = 0; 975 const startByte = this.byteOffset_ + byteOffset 976 for (let i = 0; i < 8; i++) { 977 let byteVal = this.actualBuffer.at(startByte + i) as long; 978 byteVal &= 0xff 979 res = (res | byteVal << (8 * i)) as long; 980 } 981 return (res as long) as long 982 } 983 private getBigInt64Little(byteOffset: number): bigint { 984 let res = this.getBigInt64Little(byteOffset as int) 985 return new BigInt(res) 986 } 987 988 private setBigInt64Little(byteOffset: int, value: long): void { 989 if (byteOffset < 0 || byteOffset + 8.0 > this.byteLength_) { 990 throw new RangeError("wrong index") 991 } 992 let bits = value; 993 const startByte = this.byteOffset_ + byteOffset 994 for (let i = 0; i < 8; i++) { 995 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 996 this.actualBuffer.set(startByte + i, byteVal) 997 } 998 } 999 private setBigInt64Little(byteOffset: number, value: bigint): void { 1000 const val: long = value.getLong(); 1001 this.setBigInt64Little(byteOffset as int, val) 1002 } 1003 private getBigInt64Big(byteOffset: int): long { 1004 if (byteOffset + 8 > this.byteLength_) { 1005 throw new RangeError("wrong index") 1006 } 1007 let res: long = 0; 1008 const startByte = this.byteOffset_ + byteOffset 1009 for (let i = 0; i < 8; i++) { 1010 let byteVal = this.actualBuffer.at(startByte + 7 - i) as long; 1011 byteVal &= 0xff 1012 res = (res | byteVal << (8 * i)) as long; 1013 } 1014 return (res as long) as long 1015 } 1016 private getBigInt64Big(byteOffset: number): bigint { 1017 let res = this.getBigInt64Big(byteOffset as int) 1018 return new BigInt(res) 1019 } 1020 1021 private setBigInt64Big(byteOffset: int, value: long): void { 1022 if (byteOffset < 0 || byteOffset + 8.0 > this.byteLength_) { 1023 throw new RangeError("wrong index") 1024 } 1025 let bits = value; 1026 const startByte = this.byteOffset_ + byteOffset 1027 for (let i = 0; i < 8; i++) { 1028 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 1029 this.actualBuffer.set(startByte + 7 - i, byteVal) 1030 } 1031 } 1032 private setBigInt64Big(byteOffset: number, value: bigint): void { 1033 const val: long = value.getLong(); 1034 this.setBigInt64Big(byteOffset as int, val) 1035 } 1036 // === Uint64 === 1037 1038 /** 1039 * Read bytes as they represent given type 1040 * @param byteOffset zero index to read 1041 * @returns read value (big endian) 1042 */ 1043 public getBigUint64(byteOffset: int): long { 1044 return this.getBigUint64Big(byteOffset) 1045 } 1046 1047 /** 1048 * Sets bytes as they represent given type 1049 * @param byteOffset zero index to write (big endian) 1050 */ 1051 public setBigUint64(byteOffset: int, value: long): void { 1052 this.setBigUint64Big(byteOffset, value) 1053 } 1054 /** 1055 * Sets bytes as they represent given type 1056 * @param byteOffset zero index to write 1057 * @param littleEndian read as little or big endian 1058 */ 1059 public setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void { 1060 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 1061 this.setBigUint64Little(byteOffset, value) 1062 } else { 1063 this.setBigUint64Big(byteOffset, value) 1064 } 1065 } 1066 1067 /** 1068 * Sets bytes as they represent given type 1069 * @param byteOffset zero index to write 1070 * @param littleEndian read as little or big endian 1071 */ 1072 public setBigUint64(byteOffset: int, value: long, littleEndian: boolean): void { 1073 if (littleEndian) { 1074 this.setBigUint64Little(byteOffset, value) 1075 } else { 1076 this.setBigUint64Big(byteOffset, value) 1077 } 1078 } 1079 1080 /** 1081 * Read bytes as they represent given type 1082 * @param byteOffset zero index to read 1083 * @param littleEndian read as little or big endian 1084 * @returns read value 1085 */ 1086 public getBigUint64(byteOffset: number, littleEndian?: boolean): bigint { 1087 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 1088 return this.getBigUint64Little(byteOffset) 1089 } else { 1090 return this.getBigUint64Big(byteOffset) 1091 } 1092 } 1093 1094 /** 1095 * Read bytes as they represent given type 1096 * @param byteOffset zero index to read 1097 * @param littleEndian read as little or big endian 1098 * @returns read value 1099 */ 1100 public getBigUint64(byteOffset: int, littleEndian: boolean): long { 1101 if (littleEndian) { 1102 return this.getBigUint64Little(byteOffset) 1103 } else { 1104 return this.getBigUint64Big(byteOffset) 1105 } 1106 } 1107 private getBigUint64Little(byteOffset: int): long { 1108 if (byteOffset + 8 > this.byteLength_) { 1109 throw new RangeError("wrong index") 1110 } 1111 let res: long = 0; 1112 const startByte = this.byteOffset_ + byteOffset 1113 for (let i = 0; i < 8; i++) { 1114 let byteVal = this.actualBuffer.at(startByte + i) as long; 1115 byteVal &= 0xff 1116 res = (res | byteVal << (8 * i)) as long; 1117 } 1118 return res 1119 } 1120 private getBigUint64Little(byteOffset: number): bigint { 1121 let res = this.getBigUint64Little(byteOffset as int) 1122 return DataView.bigintFromULong(res) 1123 } 1124 1125 private setBigUint64Little(byteOffset: int, value: long): void { 1126 if (byteOffset < 0 || byteOffset + 8.0 > this.byteLength_) { 1127 throw new RangeError("wrong index") 1128 } 1129 let bits = value; 1130 const startByte = this.byteOffset_ + byteOffset 1131 for (let i = 0; i < 8; i++) { 1132 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 1133 this.actualBuffer.set(startByte + i, byteVal) 1134 } 1135 } 1136 private setBigUint64Little(byteOffset: number, value: bigint): void { 1137 const val: long = value.getLong(); 1138 this.setBigUint64Little(byteOffset as int, val) 1139 } 1140 private getBigUint64Big(byteOffset: int): long { 1141 if (byteOffset + 8 > this.byteLength_) { 1142 throw new RangeError("wrong index") 1143 } 1144 let res: long = 0; 1145 const startByte = this.byteOffset_ + byteOffset 1146 for (let i = 0; i < 8; i++) { 1147 let byteVal = this.actualBuffer.at(startByte + 7 - i) as long; 1148 byteVal &= 0xff 1149 res = (res | byteVal << (8 * i)) as long; 1150 } 1151 return res 1152 } 1153 private getBigUint64Big(byteOffset: number): bigint { 1154 let res = this.getBigUint64Big(byteOffset as int) 1155 return DataView.bigintFromULong(res) 1156 } 1157 1158 private setBigUint64Big(byteOffset: int, value: long): void { 1159 if (byteOffset < 0 || byteOffset + 8.0 > this.byteLength_) { 1160 throw new RangeError("wrong index") 1161 } 1162 let bits = value; 1163 const startByte = this.byteOffset_ + byteOffset 1164 for (let i = 0; i < 8; i++) { 1165 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 1166 this.actualBuffer.set(startByte + 7 - i, byteVal) 1167 } 1168 } 1169 private setBigUint64Big(byteOffset: number, value: bigint): void { 1170 const val: long = value.getLong(); 1171 this.setBigUint64Big(byteOffset as int, val) 1172 } 1173 // === Float64 === 1174 1175 /** 1176 * Read bytes as they represent given type 1177 * @param byteOffset zero index to read 1178 * @returns read value (big endian) 1179 */ 1180 public getFloat64(byteOffset: int): number { 1181 return this.getFloat64Big(byteOffset) 1182 } 1183 1184 /** 1185 * Sets bytes as they represent given type 1186 * @param byteOffset zero index to write (big endian) 1187 */ 1188 public setFloat64(byteOffset: int, value: number): void { 1189 this.setFloat64Big(byteOffset, value) 1190 } 1191 /** 1192 * Sets bytes as they represent given type 1193 * @param byteOffset zero index to write 1194 * @param littleEndian read as little or big endian 1195 */ 1196 public setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void { 1197 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 1198 this.setFloat64Little(byteOffset, value) 1199 } else { 1200 this.setFloat64Big(byteOffset, value) 1201 } 1202 } 1203 1204 /** 1205 * Sets bytes as they represent given type 1206 * @param byteOffset zero index to write 1207 * @param littleEndian read as little or big endian 1208 */ 1209 public setFloat64(byteOffset: int, value: number, littleEndian: boolean): void { 1210 if (littleEndian) { 1211 this.setFloat64Little(byteOffset, value) 1212 } else { 1213 this.setFloat64Big(byteOffset, value) 1214 } 1215 } 1216 1217 /** 1218 * Read bytes as they represent given type 1219 * @param byteOffset zero index to read 1220 * @param littleEndian read as little or big endian 1221 * @returns read value 1222 */ 1223 public getFloat64(byteOffset: number, littleEndian?: boolean): number { 1224 if (littleEndian !== undefined && littleEndian.valueOf() == true) { 1225 return this.getFloat64Little(byteOffset) 1226 } else { 1227 return this.getFloat64Big(byteOffset) 1228 } 1229 } 1230 1231 /** 1232 * Read bytes as they represent given type 1233 * @param byteOffset zero index to read 1234 * @param littleEndian read as little or big endian 1235 * @returns read value 1236 */ 1237 public getFloat64(byteOffset: int, littleEndian: boolean): number { 1238 if (littleEndian) { 1239 return this.getFloat64Little(byteOffset) 1240 } else { 1241 return this.getFloat64Big(byteOffset) 1242 } 1243 } 1244 private getFloat64Little(byteOffset: int): number { 1245 if (byteOffset + 8 > this.byteLength_) { 1246 throw new RangeError("wrong index") 1247 } 1248 let res: long = 0; 1249 const startByte = this.byteOffset_ + byteOffset 1250 for (let i = 0; i < 8; i++) { 1251 let byteVal = this.actualBuffer.at(startByte + i) as long; 1252 byteVal &= 0xff 1253 res = (res | byteVal << (8 * i)) as long; 1254 } 1255 return Double.bitCastFromLong(res) 1256 } 1257 private getFloat64Little(byteOffset: number): number { 1258 let res = this.getFloat64Little(byteOffset as int) 1259 return res; 1260 } 1261 1262 private setFloat64Little(byteOffset: int, value: number): void { 1263 if (byteOffset < 0 || byteOffset + 8.0 > this.byteLength_) { 1264 throw new RangeError("wrong index") 1265 } 1266 let bits = Double.bitCastToLong(value); 1267 const startByte = this.byteOffset_ + byteOffset 1268 for (let i = 0; i < 8; i++) { 1269 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 1270 this.actualBuffer.set(startByte + i, byteVal) 1271 } 1272 } 1273 private setFloat64Little(byteOffset: number, value: number): void { 1274 const val: number = value as number; 1275 this.setFloat64Little(byteOffset as int, val) 1276 } 1277 private getFloat64Big(byteOffset: int): number { 1278 if (byteOffset + 8 > this.byteLength_) { 1279 throw new RangeError("wrong index") 1280 } 1281 let res: long = 0; 1282 const startByte = this.byteOffset_ + byteOffset 1283 for (let i = 0; i < 8; i++) { 1284 let byteVal = this.actualBuffer.at(startByte + 7 - i) as long; 1285 byteVal &= 0xff 1286 res = (res | byteVal << (8 * i)) as long; 1287 } 1288 return Double.bitCastFromLong(res) 1289 } 1290 private getFloat64Big(byteOffset: number): number { 1291 let res = this.getFloat64Big(byteOffset as int) 1292 return res; 1293 } 1294 1295 private setFloat64Big(byteOffset: int, value: number): void { 1296 if (byteOffset < 0 || byteOffset + 8.0 > this.byteLength_) { 1297 throw new RangeError("wrong index") 1298 } 1299 let bits = Double.bitCastToLong(value); 1300 const startByte = this.byteOffset_ + byteOffset 1301 for (let i = 0; i < 8; i++) { 1302 let byteVal = ((bits >>> (i * 8)) & 0xff) as byte 1303 this.actualBuffer.set(startByte + 7 - i, byteVal) 1304 } 1305 } 1306 private setFloat64Big(byteOffset: number, value: number): void { 1307 const val: number = value as number; 1308 this.setFloat64Big(byteOffset as int, val) 1309 } 1310 1311 private static bigintFromULong(x: long): bigint { 1312 const noSignMask: long = ((1 as long) << 63) - 1 1313 return new BigInt(x & noSignMask) + (new BigInt((x >> 63) & 0x1) << new BigInt(63)) 1314 } 1315} 1316