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