1/* 2 * Copyright (c) 2022 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 16function getTypeName(obj: unknown): string { 17 if (obj === null) { 18 return 'null'; 19 } 20 if (typeof obj !== 'object') { 21 return typeof obj; 22 } 23 if (obj != null && obj.constructor != null) { 24 return obj.constructor.name; 25 } 26 return 'unknown'; 27} 28 29class BusinessError extends Error { 30 errorNumber: number; 31 constructor(message: string, errorNumber: number) { 32 super(message); 33 this.name = 'BusinessError'; 34 this.errorNumber = errorNumber; 35 } 36} 37 38let errorMap = { 39 'typeError': 401, 40 'rangeError': 10200001, 41 'bufferSizeError': 10200009, 42 'typeErrorForProperty': 10200013 43}; 44 45enum TypeErrorCategories { 46 COMMON = 0, 47 SIZE, 48 ENCODING, 49 PROPERTY 50}; 51enum RangeErrorCategories { 52 WHOLE = 0, 53 LEFT 54}; 55 56const UINT32MAX = 4294967296; 57 58class ErrorMessage { 59 public errorNumber: number = 0; 60 public argument: string = ''; 61 public types: string[] = []; 62 public receivedObj: unknown = ''; 63 public rangeLeft: string | bigint | number = 0; 64 public rangeRight: string | bigint | number = 0; 65 66 public typeErrorCat: TypeErrorCategories = TypeErrorCategories.COMMON; 67 public rangeErrorCat: RangeErrorCategories = RangeErrorCategories.WHOLE; 68 69 constructor(errNo: number, argument?: string) { 70 this.errorNumber = errNo; 71 this.argument = argument === undefined ? '' : argument; 72 } 73 74 public setTypeInfo(types: string[], receivedObj: unknown): ErrorMessage { 75 this.types = types; 76 this.receivedObj = receivedObj; 77 return this; 78 } 79 80 public setSizeTypeInfo(types: string[], receivedObj: unknown): ErrorMessage { 81 this.types = types; 82 this.receivedObj = receivedObj; 83 this.typeErrorCat = TypeErrorCategories.SIZE; 84 return this; 85 } 86 87 public setEncodingTypeInfo(types: string[], receivedObj: unknown): ErrorMessage { 88 this.types = types; 89 this.receivedObj = receivedObj; 90 this.typeErrorCat = TypeErrorCategories.ENCODING; 91 return this; 92 } 93 94 public setProperty(argument: string): ErrorMessage { 95 this.typeErrorCat = TypeErrorCategories.PROPERTY; 96 this.argument = argument; 97 return this; 98 } 99 100 public setRangeInfo(rangeLeft: string | bigint | number, rangeRight: string | bigint | number, receivedObj: unknown): ErrorMessage { 101 this.rangeLeft = rangeLeft; 102 this.rangeRight = rangeRight; 103 this.receivedObj = receivedObj; 104 return this; 105 } 106 107 public setRangeLeftInfo(rangeLeft: string | number, receivedObj: unknown): ErrorMessage { 108 this.rangeLeft = rangeLeft; 109 this.receivedObj = receivedObj; 110 this.rangeErrorCat = RangeErrorCategories.LEFT; 111 return this; 112 } 113 114 public setSizeInfo(receivedObj: string): ErrorMessage { 115 this.receivedObj = receivedObj; 116 return this; 117 } 118 119 private getErrorTypeStrings(types: string[]): string { 120 let ret = types.join(', '); 121 ret = ret.replace(',', ' or'); 122 return ret; 123 } 124 125 private getArgumentStr(): string { 126 return 'The type of "' + this.argument + '" must be '; 127 } 128 129 private getTypeString(): string { 130 let str = ''; 131 switch (this.typeErrorCat) { 132 case TypeErrorCategories.COMMON: 133 str += this.getArgumentStr() + this.getErrorTypeStrings(this.types) + 134 '. Received value is: ' + getTypeName(this.receivedObj); 135 break; 136 case TypeErrorCategories.SIZE: 137 str += this.getArgumentStr() + this.getErrorTypeStrings(this.types) + 138 ' and the value cannot be negative. Received value is: ' + getTypeName(this.receivedObj); 139 break; 140 case TypeErrorCategories.ENCODING: 141 str += this.getArgumentStr() + this.getErrorTypeStrings(this.types) + 142 '. the encoding ' + this.receivedObj + ' is unknown'; 143 break; 144 case TypeErrorCategories.PROPERTY: 145 str += 'Cannot set property ' + this.argument + ' of Buffer which has only a getter'; 146 default: 147 break; 148 } 149 return str; 150 } 151 152 private getRangeString(): string { 153 let str = ''; 154 switch (this.rangeErrorCat) { 155 case RangeErrorCategories.WHOLE: 156 str += 'The value of "' + this.argument + '" is out of range. It must be >= ' + this.rangeLeft + 157 ' and <= ' + this.rangeRight + '. Received value is: ' + this.receivedObj; 158 break; 159 case RangeErrorCategories.LEFT: 160 str += 'The value of "' + this.argument + '" is out of range. It must be >= ' + this.rangeLeft + 161 '. Received value is: ' + this.receivedObj; 162 break; 163 default: 164 break; 165 } 166 return str; 167 } 168 169 public getString(): string { 170 let str = ''; 171 switch (this.errorNumber) { 172 case 401: //TypeError 173 case 10200013: //TypeErrorForProperty 174 str = this.getTypeString(); 175 break; 176 case 10200001: //RangeError 177 str = this.getRangeString(); 178 break; 179 case 10200009: //BufferSizeError 180 str = 'Buffer size must be a multiple of ' + this.receivedObj; 181 break; 182 default: 183 break; 184 } 185 return str; 186 } 187} 188 189interface NativeBuffer { 190 new(type: number, length: number): NativeBuffer; 191 new(type: number, array: number[]): NativeBuffer; 192 new(type: number, raw: NativeBuffer): NativeBuffer; 193 new(type: number, str: string, encoding: string): NativeBuffer; 194 new(type: number, arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): NativeBuffer; 195 new(type: number, pool: NativeBuffer, poolOffset: number, length: number): NativeBuffer; 196 setArray(array: Array<number>): undefined; 197 getLength(): number; 198 getByteOffset(): number; 199 writeString(value: string, offset: number, length: number, encoding: string): number; 200 fromString(str: string, encoding: string, size: number): NativeBuffer; 201 fillString(value: string, offset: number, end: number, encoding: string): undefined; 202 fillNumbers(value: number[], offset: number, end: number): undefined; 203 fillBuffer(value: NativeBuffer, offset: number, end: number): undefined; 204 writeInt32BE(value: number, offset: number): number; 205 readInt32BE(offset: number): number; 206 writeInt32LE(value: number, offset: number): number; 207 readInt32LE(offset: number): number; 208 writeUInt32BE(value: number, offset: number): number; 209 readUInt32BE(offset: number): number; 210 writeUInt32LE(value: number, offset: number): number; 211 readUInt32LE(offset: number): number; 212 getBufferData(): Array<number>; 213 get(index: number): number; 214 set(index: number, value: number): undefined; 215 subBuffer(start: number, end: number): NativeBuffer; 216 copy(target: NativeBuffer, targetStart: number, sourceStart: number, sourceEnd: number): number; 217 compare(target: NativeBuffer, targetStart: number, sourceStart: number, length: number): number; 218 toUtf8(start: number, end: number): string; 219 toBase64(start: number, end: number): string; 220 indexOf(value: string, byteOffset: number, encoding: string, isReverse: boolean): number; 221} 222interface NativeBlob { 223 new(src: Array<number>): NativeBlob; 224 new(blob: NativeBlob, start: number, end?: number): NativeBlob; 225 arraybuffer(): Promise<ArrayBuffer>; 226 text(): Promise<string>; 227 getBytes(): Array<number>; 228} 229interface IBuffer { 230 Buffer: NativeBuffer; 231 Blob: NativeBlob; 232 utf8ByteLength(str: string): number; 233 utf8StringToNumbers(str: string): Array<number>; 234} 235 236declare function requireInternal(s: string): IBuffer; 237const internalBuffer = requireInternal('buffer'); 238const bufferSymbol = Symbol('bufferClass'); 239const lengthSymbol = Symbol('bufferLength'); 240const bufferEncoding = ['ascii', 'utf8', 'utf-8', 'utf16le', 'utf-16le', 'ucs2', 'ucs-2', 241 'base64', 'base64url', 'latin1', 'binary', 'hex']; 242 243enum ParaType { 244 NUMBER = 0, 245 BUFFER, 246 UINT8ARRAY, 247 ARRAYBUFFER, 248 NUMBERS, 249 STRING 250} 251const initialPoolSize: number = 8 * 1024; 252let poolSize: number; 253let poolOffset: number; 254let pool: Buffer; 255const MAX_LENGTH = Math.pow(2, 32); 256const oneByte: number = 1; 257const twoBytes: number = 2; 258const threeBytes: number = 3; 259const fourBytes: number = 4; 260const fiveBytes: number = 5; 261const sixBytes: number = 6; 262const sevenBytes: number = 7; 263const eightBytes: number = 8; 264 265 266type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | 267 Int32Array | Uint32Array | Float32Array | Float64Array; 268type BackingType = Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer; 269const float64Array: Float64Array = new Float64Array(1); 270const uInt8Float64Array: Uint8Array = new Uint8Array(float64Array.buffer); 271const float32Array: Float32Array = new Float32Array(1); 272const uInt8Float32Array: Uint8Array = new Uint8Array(float32Array.buffer); 273 274function createPool(): void { 275 poolSize = initialPoolSize; 276 pool = new Buffer(poolSize); 277 poolOffset = 0; 278} 279 280function alignPool(): void { 281 if (poolOffset & 0x7) { 282 poolOffset |= 0x7; // 0x7 : align offset based of 8-bits 283 poolOffset++; 284 } 285} 286type Options = { 287 type: string, 288 endings: string 289}; 290 291const _log = console.log; 292 293console.log = function (...args) { 294 if (args.length === 1 && args[0] instanceof Buffer) { 295 let buf: Buffer = args[0]; 296 let bufArr: Array<number> = buf[bufferSymbol].getBufferData(); 297 let getStr = function (bufArr: Array<number>, len: number) { 298 let str = ''; 299 for (let i = 0; i < len; i++) { 300 let strTemp = bufArr[i].toString(16); 301 strTemp = (strTemp.length === 1) ? `0${strTemp}` : strTemp; 302 str += ` ${strTemp}`; 303 } 304 return str; 305 }; 306 let msg = ''; 307 if (bufArr.length > 50) { 308 let bufStr = getStr(bufArr, 50); // 50: Maximum number of log displays 309 msg = bufStr + ` ... ${bufArr.length - 50} more bytes`; 310 } else { 311 msg = getStr(bufArr, bufArr.length); 312 } 313 _log.call(console, `<Buffer ${msg}>`); 314 } else { 315 _log(...args); 316 } 317}; 318 319class Blob { 320 blobClass: NativeBlob; 321 private _size: number; 322 private _type: string; 323 324 public get size(): number { 325 return this._size; 326 } 327 328 public get type(): string { 329 return this._type; 330 } 331 332 constructor(sources: string[] | ArrayBuffer[] | TypedArray[] | DataView[] | Blob[], options: Options) { 333 if (options === undefined) { 334 options = { 335 type: '', 336 endings: 'transparent' 337 }; 338 } 339 typeErrorCheck(options, ['Object'], 'options'); 340 341 let type = options.type ? options.type : ''; 342 let endings = options.endings ? options.endings : 'transparent'; 343 if (endings !== 'transparent' && endings !== 'native') { 344 throw new BusinessError('invalid arg value of options.endings', errorMap.typeError); 345 } 346 let arr: Array<number> = []; 347 if (sources instanceof Array || isTypedArray(sources)) { 348 for (const value of sources) { 349 arr = arr.concat(this.normalizeSource(value)); 350 } 351 } else { 352 throw typeError(sources, 'sources', ['Iterable']); 353 } 354 this._size = arr.length; 355 this._type = type; 356 this.blobClass = new internalBuffer.Blob(arr); 357 } 358 359 normalizeSource(source: string | ArrayBuffer | TypedArray | DataView | Blob | Buffer): Array<number> { 360 let ret: Array<number> = []; 361 if (typeof source === 'string') { 362 return internalBuffer.utf8StringToNumbers(source); 363 } else if (source instanceof ArrayBuffer) { 364 return Array.prototype.slice.call(new Uint8Array(source)); 365 } else if (isTypedArray(source)) { 366 let numbers = Array.prototype.slice.call(source); 367 let str = ''; 368 for (let i = 0, len = numbers.length; i < len; i++) { 369 str += numbers[i].toString(); 370 } 371 let charCodeArr = []; 372 for (let i = 0, len = str.length; i < len; i++) { 373 let code = str.charCodeAt(i); 374 charCodeArr.push(code); 375 } 376 return charCodeArr; 377 } else if (source instanceof DataView) { 378 return Array.prototype.slice.call(new Uint8Array(source.buffer)); 379 } else if (source instanceof Blob) { 380 return source.blobClass.getBytes(); 381 } else if (source instanceof Buffer) { 382 for (let i = 0, len = source.length; i < len; i++) { 383 ret[i] = source[i]; 384 } 385 return ret; 386 } 387 return []; 388 } 389 390 arrayBuffer(): Promise<ArrayBuffer> { 391 return this.blobClass.arraybuffer(); 392 } 393 394 text(): Promise<string> { 395 return this.blobClass.text(); 396 } 397 398 slice(start?: number, end?: number, type?: string): Blob { 399 let newBlob = Object.create(this); 400 if (type !== undefined) { 401 newBlob._type = type; 402 } 403 if (start === undefined) { 404 return newBlob; 405 } 406 if (end === undefined) { 407 newBlob.blobClass = new internalBuffer.Blob(this.blobClass, start); 408 return newBlob; 409 } 410 if (start > end) { 411 return newBlob; 412 } 413 if ((start > 0 && end < 0) || (start < 0 && end > 0)) { 414 return newBlob; 415 } 416 newBlob.blobClass = new internalBuffer.Blob(this.blobClass, start, end); 417 return newBlob; 418 } 419} 420 421let utils = { 422 eightBits: 0xFF, 423 sixtyFourBit: 0xFFFFFFFFn, 424 425 getLowerEight(value: number): number { 426 return value & this.eightBits; 427 }, 428 getLowerSixtyFour(value: bigint): bigint { 429 return value & this.sixtyFourBit; 430 } 431}; 432 433enum Style { 434 intBE = 0, 435 intLE, 436 uintBE, 437 uintLE 438}; 439 440class HandlerBuffer { 441 get(obj: Buffer, prop: string): number | undefined { 442 if (typeof prop === 'number') { 443 if (prop >= obj.length) { 444 return obj[prop]; 445 } 446 return obj[bufferSymbol].get(prop); 447 } 448 return obj[prop]; 449 } 450 set(obj: Buffer, prop: string | symbol, value: number): boolean { 451 if (typeof prop === 'number') { 452 if (prop >= obj.length) { 453 return false; 454 } 455 value = utils.getLowerEight(value); 456 obj[bufferSymbol].set(prop, value); 457 return true; 458 } 459 460 if (prop === lengthSymbol || prop === bufferSymbol) { 461 obj[prop] = value; 462 return true; 463 } else if (prop === 'length' || prop === 'buffer' || prop === 'byteOffset') { 464 throw typeErrorForProperty(prop); 465 } 466 return false; 467 } 468 ownKeys(obj: Buffer): Array<string> { 469 let keys: Array<string> = []; 470 for (let i = 0, len = obj.length; i < len; i++) { 471 keys.push(i.toString()); 472 } 473 return keys; 474 } 475} 476class Buffer { 477 private _arrayBuffer: ArrayBuffer | undefined; 478 479 public get length(): number { 480 return this[lengthSymbol]; 481 } 482 483 public get byteOffset(): number { 484 return this[bufferSymbol].getByteOffset(); 485 } 486 487 public get buffer(): ArrayBufferLike { 488 if (this._arrayBuffer) { 489 return this._arrayBuffer; 490 } 491 let arr = this[bufferSymbol].getBufferData(); 492 return new Uint8Array(arr).buffer; 493 } 494 495 constructor(value: number | Buffer | Uint8Array | ArrayBuffer | Array<number> | string, 496 byteOffsetOrEncoding?: number | string, length?: number) { 497 if (arguments.length === 1) { 498 if (typeof value === 'number') { 499 this[bufferSymbol] = new internalBuffer.Buffer(ParaType.NUMBER, value); 500 } else if (value instanceof Buffer) { 501 this[bufferSymbol] = new internalBuffer.Buffer(ParaType.BUFFER, value[bufferSymbol]); 502 } else if (value instanceof Uint8Array) { 503 this[bufferSymbol] = new internalBuffer.Buffer(ParaType.UINT8ARRAY, value); 504 } else if (value instanceof Array) { 505 this[bufferSymbol] = new internalBuffer.Buffer(ParaType.NUMBERS, value); 506 } 507 } else if (arguments.length === 3 && typeof byteOffsetOrEncoding === 'number' && typeof length === 'number') { 508 if (value instanceof ArrayBuffer) { 509 this[bufferSymbol] = new internalBuffer.Buffer(ParaType.ARRAYBUFFER, value, byteOffsetOrEncoding, length); 510 this._arrayBuffer = value; 511 } else if (value instanceof Buffer) { 512 this[bufferSymbol] = new internalBuffer.Buffer(ParaType.BUFFER, value[bufferSymbol], byteOffsetOrEncoding, length); 513 } 514 } else if (arguments.length === 2 && typeof value === 'string' && typeof byteOffsetOrEncoding === 'string') { 515 this[bufferSymbol] = new internalBuffer.Buffer(ParaType.STRING, value, byteOffsetOrEncoding); 516 } else { 517 this[bufferSymbol] = new internalBuffer.Buffer(ParaType.NUMBER, 0); 518 } 519 this[lengthSymbol] = this[bufferSymbol].getLength(); 520 return new Proxy(this, new HandlerBuffer()); 521 } 522 523 /** 524 * Fills buf with the specified value. If the offset and end are not given, the entire buf will be filled. 525 * @since 9 526 * @syscap SystemCapability.Utils.Lang 527 * @param value The value with which to fill buf 528 * @param [offset = 0] Number of bytes to skip before starting to fill buf 529 * @param [end = buf.length] Where to stop filling buf (not inclusive) 530 * @param [encoding='utf8'] The encoding for value if value is a string 531 * @return A reference to buf 532 */ 533 fill(value: string | Buffer | Uint8Array | number, offset: number = 0, end: number = this.length, 534 encoding: string = 'utf8'): Buffer { 535 if (this.length === 0) { 536 return this; 537 } 538 if (arguments.length === 2) { 539 if (typeof offset === 'string') { 540 encoding = offset; 541 offset = 0; 542 } 543 } else if (arguments.length === 3) { 544 if (typeof end === 'string') { 545 encoding = end; 546 end = this.length; 547 } 548 } 549 if (typeof offset !== 'number') { 550 typeErrorCheck(offset, ['number'], 'offset'); 551 } 552 if (typeof end === 'number') { 553 typeErrorCheck(end, ['number'], 'end'); 554 } 555 if (typeof encoding !== 'string') { 556 typeErrorCheck(encoding, ['string'], 'encoding'); 557 } 558 559 const normalizedEncoding = encodingTypeErrorCheck(encoding); 560 561 rangeErrorCheck(offset, 'offset', 0, UINT32MAX); 562 rangeErrorCheck(end, 'end', 0, this.length); 563 564 if (offset > end - 1) { 565 return this; 566 } 567 if (typeof value === 'string') { 568 if (normalizedEncoding === 'hex') { 569 let numbers = hexStrtoNumbers(value); 570 this[bufferSymbol].fillNumbers(numbers, offset, end); 571 } else { 572 this[bufferSymbol].fillString(value, offset, end, normalizedEncoding); 573 } 574 } 575 if (typeof value === 'number') { 576 let nums: Array<number> = []; 577 nums.push(value & 0xFF); // 0xFF : get lower 8-bits 578 this[bufferSymbol].fillNumbers(nums, offset, end); 579 } 580 if (value instanceof Buffer) { 581 this[bufferSymbol].fillBuffer(value[bufferSymbol], offset, end); 582 } 583 if (value instanceof Uint8Array) { 584 let nums = Array.from(value); 585 this[bufferSymbol].fillNumbers(nums, offset, end); 586 } 587 return this; 588 } 589 590 write(str: string, offset: number = 0, length: number = this.length - offset, encoding: string = 'utf8'): number { 591 typeErrorCheck(str, ['string'], 'str'); 592 if (arguments.length === 1) { 593 return this[bufferSymbol].writeString(str, 0, length, 'utf8'); 594 } else if (arguments.length === 2) { 595 if (typeof offset === 'string') { 596 encoding = offset; 597 let encode = encodingTypeErrorCheck(encoding); 598 return this[bufferSymbol].writeString(str, 0, this.length, encode); 599 } else if (typeof offset === 'number') { 600 rangeErrorCheck(offset, 'offset', 0, this.length - 1); 601 return this[bufferSymbol].writeString(str, offset, length, 'utf8'); 602 } else { 603 throw typeError(offset, 'offset', ['number']); 604 } 605 } else if (arguments.length === 3) { 606 typeErrorCheck(offset, ['number'], 'offset'); 607 rangeErrorCheck(offset, 'offset', 0, this.length - 1); 608 if (typeof length === 'number') { 609 rangeErrorCheck(length, 'length', 0, this.length); 610 length = (length > this.length - offset) ? (this.length - offset) : length; 611 return this[bufferSymbol].writeString(str, offset, length, 'utf8'); 612 } else if (typeof length === 'string') { 613 encoding = length; 614 length = this.length - offset; 615 let encode = encodingTypeErrorCheck(encoding); 616 return this[bufferSymbol].writeString(str, offset, length, encode); 617 } else { 618 throw typeError(length, 'length', ['number']); 619 } 620 } else { 621 if (typeof offset !== 'number') { 622 throw typeError(offset, 'offset', ['number']); 623 } else if (typeof length !== 'number') { 624 throw typeError(length, 'length', ['number']); 625 } else { 626 rangeErrorCheck(offset, 'offset', 0, this.length - 1); 627 let encode = encodingTypeErrorCheck(encoding); 628 length = (length > this.length - offset) ? (this.length - offset) : length; 629 return this[bufferSymbol].writeString(str, offset, length, encode); 630 } 631 } 632 } 633 634 convertToBig64BE(value: bigint, offset: number): number { 635 let byteValue = Number(utils.getLowerSixtyFour(value)); 636 let bitNum = 8; 637 for (let i = bitNum - 1; i > 0; i--) { 638 this[offset + i] = byteValue; 639 if (i === 4) { 640 byteValue = Number(utils.getLowerSixtyFour(value >> 32n)); 641 } else { 642 byteValue = byteValue >> 8; // 8 means offset 8 bits 643 } 644 } 645 this[offset] = byteValue; 646 return offset + 8; 647 } 648 649 convertToBig64LE(value: bigint, offset: number): number { 650 let byteValue = Number(utils.getLowerSixtyFour(value)); 651 let bitNum = 8; 652 for (let i = 0; i < bitNum - 1; i++) { 653 this[offset++] = byteValue; 654 if (i === 3) { 655 byteValue = Number(utils.getLowerSixtyFour(value >> 32n)); // 32 means offset 32-bits 656 } else { 657 byteValue = byteValue >> 8; // 8 means offset 8 bits 658 } 659 } 660 this[offset++] = byteValue; 661 return offset; 662 } 663 664 private readData(offset: number, byteLength: number, style: Style): number | undefined { 665 rangeErrorCheck(byteLength, 'byteLength', oneByte, sixBytes); 666 if (style === Style.intBE) { 667 switch (byteLength) { 668 case oneByte: 669 return this.readInt8(offset); 670 case twoBytes: 671 return this.readInt16BE(offset); 672 case threeBytes: 673 return this.readInt24BE(offset); 674 case fourBytes: 675 return this.readInt32BE(offset); 676 case fiveBytes: 677 return this.readInt40BE(offset); 678 case sixBytes: 679 return this.readInt48BE(offset); 680 default: 681 break; 682 } 683 } else if (style === Style.intLE) { 684 switch (byteLength) { 685 case oneByte: 686 return this.readInt8(offset); 687 case twoBytes: 688 return this.readInt16LE(offset); 689 case threeBytes: 690 return this.readInt24LE(offset); 691 case fourBytes: 692 return this.readInt32LE(offset); 693 case fiveBytes: 694 return this.readInt40LE(offset); 695 case sixBytes: 696 return this.readInt48LE(offset); 697 default: 698 break; 699 } 700 } else if (style === Style.uintLE) { 701 switch (byteLength) { 702 case oneByte: 703 return this.readUInt8(offset); 704 case twoBytes: 705 return this.readUInt16LE(offset); 706 case threeBytes: 707 return this.readUInt24LE(offset); 708 case fourBytes: 709 return this.readUInt32LE(offset); 710 case fiveBytes: 711 return this.readUInt40LE(offset); 712 case sixBytes: 713 return this.readUInt48LE(offset); 714 default: 715 break; 716 } 717 } else if (style === Style.uintBE) { 718 switch (byteLength) { 719 case oneByte: 720 return this.readUInt8(offset); 721 case twoBytes: 722 return this.readUInt16BE(offset); 723 case threeBytes: 724 return this.readUInt24BE(offset); 725 case fourBytes: 726 return this.readUInt32BE(offset); 727 case fiveBytes: 728 return this.readUInt40BE(offset); 729 case sixBytes: 730 return this.readUInt48BE(offset); 731 default: 732 break; 733 } 734 } 735 return undefined; 736 } 737 738 private writeData(value: number, offset: number, byteLength: number, style: Style): number | undefined { 739 rangeErrorCheck(byteLength, 'byteLength', oneByte, sixBytes); 740 if (style === Style.intBE) { 741 switch (byteLength) { 742 case oneByte: 743 return this.writeInt8(value, offset); 744 case twoBytes: 745 return this.writeInt16BE(value, offset); 746 case threeBytes: 747 return this.writeUInt24BE(value, offset); 748 case fourBytes: 749 return this.writeInt32BE(value, offset); 750 case fiveBytes: 751 return this.writeUInt40BE(value, offset); 752 case sixBytes: 753 return this.writeUInt48BE(value, offset); 754 default: 755 break; 756 } 757 } else if (style === Style.intLE) { 758 switch (byteLength) { 759 case oneByte: 760 return this.writeUInt8(value, offset); 761 case twoBytes: 762 return this.writeUInt16LE(value, offset); 763 case threeBytes: 764 return this.writeUInt24LE(value, offset); 765 case fourBytes: 766 return this.writeUInt32LE(value, offset); 767 case fiveBytes: 768 return this.writeUInt40LE(value, offset); 769 case sixBytes: 770 return this.writeUInt48LE(value, offset); 771 default: 772 break; 773 } 774 } else if (style === Style.uintLE) { 775 switch (byteLength) { 776 case oneByte: 777 return this.writeUInt8(value, offset); 778 case twoBytes: 779 return this.writeUInt16LE(value, offset); 780 case threeBytes: 781 return this.writeUInt24LE(value, offset); 782 case fourBytes: 783 return this.writeUInt32LE(value, offset); 784 case fiveBytes: 785 return this.writeUInt40LE(value, offset); 786 case sixBytes: 787 return this.writeUInt48LE(value, offset); 788 default: 789 break; 790 } 791 } else if (style === Style.uintBE) { 792 switch (byteLength) { 793 case oneByte: 794 return this.writeUInt8(value, offset); 795 case twoBytes: 796 return this.writeUInt16BE(value, offset); 797 case threeBytes: 798 return this.writeUInt24BE(value, offset); 799 case fourBytes: 800 return this.writeUInt32BE(value, offset); 801 case fiveBytes: 802 return this.writeUInt40BE(value, offset); 803 case sixBytes: 804 return this.writeUInt48BE(value, offset); 805 default: 806 break; 807 } 808 } 809 return undefined; 810 } 811 812 writeBigInt64BE(value: bigint, offset: number = 0): number { 813 typeErrorCheck(value, ['bigint'], 'value'); 814 typeErrorCheck(offset, ['number'], 'offset'); 815 this.checkOffsetRange(offset, eightBytes); 816 // 2n : 63n : 1n : The range of 64-bit BigInt value is from negative the 63st power of 2 to the 63st power of 2 minus 1 817 rangeErrorCheck(value, 'value', -(2n ** 63n), 2n ** 63n, '-(2n ** 63n)', '2n ** 63n'); 818 return this.convertToBig64BE(value, offset); 819 } 820 821 readBigInt64BE(offset: number = 0): bigint { 822 typeErrorCheck(offset, ['number'], 'offset'); 823 this.checkOffsetRange(offset, eightBytes); 824 const val = (this[offset] << 24) + this.calculationBE(offset + 1, 3); // 24 : 3 : the first val for this[offset] 825 return (BigInt(val) << 32n) + // 32 means offset 32-bits left 826 BigInt(this.calculationBE(offset + 4, 4)); // 4 means offset 4 bytes 827 } 828 829 writeBigInt64LE(value: bigint, offset: number = 0): number { 830 typeErrorCheck(value, ['bigint'], 'value'); 831 typeErrorCheck(offset, ['number'], 'offset'); 832 this.checkOffsetRange(offset, eightBytes); 833 // 2n : 63n : 1n : The range of 64-bit BigInt value is from negative the 63st power of 2 to the 63st power of 2 minus 1 834 rangeErrorCheck(value, 'value', -(2n ** 63n), 2n ** 63n, '-(2n ** 63n)', '2n ** 63n'); 835 836 return this.convertToBig64LE(value, offset); 837 } 838 839 private calculationLE(offset: number, count: number): number { 840 let result: number = 0; 841 for (let i = 0; i < count; i++) { 842 result += this[offset++] * Math.pow(2, 8 * i); // 2 : 8 : Represents offset 843 } 844 return result; 845 } 846 847 private calculationBE(offset: number, count: number): number { 848 let result: number = 0; 849 for (let i = count - 1; i >= 0; i--) { 850 result += this[offset++] * Math.pow(2, 8 * i); // 2 : 8 : Represents offset 851 } 852 return result; 853 } 854 855 readBigInt64LE(offset: number = 0): bigint { 856 typeErrorCheck(offset, ['number'], 'offset'); 857 this.checkOffsetRange(offset, eightBytes); 858 const val = this.calculationLE(offset + 4, 3) + (this[offset + 7] << 24); // 24 means offset 24-bits left 859 return (BigInt(val) << 32n) + BigInt(this.calculationLE(offset, 4)); // 32 means offset 32-bits left 860 } 861 862 writeBigUInt64BE(value: bigint, offset: number = 0): number { 863 typeErrorCheck(value, ['bigint'], 'value'); 864 typeErrorCheck(offset, ['number'], 'offset'); 865 this.checkOffsetRange(offset, eightBytes); 866 // 2n : 64n : 1n : The range of 64-bit BigUInt value is from 0 to the 64st power of 2 minus 1 867 rangeErrorCheck(value, 'value', 0, 2n ** 64n - 1n, '0', '2n ** 64n - 1n'); 868 869 return this.convertToBig64BE(value, offset); 870 } 871 872 readBigUInt64BE(offset: number = 0): bigint { 873 typeErrorCheck(offset, ['number'], 'offset'); 874 this.checkOffsetRange(offset, eightBytes); 875 const hi = this.calculationBE(offset, 4); // 4 means offset 4 bytes 876 877 const lo = this.calculationBE(offset + 4, 4); // 4 means offset 4 bytes 878 return (BigInt(hi) << 32n) + BigInt(lo); // 32 means offset 32-bits left 879 } 880 881 writeBigUInt64LE(value: bigint, offset: number = 0): number { 882 typeErrorCheck(value, ['bigint'], 'value'); 883 typeErrorCheck(offset, ['number'], 'offset'); 884 this.checkOffsetRange(offset, eightBytes); 885 rangeErrorCheck(value, 'value', 0, 2n ** 64n - 1n, '0', '2n ** 64n - 1n'); // 2n : 64n : 1n : The range of BigUInt 886 887 return this.convertToBig64LE(value, offset); 888 } 889 890 readBigUInt64LE(offset: number = 0): bigint { 891 typeErrorCheck(offset, ['number'], 'offset'); 892 this.checkOffsetRange(offset, eightBytes); 893 const lo = this.calculationLE(offset, 4); 894 const hi = this.calculationLE(offset + 4, 4); 895 return BigInt(lo) + (BigInt(hi) << 32n); // 32 means offset 32-bits left 896 } 897 898 writeInt8(value: number, offset: number = 0): number { 899 typeErrorCheck(value, ['number'], 'value'); 900 typeErrorCheck(offset, ['number'], 'offset'); 901 this.checkOffsetRange(offset, oneByte); 902 rangeErrorCheck(value, 'value', - (Math.pow(2, 7)), (Math.pow(2, 7) - 1)); // 2 : 7 : The range of 8-bit Int value 903 value = +value; 904 905 this[offset] = value; 906 return offset + 1; 907 } 908 909 readInt8(offset: number = 0): number { 910 typeErrorCheck(offset, ['number'], 'offset'); 911 this.checkOffsetRange(offset, oneByte); 912 const val = this[offset]; 913 914 return val | (val & Math.pow(2, 7)) * 0x1fffffe; 915 } 916 917 writeInt16BE(value: number, offset: number = 0): number { 918 typeErrorCheck(value, ['number'], 'value'); 919 typeErrorCheck(offset, ['number'], 'offset'); 920 this.checkOffsetRange(offset, twoBytes); 921 rangeErrorCheck(value, 'value', - (Math.pow(2, 15)), (Math.pow(2, 15) - 1)); // 2 : 15 : The range of 16-bit 922 value = +value; 923 this[offset++] = (value >>> 8); // 8 : calculation offset 924 this[offset++] = value; 925 return offset; 926 } 927 928 readInt16BE(offset: number = 0): number { 929 typeErrorCheck(offset, ['number'], 'offset'); 930 this.checkOffsetRange(offset, twoBytes); 931 const val = this.calculationBE(offset, 2); // 2 : calculation offset 932 return val | (val & Math.pow(2, 15)) * 0x1fffe; // 2 : 15 : 0x1fffe : The number of 2 bytes changes to 4 bytes 933 } 934 935 writeInt16LE(value: number, offset: number = 0): number { 936 typeErrorCheck(value, ['number'], 'value'); 937 typeErrorCheck(offset, ['number'], 'offset'); 938 this.checkOffsetRange(offset, twoBytes); 939 rangeErrorCheck(value, 'value', -(Math.pow(2, 15)), (Math.pow(2, 15) - 1)); // 2 : 15 : The range of 16-bit 940 value = +value; 941 this[offset++] = value; 942 this[offset++] = (value >>> 8); 943 return offset; 944 } 945 946 readInt16LE(offset: number = 0): number { 947 typeErrorCheck(offset, ['number'], 'offset'); 948 this.checkOffsetRange(offset, twoBytes); 949 const val = this[offset] + this[offset + 1] * Math.pow(2, 8); // 8 : means offset 8 bits 950 return val | (val & Math.pow(2, 15)) * 0x1fffe; // 2 : 15 : 0x1fffe : The number of 2 bytes changes to 4 bytes 951 } 952 953 readUInt16LE(offset: number = 0): number { 954 typeErrorCheck(offset, ['number'], 'offset'); 955 this.checkOffsetRange(offset, twoBytes); 956 return this[offset] + this[offset + 1] * Math.pow(2, 8); // 8 means offset 8 bits 957 } 958 959 writeUInt8(value: number, offset: number = 0): number { 960 typeErrorCheck(value, ['number'], 'value'); 961 typeErrorCheck(offset, ['number'], 'offset'); 962 this.checkOffsetRange(offset, oneByte); 963 rangeErrorCheck(value, 'value', 0, 255); // 255 : The range of 8-bit UInt value is from 0 to the 8st power of 2 minus 1 964 value = +value; 965 966 this[offset] = value; 967 return offset + 1; 968 } 969 970 readUInt8(offset: number = 0): number { 971 typeErrorCheck(offset, ['number'], 'offset'); 972 this.checkOffsetRange(offset, oneByte); 973 const val = this[offset]; 974 return val; 975 } 976 977 writeIntBE(value: number, offset: number, byteLength: number): number | undefined { 978 typeErrorCheck(value, ['number'], 'value'); 979 typeErrorCheck(offset, ['number'], 'offset'); 980 typeErrorCheck(byteLength, ['number'], 'byteLength'); 981 return this.writeData(value, offset, byteLength, Style.intBE); 982 } 983 984 private writeUInt24BE(value: number, offset: number = 0): number { 985 this.checkOffsetRange(offset, threeBytes); 986 // 2 : 24 : The range of 24-bit UInt value is from 0 to the 24st power of 2 minus 1 987 rangeErrorCheck(value, 'value', 0, 2 ** 24 - 1, '0', '2**24 - 1'); 988 value = +value; 989 for (let i: number = 2; i > 0; i--) { 990 this[offset + i] = value; 991 value = value >>> 8; // 8 means offset 8 bits 992 } 993 this[offset] = value; 994 return offset + 3; // 3 means offset 3 bytes 995 } 996 997 private writeUInt40BE(value: number, offset: number = 0): number { 998 this.checkOffsetRange(offset, fiveBytes); 999 // 2 : 40 : The range of 40-bit UInt value is from 0 to the 40st power of 2 minus 1 1000 rangeErrorCheck(value, 'value', 0, 2 ** 40 - 1, '0', '2**40 - 1'); 1001 value = +value; 1002 this[offset++] = Math.floor(value * Math.pow(2, -32)); // -32 means offset 32 bits to left 1003 for (let i: number = 3; i > 0; i--) { 1004 this[offset + i] = value; 1005 value = value >>> 8; // 8 means offset 8 bits 1006 } 1007 this[offset] = value; 1008 return offset + 4; // 4 means offset 4 bytes 1009 } 1010 1011 private writeUInt48BE(value: number, offset: number = 0): number { 1012 this.checkOffsetRange(offset, sixBytes); 1013 // 2 : 48 : The range of 48-bit UInt value is from 0 to the 48st power of 2 minus 1 1014 rangeErrorCheck(value, 'value', 0, 2 ** 48 - 1, '0', '2**48 - 1'); 1015 value = +value; 1016 const newVal = Math.floor(value * Math.pow(2, -32)); // -32 means offset 32 bits to left 1017 this[offset++] = (newVal >>> 8); 1018 this[offset++] = newVal; 1019 for (let i: number = 3; i > 0; i--) { 1020 this[offset + i] = value; 1021 value = value >>> 8; // 8 means offset 8 bits 1022 } 1023 this[offset] = value; 1024 return offset + 4; // 4 means offset 4 bytes 1025 } 1026 1027 readIntBE(offset: number, byteLength: number): number | undefined { 1028 typeErrorCheck(offset, ['number'], 'offset'); 1029 typeErrorCheck(byteLength, ['number'], 'byteLength'); 1030 return this.readData(offset, byteLength, Style.intBE); 1031 } 1032 1033 private readInt48BE(offset: number = 0): number { 1034 this.checkOffsetRange(offset, sixBytes); 1035 const val = this.calculationBE(offset, 2); 1036 // 2 : 15 : 0x1fffe : The number of 2 bytes changes to 4 bytes, positive high fill 0, negative high fill 1. 1037 return (val | (val & Math.pow(2, 15)) * 0x1fffe) * Math.pow(2, 32) + this.calculationBE(offset + 2, 4); 1038 } 1039 1040 private readInt40BE(offset: number = 0): number { 1041 this.checkOffsetRange(offset, fiveBytes); 1042 const first = this[offset]; 1043 const last = this[offset + 4]; 1044 // 2 : 7 : 0x1fffffe : The number of 1 byte changes to 4 bytes, positive high fill 0, negative high fill 1. 1045 return (this[offset] | (this[offset] & Math.pow(2, 7)) * 0x1fffffe) * Math.pow(2, 32) + // 32 means offset 32 bits 1046 this.calculationBE(++offset, 4); // 4 means offset 4 bytes 1047 } 1048 1049 1050 private readInt24BE(offset: number = 0): number { 1051 this.checkOffsetRange(offset, threeBytes); 1052 const val = this.calculationBE(offset, 3); 1053 // 2 : 23 : 0x1fe : The number of 3 bytes changes to 4 bytes, positive high fill 0, negative high fill 1. 1054 return val | (val & Math.pow(2, 23)) * 0x1fe; 1055 } 1056 1057 writeIntLE(value: number, offset: number, byteLength: number): number | undefined { 1058 typeErrorCheck(value, ['number'], 'value'); 1059 typeErrorCheck(offset, ['number'], 'offset'); 1060 typeErrorCheck(byteLength, ['number'], 'byteLength'); 1061 return this.writeData(value, offset, byteLength, Style.intLE); 1062 } 1063 1064 private writeUInt48LE(value: number, offset: number = 0): number { 1065 this.checkOffsetRange(offset, sixBytes); 1066 // 2 : 48 : The range of 48-bit UInt value is from 0 to the 48st power of 2 minus 1 1067 rangeErrorCheck(value, 'value', 0, 2 ** 48 - 1, '0', '2**48 - 1'); 1068 value = +value; 1069 const newVal = Math.floor(value * Math.pow(2, -32)); // -32 means offset 32 bits to left 1070 for (let i: number = 3; i > 0; i--) { 1071 this[offset++] = value; 1072 value = value >>> 8; // 8 means offset 8 bits 1073 } 1074 this[offset++] = value; 1075 this[offset++] = newVal; 1076 this[offset++] = (newVal >>> 8); // 8 means offset 8 bits 1077 return offset; 1078 } 1079 1080 private writeUInt40LE(value: number, offset: number = 0): number { 1081 this.checkOffsetRange(offset, fiveBytes); 1082 // 2 : 40 : The range of 40-bit UInt value is from 0 to the 40st power of 2 minus 1 1083 rangeErrorCheck(value, 'value', 0, 2 ** 40 - 1, '0', '2**40 - 1'); 1084 value = +value; 1085 const newVal = value; 1086 for (let i: number = 3; i > 0; i--) { 1087 this[offset++] = value; 1088 value = value >>> 8; // 8 means offset 8 bits 1089 } 1090 this[offset++] = value; 1091 this[offset++] = Math.floor(newVal * Math.pow(2, -32)); // -32 means offset 32 bits to left 1092 return offset; 1093 } 1094 1095 private writeUInt24LE(value: number, offset: number = 0): number { 1096 this.checkOffsetRange(offset, threeBytes); 1097 // 2 : 24 : The range of 24-bit UInt value is from 0 to the 24st power of 2 minus 1 1098 rangeErrorCheck(value, 'value', 0, 2 ** 24 - 1, '0', '2**24 - 1'); 1099 value = +value; 1100 for (let i: number = 2; i > 0; i--) { 1101 this[offset++] = value; 1102 value = value >>> 8; // 8 means offset 8 bits 1103 } 1104 this[offset++] = value; 1105 return offset; 1106 } 1107 1108 readIntLE(offset: number, byteLength: number): number | undefined { 1109 typeErrorCheck(offset, ['number'], 'offset'); 1110 typeErrorCheck(byteLength, ['number'], 'byteLength'); 1111 return this.readData(offset, byteLength, Style.intLE); 1112 } 1113 1114 private readInt48LE(offset: number = 0): number { 1115 this.checkOffsetRange(offset, sixBytes); 1116 const val = this.calculationLE(offset + 4, 2); 1117 // 2 : 15 : 0x1fffe : The number of 2 bytes changes to 4 bytes, positive high fill 0, negative high fill 1. 1118 return (val | (val & Math.pow(2, 15)) * 0x1fffe) * Math.pow(2, 32) + this.calculationLE(offset, 4); 1119 } 1120 1121 private readInt40LE(offset: number = 0): number { 1122 this.checkOffsetRange(offset, fiveBytes); 1123 // 2 : 7 : 0x1fffffe : The number of 1 byte changes to 4 bytes, positive high fill 0, negative high fill 1. 1124 return (this[offset + 4] | (this[offset + 4] & Math.pow(2, 7)) * 0x1fffffe) * Math.pow(2, 32) + // 32 means offset 32 bits 1125 this.calculationLE(offset, 4); // 4 means offset 4 bytes 1126 } 1127 1128 private readInt24LE(offset: number = 0): number { 1129 this.checkOffsetRange(offset, threeBytes); 1130 const val = this.calculationLE(offset, 3); // 3 means get 3 bytes 1131 // 2 : 23 : 0x1fe : The number of 3 bytes changes to 4 bytes, positive high fill 0, negative high fill 1. 1132 return val | (val & Math.pow(2, 23)) * 0x1fe; 1133 } 1134 1135 writeUIntLE(value: number, offset: number, byteLength: number): number | undefined { 1136 typeErrorCheck(value, ['number'], 'value'); 1137 typeErrorCheck(offset, ['number'], 'offset'); 1138 typeErrorCheck(byteLength, ['number'], 'byteLength'); 1139 return this.writeData(value, offset, byteLength, Style.uintLE); 1140 } 1141 1142 readUIntLE(offset: number, byteLength: number): number | undefined { 1143 typeErrorCheck(offset, ['number'], 'offset'); 1144 typeErrorCheck(byteLength, ['number'], 'byteLength'); 1145 return this.readData(offset, byteLength, Style.uintLE); 1146 } 1147 1148 private readUInt48LE(offset: number = 0): number { 1149 this.checkOffsetRange(offset, sixBytes); 1150 return this.calculationLE(offset, 4) + 1151 (this.calculationLE(offset + 4, 2)) * Math.pow(2, 32); // 32 means offset 32 bits 1152 } 1153 1154 private readUInt40LE(offset: number = 0): number { 1155 this.checkOffsetRange(offset, fiveBytes); 1156 return this.calculationLE(offset, 5); // 5 means get 5 bytes 1157 } 1158 1159 private readUInt24LE(offset: number = 0): number { 1160 this.checkOffsetRange(offset, threeBytes); 1161 return this.calculationLE(offset, 3); // 3 means get 3 bytes 1162 } 1163 1164 writeUIntBE(value: number, offset: number, byteLength: number): number | undefined { 1165 typeErrorCheck(value, ['number'], 'value'); 1166 typeErrorCheck(offset, ['number'], 'offset'); 1167 typeErrorCheck(byteLength, ['number'], 'byteLength'); 1168 return this.writeData(value, offset, byteLength, Style.uintBE); 1169 } 1170 1171 readUIntBE(offset: number, byteLength: number): number | undefined { 1172 typeErrorCheck(offset, ['number'], 'offset'); 1173 typeErrorCheck(byteLength, ['number'], 'byteLength'); 1174 return this.readData(offset, byteLength, Style.uintBE); 1175 } 1176 1177 private readUInt48BE(offset: number = 0): number { 1178 this.checkOffsetRange(offset, sixBytes); 1179 return (this.calculationBE(offset, 2)) * Math.pow(2, 32) + // 32 means offset 32 bits 1180 this.calculationBE(offset + 2, 4); // 4 means get 4 bytes 1181 } 1182 1183 private readUInt40BE(offset: number = 0): number { 1184 this.checkOffsetRange(offset, fiveBytes); 1185 return this.calculationBE(offset, 5); // 5 means get 5 bytes 1186 } 1187 1188 private readUInt24BE(offset: number = 0): number { 1189 this.checkOffsetRange(offset, threeBytes); 1190 return this.calculationBE(offset, 3); // 3 means get 3 bytes 1191 } 1192 1193 writeInt32BE(value: number, offset: number = 0): number { 1194 typeErrorCheck(value, ['number'], 'value'); 1195 typeErrorCheck(offset, ['number'], 'offset'); 1196 this.checkOffsetRange(offset, fourBytes); 1197 // 2 : 31 : The range of 32-bit Int value is from negative the 31st power of 2 to the 31st power of 2 minus 1 1198 rangeErrorCheck(value, 'value', - (Math.pow(2, 31)), (Math.pow(2, 31) - 1)); 1199 1200 value = +value; 1201 this[bufferSymbol].writeInt32BE(value, offset); 1202 return offset + 4; // 4 means offset 4 bytes 1203 } 1204 1205 private checkOffsetRange(offset: number, size: number): void { 1206 rangeErrorCheck(offset, 'offset', 0, this.length - size); 1207 } 1208 1209 readInt32BE(offset: number = 0): number { 1210 typeErrorCheck(offset, ['number'], 'offset'); 1211 this.checkOffsetRange(offset, fourBytes); 1212 return this[bufferSymbol].readInt32BE(offset); 1213 } 1214 1215 writeInt32LE(value: number, offset: number = 0): number { 1216 typeErrorCheck(value, ['number'], 'value'); 1217 typeErrorCheck(offset, ['number'], 'offset'); 1218 this.checkOffsetRange(offset, fourBytes); 1219 // 2 : 31 : The range of 32-bit Int value is from negative the 31st power of 2 to the 31st power of 2 minus 1 1220 rangeErrorCheck(value, 'value', - (Math.pow(2, 31)), (Math.pow(2, 31) - 1)); 1221 1222 value = +value; 1223 this[bufferSymbol].writeInt32LE(value, offset); 1224 return offset + 4; // 4 means offset 4 bytes 1225 } 1226 1227 readInt32LE(offset: number = 0): number { 1228 typeErrorCheck(offset, ['number'], 'offset'); 1229 this.checkOffsetRange(offset, fourBytes); 1230 return this[bufferSymbol].readInt32LE(offset); 1231 } 1232 1233 writeUInt32BE(value: number, offset: number = 0): number { 1234 typeErrorCheck(value, ['number'], 'value'); 1235 typeErrorCheck(offset, ['number'], 'offset'); 1236 this.checkOffsetRange(offset, fourBytes); 1237 // 2 : 32 : The range of 32-bit UInt value is from zero to the 32st power of 2 minus 1 1238 rangeErrorCheck(value, 'value', 0, (Math.pow(2, 32) - 1)); 1239 value = +value; 1240 this[bufferSymbol].writeUInt32BE(value, offset); 1241 return offset + 4; // 4 means offset 4 bytes 1242 } 1243 1244 readUInt32BE(offset: number = 0): number { 1245 typeErrorCheck(offset, ['number'], 'offset'); 1246 this.checkOffsetRange(offset, fourBytes); 1247 return this[bufferSymbol].readUInt32BE(offset); 1248 } 1249 1250 writeUInt32LE(value: number, offset: number = 0): number { 1251 typeErrorCheck(value, ['number'], 'value'); 1252 typeErrorCheck(offset, ['number'], 'offset'); 1253 this.checkOffsetRange(offset, fourBytes); 1254 // 2 : 32 : The range of 32-bit UInt value is from zero to the 32st power of 2 minus 1 1255 rangeErrorCheck(value, 'value', 0, (Math.pow(2, 32) - 1)); 1256 value = +value; 1257 this[bufferSymbol].writeUInt32LE(value, offset); 1258 return offset + 4; // 4 means offset 4 bytes 1259 } 1260 1261 readUInt32LE(offset: number = 0): number { 1262 typeErrorCheck(offset, ['number'], 'offset'); 1263 this.checkOffsetRange(offset, fourBytes); 1264 return this[bufferSymbol].readUInt32LE(offset); 1265 } 1266 1267 writeDoubleBE(value: number, offset: number = 0): number { 1268 typeErrorCheck(value, ['number'], 'value'); 1269 typeErrorCheck(offset, ['number'], 'offset'); 1270 this.checkOffsetRange(offset, eightBytes); 1271 1272 value = +value; 1273 float64Array[0] = value; 1274 let i: number = 7; // 7 is uInt8Float64Array->maxIndex 1275 while (i >= 0) { 1276 this[offset++] = uInt8Float64Array[i--]; 1277 } 1278 return offset; 1279 } 1280 1281 readDoubleBE(offset: number = 0): number { 1282 typeErrorCheck(offset, ['number'], 'offset'); 1283 this.checkOffsetRange(offset, eightBytes); 1284 1285 let i: number = 7; // 7 is uInt8Float64Array->maxIndex 1286 while (i >= 0) { 1287 uInt8Float64Array[i--] = this[offset++]; 1288 } 1289 return float64Array[0]; 1290 } 1291 1292 writeDoubleLE(value: number, offset: number = 0): number { 1293 typeErrorCheck(value, ['number'], 'value'); 1294 typeErrorCheck(offset, ['number'], 'offset'); 1295 this.checkOffsetRange(offset, eightBytes); 1296 1297 value = +value; 1298 float64Array[0] = value; 1299 let i: number = 0; 1300 while (i <= 7) { // 7 is uInt8Float64Array->maxIndex 1301 this[offset++] = uInt8Float64Array[i++]; 1302 } 1303 return offset; 1304 } 1305 1306 readDoubleLE(offset: number = 0): number { 1307 typeErrorCheck(offset, ['number'], 'offset'); 1308 this.checkOffsetRange(offset, eightBytes); 1309 1310 let i: number = 0; 1311 while (i <= 7) { // 7 is uInt8Float64Array->maxIndex 1312 uInt8Float64Array[i++] = this[offset++]; 1313 } 1314 return float64Array[0]; 1315 } 1316 1317 writeFloatBE(value: number, offset: number = 0): number { 1318 typeErrorCheck(value, ['number'], 'value'); 1319 typeErrorCheck(offset, ['number'], 'offset'); 1320 this.checkOffsetRange(offset, fourBytes); 1321 1322 value = +value; 1323 float32Array[0] = value; 1324 let i: number = 3; // 3 is uInt8Float32Array->maxIndex 1325 while (i >= 0) { 1326 this[offset++] = uInt8Float32Array[i--]; 1327 } 1328 return offset; 1329 } 1330 1331 readFloatBE(offset: number = 0): number { 1332 typeErrorCheck(offset, ['number'], 'offset'); 1333 this.checkOffsetRange(offset, fourBytes); 1334 1335 let i: number = 3; // 3 is uInt8Float32Array->maxIndex 1336 while (i >= 0) { 1337 uInt8Float32Array[i--] = this[offset++]; 1338 } 1339 return float32Array[0]; 1340 } 1341 1342 writeFloatLE(value: number, offset: number = 0): number { 1343 typeErrorCheck(value, ['number'], 'value'); 1344 typeErrorCheck(offset, ['number'], 'offset'); 1345 this.checkOffsetRange(offset, fourBytes); 1346 1347 value = +value; 1348 float32Array[0] = value; 1349 let i: number = 0; 1350 while (i <= 3) { // 3 is uInt8Float32Array->maxIndex 1351 this[offset++] = uInt8Float32Array[i++]; 1352 } 1353 return offset; 1354 } 1355 1356 readFloatLE(offset: number): number { 1357 if (offset === undefined || offset === null) { 1358 offset = 0; 1359 } 1360 typeErrorCheck(offset, ['number'], 'offset'); 1361 this.checkOffsetRange(offset, fourBytes); 1362 let i: number = 0; 1363 while (i <= 3) { // 3 is uInt8Float32Array->maxIndex 1364 uInt8Float32Array[i++] = this[offset++]; 1365 } 1366 return float32Array[0]; 1367 } 1368 1369 writeUInt16BE(value: number, offset: number = 0): number { 1370 typeErrorCheck(value, ['number'], 'value'); 1371 typeErrorCheck(offset, ['number'], 'offset'); 1372 this.checkOffsetRange(offset, twoBytes); 1373 // 2 : 16 : The range of 32-bit Int value is from zero to the 16st power of 2 minus 1 1374 rangeErrorCheck(value, 'value', 0, Math.pow(2, 16) - 1); 1375 value = +value; 1376 this[offset++] = (value >>> 8); // 8 means offset 8 bits 1377 this[offset++] = value; 1378 return offset; 1379 } 1380 1381 readUInt16BE(offset: number = 0): number { 1382 typeErrorCheck(offset, ['number'], 'offset'); 1383 this.checkOffsetRange(offset, twoBytes); 1384 const first = this[offset]; 1385 const last = this[offset + 1]; 1386 return first * Math.pow(2, 8) + last; // 8 means offset 8 bits 1387 } 1388 1389 writeUInt16LE(value: number, offset: number = 0): number { 1390 typeErrorCheck(value, ['number'], 'value'); 1391 typeErrorCheck(offset, ['number'], 'offset'); 1392 this.checkOffsetRange(offset, twoBytes); 1393 // 2 : 16 : The range of 32-bit Int value is from zero to the 16st power of 2 minus 1 1394 rangeErrorCheck(value, 'value', 0, Math.pow(2, 16) - 1); 1395 value = +value; 1396 this[offset++] = value; 1397 this[offset++] = (value >>> 8); // 8 means offset 8 bits 1398 return offset; 1399 } 1400 1401 compare(target: Buffer | Uint8Array, targetStart: number = 0, targetEnd: number = target.length, 1402 sourceStart: number = 0, sourceEnd: number = this.length): number { 1403 typeErrorCheck(target, ['Buffer', 'Uint8Array'], 'target'); 1404 typeErrorCheck(targetStart, ['number'], 'targetStart'); 1405 typeErrorCheck(targetEnd, ['number'], 'targetEnd'); 1406 typeErrorCheck(sourceStart, ['number'], 'sourceStart'); 1407 typeErrorCheck(sourceEnd, ['number'], 'sourceEnd'); 1408 rangeErrorCheck(targetStart, 'targetStart', 0, UINT32MAX); 1409 rangeErrorCheck(targetEnd, 'targetEnd', 0, UINT32MAX); 1410 rangeErrorCheck(targetEnd, 'targetEnd', 0, target.length); 1411 rangeErrorCheck(sourceEnd, 'sourceEnd', 0, this.length); 1412 if (sourceStart >= sourceEnd) { 1413 return (targetStart >= targetEnd ? 0 : -1); 1414 } 1415 if (targetStart >= targetEnd) { 1416 return 1; 1417 } 1418 let length1: number = sourceEnd - sourceStart; 1419 let length2: number = targetEnd - targetStart; 1420 let length: number = length1 > length2 ? length2 : length1; 1421 if (target instanceof Buffer) { 1422 let val = this[bufferSymbol].compare(target[bufferSymbol], targetStart, sourceStart, length); 1423 if (val === 0) { 1424 if (length1 === length2) { 1425 return 0; 1426 } 1427 return length1 < length2 ? -1 : 1; 1428 } else { 1429 return val < 0 ? 1 : -1; 1430 } 1431 } else { 1432 let bufData1 = this[bufferSymbol].getBufferData(); 1433 for (let i = 0; i < length; i++) { 1434 let value1 = +bufData1[i + sourceStart]; 1435 let value2 = +target[i + targetStart]; 1436 if (value1 === value2) { 1437 continue; 1438 } 1439 return value1 < value2 ? -1 : 1; 1440 } 1441 if (length1 === length2) { 1442 return 0; 1443 } 1444 return length1 < length2 ? -1 : 1; 1445 } 1446 } 1447 1448 equals(otherBuffer: Uint8Array | Buffer): boolean { 1449 typeErrorCheck(otherBuffer, ['Buffer', 'Uint8Array'], 'otherBuffer'); 1450 let res = this.compare(otherBuffer, 0, otherBuffer.length, 0, this.length); 1451 return res === 0 ? true : false; 1452 } 1453 1454 subarray(start: number = 0, end: number = this.length): Buffer { 1455 let newBuf = Object.create(this); 1456 start = isNaN(start) ? 0 : Number(start); 1457 end = isNaN(end) ? 0 : Number(end); 1458 end = (end > this.length) ? this.length : end; 1459 if (start < 0 || end < 0 || end <= start) { 1460 return new Buffer(0); 1461 } 1462 newBuf[bufferSymbol] = this[bufferSymbol].subBuffer(start, end); 1463 newBuf[lengthSymbol] = (end - start); 1464 return newBuf; 1465 } 1466 1467 copy(target: Buffer | Uint8Array, targetStart: number = 0, sourceStart: number = 0, 1468 sourceEnd: number = this.length): number { 1469 typeErrorCheck(target, ['Buffer', 'Uint8Array'], 'target'); 1470 targetStart = isNaN(targetStart) ? 0 : Number(targetStart); 1471 sourceStart = isNaN(sourceStart) ? 0 : Number(sourceStart); 1472 sourceEnd = isNaN(sourceEnd) ? 0 : Number(sourceEnd); 1473 rangeLeftErrorCheck(targetStart, 'targetStart', 0); 1474 rangeLeftErrorCheck(sourceStart, 'sourceStart', 0); 1475 rangeLeftErrorCheck(sourceEnd, 'sourceEnd', 0); 1476 if (targetStart >= target.length) { 1477 return 0; 1478 } 1479 if (sourceEnd <= sourceStart || sourceStart >= this.length) { 1480 return 0; 1481 } 1482 if (target instanceof Buffer) { 1483 return this[bufferSymbol].copy(target[bufferSymbol], targetStart, sourceStart, sourceEnd); 1484 } 1485 let sLength: number = sourceEnd; 1486 let tLength: number = target.length; 1487 let length = tLength > sLength ? sLength : tLength; 1488 for (let i = targetStart; i < length; i++) { 1489 target[i] = this[i]; 1490 } 1491 return length - targetStart; 1492 } 1493 1494 toString(encoding: string = 'utf8', start: number = 0, end: number = this.length): string { 1495 let encodObj = getEncodingByType(encoding); 1496 if (!encodObj) { 1497 throw typeErrorForEncoding(encoding, 'encoding'); 1498 } 1499 start = isNaN(start) ? 0 : (Number(start) < 0 ? 0 : Number(start)); 1500 end = isNaN(end) ? 0 : Number(end); 1501 let bufLength = this.length; 1502 if (start >= bufLength || start > end) { 1503 return ''; 1504 } 1505 end = end > bufLength ? bufLength : end; 1506 return encodObj.toString(this, start, end); 1507 } 1508 1509 toJSON(): Object { 1510 if (this.length <= 0) { 1511 return { type: 'Buffer', data: [] }; 1512 } 1513 let data = this[bufferSymbol].getBufferData(); 1514 return { type: 'Buffer', data }; 1515 } 1516 1517 indexOf(value: string | number | Buffer | Uint8Array, byteOffset: number = 0, encoding: string = 'utf8'): number { 1518 typeErrorCheck(value, ['string', 'number', 'Buffer', 'Uint8Array'], 'value'); 1519 if (typeof value === 'string') { 1520 if (typeof byteOffset === 'string') { 1521 encoding = byteOffset; 1522 } 1523 if (typeof byteOffset !== 'number') { 1524 byteOffset = 0; 1525 } 1526 encoding = encodingTypeErrorCheck(encoding); 1527 return this[bufferSymbol].indexOf(value, byteOffset, encoding, false); 1528 } else if (typeof value === 'number') { 1529 value = +value; 1530 if (value < 0 || value > utils.eightBits) { 1531 return -1; 1532 } 1533 let data = this[bufferSymbol].getBufferData(); 1534 return data.indexOf(value, byteOffset); 1535 } else { 1536 let sourceData = this[bufferSymbol].getBufferData(); 1537 if (value instanceof Buffer) { 1538 let targetData = value[bufferSymbol].getBufferData(); 1539 return sourceData.join(',').indexOf(targetData.join(','), byteOffset); 1540 } 1541 return sourceData.join(',').indexOf(value.join(','), byteOffset); 1542 } 1543 } 1544 1545 lastIndexOf(value: string | number | Buffer | Uint8Array, byteOffset: number = 0, 1546 encoding: string = 'utf8'): number { 1547 typeErrorCheck(value, ['string', 'number', 'Buffer', 'Uint8Array'], 'value'); 1548 if (typeof value === 'string') { 1549 if (typeof byteOffset === 'string') { 1550 encoding = byteOffset; 1551 } 1552 if (typeof byteOffset !== 'number') { 1553 byteOffset = 0; 1554 } 1555 encoding = encodingTypeErrorCheck(encoding); 1556 return this[bufferSymbol].indexOf(value, byteOffset, encoding, true); 1557 } else if (typeof value === 'number') { 1558 value = +value; 1559 if (value < 0 || value > utils.eightBits) { 1560 return -1; 1561 } 1562 let data = this[bufferSymbol].getBufferData(); 1563 return data.lastIndexOf(value, byteOffset); 1564 } else { 1565 let sourceData = this[bufferSymbol].getBufferData(); 1566 if (value instanceof Buffer) { 1567 let targetData = value[bufferSymbol].getBufferData(); 1568 return sourceData.join(',').lastIndexOf(targetData.join(','), byteOffset); 1569 } 1570 return sourceData.join(',').lastIndexOf(value.join(','), byteOffset); 1571 } 1572 } 1573 1574 includes(value: string | number | Buffer | Uint8Array, byteOffset: number = 0, encoding: string = 'utf8'): boolean { 1575 typeErrorCheck(value, ['string', 'number', 'Buffer', 'Uint8Array'], 'value'); 1576 encoding = encodingTypeErrorCheck(encoding); 1577 return this.indexOf(value, byteOffset, encoding) !== -1; 1578 } 1579 1580 reverseBits(dealNum: number): Buffer { 1581 const len: number = this.length; 1582 const dealLen: number = dealNum; 1583 for (let i = 0; i < len / dealLen; i++) { 1584 let times: number = 0; 1585 let startIndex: number = dealLen * i; 1586 let endIndex: number = startIndex + dealLen - 1; 1587 while (times < dealLen / 2) { 1588 let tmp = this[startIndex + times]; 1589 this[startIndex + times] = this[endIndex - times]; 1590 this[endIndex - times] = tmp; 1591 times++; 1592 } 1593 } 1594 return this; 1595 } 1596 1597 swap16(): Buffer { 1598 const len = this.length; 1599 const dealLen: number = 2; // Process every 2 bits 1600 if (len % dealLen !== 0) { 1601 throw bufferSizeError('16-bits'); 1602 } 1603 return this.reverseBits(dealLen); 1604 } 1605 1606 swap32(): Buffer { 1607 const len = this.length; 1608 const dealLen: number = 4; // Process every 4 bits 1609 if (len % dealLen !== 0) { 1610 throw bufferSizeError('32-bits'); 1611 } 1612 return this.reverseBits(dealLen); 1613 } 1614 1615 swap64(): Buffer { 1616 const len = this.length; 1617 const dealLen: number = 8; // Process every 8 bits 1618 if (len % dealLen !== 0) { 1619 throw bufferSizeError('64-bits'); 1620 } 1621 return this.reverseBits(dealLen); 1622 } 1623 1624 keys(): IterableIterator<number> { 1625 return this[bufferSymbol].getBufferData().keys(); 1626 } 1627 1628 values(): IterableIterator<number> { 1629 return this[bufferSymbol].getBufferData().values(); 1630 } 1631 1632 entries(): IterableIterator<[number, number]> { 1633 return this[bufferSymbol].getBufferData().entries(); 1634 } 1635 1636 [Symbol.iterator]() { 1637 return this[bufferSymbol].getBufferData().entries(); 1638 } 1639} 1640 1641function typeError(param: unknown, paramName: string, excludedTypes: string[]): BusinessError { 1642 let msg = new ErrorMessage(errorMap.typeError, paramName).setTypeInfo(excludedTypes, param).getString(); 1643 return new BusinessError(msg, errorMap.typeError); 1644} 1645 1646function typeErrorForEncoding(param: unknown, paramName: string): BusinessError { 1647 let msg = new ErrorMessage(errorMap.typeError, paramName).setEncodingTypeInfo(['BufferEncoding'], param).getString(); 1648 return new BusinessError(msg, errorMap.typeError); 1649} 1650 1651function typeErrorForProperty(typeName: string): BusinessError { 1652 let msg = new ErrorMessage(errorMap.typeErrorForProperty).setProperty(typeName).getString(); 1653 return new BusinessError(msg, errorMap.typeErrorForProperty); 1654} 1655 1656function typeErrorForSize(param: unknown, paramName: string, excludedTypes: string[]): BusinessError { 1657 let msg = new ErrorMessage(errorMap.typeError, paramName).setSizeTypeInfo(excludedTypes, param).getString(); 1658 return new BusinessError(msg, errorMap.typeError); 1659} 1660 1661function rangeError(paramName: string, rangeLeft: string | bigint | number, rangeRight: string | bigint | number, 1662 receivedValue: number | bigint): BusinessError { 1663 let msg = 1664 new ErrorMessage(errorMap.rangeError, paramName).setRangeInfo(rangeLeft, rangeRight, receivedValue).getString(); 1665 return new BusinessError(msg, errorMap.rangeError); 1666} 1667 1668function rangeLeftError(paramName: string, rangeLeft: number, receivedValue: number): BusinessError { 1669 let msg = new ErrorMessage(errorMap.rangeError, paramName).setRangeLeftInfo(rangeLeft, receivedValue).getString(); 1670 return new BusinessError(msg, errorMap.rangeError); 1671} 1672 1673function bufferSizeError(size: string): BusinessError { 1674 let msg = new ErrorMessage(errorMap.bufferSizeError).setSizeInfo(size).getString(); 1675 return new BusinessError(msg, errorMap.bufferSizeError); 1676} 1677 1678function typeErrorCheck(param: unknown, types: string[], paramName: string): void { 1679 let typeName = getTypeName(param); 1680 if (!types.includes(typeName)) { 1681 throw typeError(param, paramName, types); 1682 } 1683} 1684 1685function sizeErrorCheck(param: unknown, paramName: string, types: string[], 1686 rangeLeft: number, rangeRight: number): void { 1687 let typeName = getTypeName(param); 1688 if (!types.includes(typeName)) { 1689 throw typeErrorForSize(param, paramName, types); 1690 } 1691 if (Number(param) < rangeLeft || Number(param) > rangeRight) { 1692 let typeString = types.join(', '); 1693 typeString = typeString.replace(',', ' or'); 1694 let msg = 'The type of "' + paramName + '" must be ' + typeString + 1695 ' and the value cannot be negative. Received value is: ' + Number(param).toString(); 1696 throw new BusinessError(msg, errorMap.typeError); 1697 } 1698} 1699 1700function encodingTypeErrorCheck(encoding: string): string { 1701 const normalizedEncoding = normalizeEncoding(encoding); 1702 if (normalizedEncoding === undefined) { 1703 throw typeErrorForEncoding(encoding, 'encoding'); 1704 } 1705 return normalizedEncoding; 1706} 1707 1708function rangeErrorCheck(param: number | bigint, paramName: string, rangeLeft: bigint | number, 1709 rangeRight: bigint | number, rangeLeftExpr: string = '', rangeRightExpr: string = ''): void { 1710 let left = BigInt(rangeLeft); 1711 let right = BigInt(rangeRight); 1712 if (param < left || param > right) { 1713 throw rangeError(paramName, rangeLeftExpr === '' ? rangeLeft : rangeLeftExpr, 1714 rangeRightExpr === '' ? rangeRight : rangeRightExpr, param); 1715 } 1716} 1717 1718function rangeLeftErrorCheck(param: number, paramName: string, rangeLeft: number): void { 1719 if (param < rangeLeft) { 1720 throw rangeLeftError(paramName, rangeLeft, param); 1721 } 1722} 1723 1724function concat(list: Buffer[] | Uint8Array[], totalLength?: number): Buffer { 1725 typeErrorCheck(list, ['Array'], 'list'); 1726 if (!(typeof totalLength === 'number' || typeof totalLength === 'undefined')) { 1727 throw typeError(totalLength, 'totalLength', ['number']); 1728 } 1729 if (list.length === 0) { 1730 return new Buffer(0); 1731 } 1732 if (!totalLength) { 1733 totalLength = 0; 1734 for (let i = 0, len = list.length; i < len; i++) { 1735 let buf = list[i]; 1736 if (buf instanceof Uint8Array || buf instanceof Buffer) { 1737 totalLength += list[i].length; 1738 } 1739 } 1740 } 1741 1742 rangeErrorCheck(totalLength, 'totalLength', 0, UINT32MAX); 1743 1744 let buffer = allocUninitializedFromPool(totalLength); 1745 let offset = 0; 1746 for (let i = 0, len = list.length; i < len; i++) { 1747 const buf = list[i]; 1748 if (buf instanceof Uint8Array) { 1749 buf.forEach((val) => buffer[offset++] = val); 1750 } else if (buf instanceof Buffer) { 1751 buf.copy(buffer, offset); 1752 offset += buf.length; 1753 } 1754 } 1755 return buffer; 1756} 1757 1758function alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer { 1759 sizeErrorCheck(size, 'size', ['number'], 0, MAX_LENGTH); 1760 const buf = new Buffer(size); 1761 buf.fill(0); 1762 if (arguments.length === 2 && fill !== undefined && fill !== 0) { 1763 buf.fill(fill); 1764 } else if (arguments.length === 3) { 1765 if (encoding === undefined || encoding === null) { 1766 encoding = 'utf-8'; 1767 } 1768 typeErrorCheck(encoding, ['string'], 'encoding'); 1769 if (fill !== undefined && fill !== 0) { 1770 buf.fill(fill, undefined, undefined, encoding); 1771 } 1772 } 1773 return buf; 1774} 1775 1776function allocUninitializedFromPool(size: number): Buffer { 1777 sizeErrorCheck(size, 'size', ['number'], 0, MAX_LENGTH); 1778 if (!pool) { 1779 createPool(); 1780 } 1781 if (size < (poolSize >>> 1)) { 1782 if (size > (poolSize - poolOffset)) { 1783 createPool(); 1784 } 1785 const b = new Buffer(pool, poolOffset, size); 1786 poolOffset += size; 1787 alignPool(); 1788 return b; 1789 } 1790 return new Buffer(size); 1791} 1792 1793function allocUninitialized(size: number): Buffer { 1794 sizeErrorCheck(size, 'size', ['number'], 0, MAX_LENGTH); 1795 const buf = new Buffer(size); 1796 return buf; 1797} 1798 1799function normalizeEncoding(enc: string): string | undefined { 1800 enc = enc.toLowerCase(); 1801 if (bufferEncoding.includes(enc)) { 1802 if (enc === 'ucs2' || enc === 'ucs-2' || enc === 'utf-16le') { 1803 enc = 'utf16le'; 1804 } 1805 if (enc === 'utf-8') { 1806 enc = 'utf8'; 1807 } 1808 return enc; 1809 } else { 1810 return undefined; 1811 } 1812} 1813 1814function from(value: Buffer | Uint8Array | ArrayBuffer | SharedArrayBuffer | string | object | Array<number>, 1815 offsetOrEncoding?: number | string, length?: number): Buffer { 1816 if (value instanceof ArrayBuffer || value instanceof SharedArrayBuffer) { 1817 offsetOrEncoding = isNaN(Number(offsetOrEncoding)) ? 0 : Number(offsetOrEncoding); 1818 if (offsetOrEncoding < 0) { 1819 throw typeError(offsetOrEncoding, 'offset', ['number']); 1820 } 1821 if (!length) { 1822 length = value.byteLength - offsetOrEncoding; 1823 } else { 1824 length = isNaN(Number(length)) ? 0 : Number(length); 1825 } 1826 rangeErrorCheck(offsetOrEncoding, 'byteOffset', 0, value.byteLength); 1827 rangeErrorCheck(length, 'length', 0, value.byteLength - offsetOrEncoding); 1828 return new Buffer(value, offsetOrEncoding, length); 1829 } 1830 if (value instanceof Buffer) { 1831 return new Buffer(value); 1832 } 1833 if (value instanceof Uint8Array) { 1834 return new Buffer(value); 1835 } 1836 if (value instanceof Array) { 1837 if (!pool) { 1838 createPool(); 1839 } 1840 let buffer = new Buffer(pool, poolOffset, value.length); 1841 poolOffset += value.length; 1842 alignPool(); 1843 buffer[bufferSymbol].setArray(value); 1844 return buffer; 1845 } 1846 let encoding = ''; 1847 if (typeof value === 'string' || typeof value[Symbol.toPrimitive] === 'function') { 1848 offsetOrEncoding = offsetOrEncoding ? offsetOrEncoding : 'utf8'; 1849 if (typeof offsetOrEncoding !== 'string') { 1850 throw typeError(getTypeName(offsetOrEncoding), 'offsetOrEncoding', ['string']); 1851 } else { 1852 encoding = encodingTypeErrorCheck(offsetOrEncoding); 1853 } 1854 } 1855 if (typeof value === 'string') { 1856 return fromString(value, encoding); 1857 } 1858 if (typeof value === 'object' && value !== null) { 1859 const valueOf = value.valueOf && value.valueOf(); 1860 if (valueOf != null && 1861 valueOf !== value && 1862 (typeof valueOf === 'string' || typeof valueOf === 'object')) { 1863 return from(valueOf, offsetOrEncoding, length); 1864 } 1865 if (typeof value[Symbol.toPrimitive] === 'function') { 1866 const primitive = value[Symbol.toPrimitive]('string'); 1867 if (typeof primitive === 'string') { 1868 return fromString(primitive, encoding); 1869 } 1870 } 1871 } 1872 throw typeError(getTypeName(value), 'value', ['Buffer', 'ArrayBuffer', 'Array', 'Array-like']); 1873} 1874 1875function hexStrtoNumbers(hex: string): Array<number> { 1876 let arr = hex.split(''); 1877 let nums: Array<number> = []; 1878 for (let i = 0, len = arr.length; i < len / 2; i++) { 1879 let tmp = '0x' + arr[i * 2] + arr[i * 2 + 1]; 1880 let hexNum = Number(tmp); 1881 if (isNaN(hexNum)) { 1882 if (i === 0) { 1883 throw new Error(`The argument 'value' is invalid. Received "${hex}"`); 1884 } 1885 break; 1886 } 1887 nums[i] = Number(tmp); 1888 } 1889 return nums; 1890} 1891 1892function fromString(value: string, encoding: string): Buffer { 1893 let enc = normalizeEncoding(encoding); 1894 if (!enc) { 1895 throw typeErrorForEncoding(encoding, 'encoding'); 1896 } 1897 let size = byteLength(value, enc); 1898 let buffer = allocUninitializedFromPool(size); 1899 buffer[bufferSymbol].fromString(value, enc, size); 1900 buffer[lengthSymbol] = buffer[bufferSymbol].getLength(); 1901 return buffer; 1902} 1903 1904function isTypedArray(self: unknown): boolean { 1905 let typeArr = [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, 1906 Int32Array, Uint32Array, Float32Array, Float64Array]; 1907 for (let i = 0, len = typeArr.length; i < len; i++) { 1908 if (self instanceof typeArr[i]) { 1909 return true; 1910 } 1911 } 1912 return false; 1913} 1914 1915function isBuffer(obj: Object): boolean { 1916 return obj instanceof Buffer; 1917} 1918 1919function isEncoding(encoding: string): boolean { 1920 if (typeof encoding !== 'string' || encoding.length === 0) { 1921 return false; 1922 } 1923 return getEncodingByType(encoding) ? true : false; 1924} 1925 1926function byteLength(string: string | BackingType, encoding: string = 'utf8'): number { 1927 if (typeof string === 'string' || isTypedArray(string) || 1928 string instanceof DataView || string instanceof ArrayBuffer || 1929 string instanceof SharedArrayBuffer) { 1930 if (string instanceof Buffer) { 1931 return string.length; 1932 } else if (typeof string === 'string') { 1933 if (string.length === 0) { 1934 return 0; 1935 } 1936 let encodRes = getEncodingByType(encoding); 1937 if (!encodRes) { 1938 return getUtf8ByteLength(string); 1939 } 1940 return encodRes.byteLength(string); 1941 } else { 1942 return string.byteLength; 1943 } 1944 } else { 1945 throw typeError(string, 'string', ['string', 'Buffer', 'ArrayBuffer']); 1946 } 1947} 1948 1949function transcode(source: Buffer | Uint8Array, fromEnc: string, toEnc: string): Buffer { 1950 typeErrorCheck(source, ['Buffer', 'Uint8Array'], 'source'); 1951 typeErrorCheck(fromEnc, ['string'], 'fromEnc'); 1952 typeErrorCheck(toEnc, ['string'], 'toEnc'); 1953 let from = source.toString(fromEnc); 1954 return fromString(from, toEnc); 1955} 1956 1957function toUtf8(self: Buffer, start: number, end: number): string { 1958 return self[bufferSymbol].toUtf8(start, end); 1959} 1960 1961function toAscii(self: Buffer, start: number, end: number): string { 1962 let bufData = self[bufferSymbol].getBufferData(); 1963 let val = ''; 1964 for (let i = start; i < end; i++) { 1965 val += String.fromCharCode(+bufData[i] & 0x7F); // 0x7F : get the lower 15-bits 1966 } 1967 return val; 1968} 1969 1970function toBinary(self: Buffer, start: number, end: number): string { 1971 let bufData = self[bufferSymbol].getBufferData(); 1972 let val = ''; 1973 for (let i = start; i < end; i++) { 1974 val += String.fromCharCode(+bufData[i]); 1975 } 1976 return val; 1977} 1978 1979function toHex(self: Buffer, start: number, end: number): string { 1980 let bufData = self[bufferSymbol].getBufferData(); 1981 let str = ''; 1982 for (let i = start, len = end; i < len; i++) { 1983 let tmpstr = Number(bufData[i]).toString(16); // 16 : 16 decimal 1984 tmpstr = (tmpstr.length === 1) ? `0${tmpstr}` : tmpstr; 1985 str += tmpstr; 1986 } 1987 return str; 1988} 1989 1990function toUtf16LE(self: Buffer, start: number, end: number): string { 1991 let bufData: Array<number> = self[bufferSymbol].getBufferData(); 1992 let val = ''; 1993 for (let i = start; i + 1 < end; i += 2) { 1994 val += String.fromCodePoint((bufData[i + 1] << 8) + (bufData[i])); // 8 means offset 8 bits 1995 } 1996 return val; 1997} 1998 1999function toBase64(self: Buffer, start: number, end: number): string { 2000 let str = self[bufferSymbol].toBase64(start, end); 2001 return str; 2002} 2003 2004function getEncodingByType(type: string) { 2005 type = type.toLowerCase(); 2006 switch (type) { 2007 case 'utf8': 2008 case 'utf-8': 2009 return { 2010 byteLength: getUtf8ByteLength, 2011 toString: toUtf8 2012 }; 2013 case 'ucs2': 2014 case 'ucs-2': 2015 return { 2016 byteLength: (str: string) => str.length * 2, // 2 : 2 times of ascii 2017 toString: toUtf16LE 2018 }; 2019 case 'ascii': 2020 case 'latin1': 2021 return { 2022 byteLength: (str: string) => str.length, 2023 toString: toAscii 2024 }; 2025 case 'binary': 2026 return { 2027 byteLength: (str: string) => str.length, 2028 toString: toBinary 2029 }; 2030 case 'utf16le': 2031 case 'utf-16le': 2032 return { 2033 byteLength: (str: string) => str.length * 2, // 2 : 2 times of ascii 2034 toString: toUtf16LE 2035 }; 2036 case 'base64': 2037 case 'base64url': 2038 return { 2039 byteLength: getBase64ByteLength, 2040 toString: toBase64 2041 }; 2042 case 'hex': 2043 return { 2044 byteLength: (str: string) => str.length >>> 1, // 1 : one-half 2045 toString: toHex 2046 }; 2047 default: 2048 return undefined; 2049 } 2050} 2051 2052function getUtf8ByteLength(str: string): number { 2053 return internalBuffer.utf8ByteLength(str); 2054} 2055 2056function getBase64ByteLength(str: string): number { 2057 let bytes = str.length; 2058 for (let i = 0, len = str.length; i < len; i++) { 2059 if (str.charCodeAt(i) === 0x3D) { // 0x3D : ascii code represent of '=' 2060 bytes--; 2061 } 2062 if (bytes > 1 && str.charCodeAt(i) === 0x3D) { // 0x3D : ascii code represent of '=' 2063 bytes--; 2064 } 2065 } 2066 return (bytes * 3) >>> 2; // 3 : 2 : Base64 ratio: 3/4 2067} 2068 2069function compare(buf1: Buffer | Uint8Array, buf2: Buffer | Uint8Array): 1 | 0 | -1 { 2070 if (!(buf1 instanceof Buffer) && !(buf1 instanceof Uint8Array)) { 2071 throw new BusinessError(new ErrorMessage(errorMap.typeError, 'buf1').setTypeInfo(['Buffer', 'Uint8Array'], 2072 getTypeName(buf1)).getString(), errorMap.typeError); 2073 } 2074 if (!(buf2 instanceof Buffer) && !(buf2 instanceof Uint8Array)) { 2075 throw new BusinessError(new ErrorMessage(errorMap.typeError, 'buf2').setTypeInfo(['Buffer', 'Uint8Array'], 2076 getTypeName(buf2)).getString(), errorMap.typeError); 2077 } 2078 2079 let bufData1: Array<number> | Uint8Array; 2080 let bufData2: Array<number> | Uint8Array; 2081 if (buf1 instanceof Buffer) { 2082 bufData1 = buf1[bufferSymbol].getBufferData(); 2083 } else { 2084 bufData1 = buf1; 2085 } 2086 if (buf2 instanceof Buffer) { 2087 bufData2 = buf2[bufferSymbol].getBufferData(); 2088 } else { 2089 bufData2 = buf2; 2090 } 2091 let length1: number = bufData1.length; 2092 let length2: number = bufData2.length; 2093 let length: number = length1 > length2 ? length2 : length1; 2094 for (let i = 0; i < length; i++) { 2095 let value1 = +bufData1[i]; 2096 let value2 = +bufData2[i]; 2097 if (value1 > value2) { 2098 return 1; 2099 } else if (value1 < value2) { 2100 return -1; 2101 } 2102 } 2103 if (length1 > length2) { 2104 return 1; 2105 } else if (length1 < length2) { 2106 return -1; 2107 } 2108 return 0; 2109} 2110 2111export default { 2112 Buffer, 2113 Blob, 2114 from, 2115 alloc, 2116 allocUninitializedFromPool, 2117 allocUninitialized, 2118 byteLength, 2119 isBuffer, 2120 isEncoding, 2121 compare, 2122 concat, 2123 transcode 2124}; 2125