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