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