1/* 2 * Copyright (c) 2021 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 16interface HelpUtil { 17 TextEncoder: Object; 18 TextDecoder: TextDecoder; 19 Base64: Object; 20 Base64Helper: NativeBase64; 21 Types: Object; 22 dealwithformatstring(formatString: string | Array<string | number | Fn>): string; 23 printf(formatString: string | Array<string | number | Fn>, 24 ...valueString: Array<Object>): string; 25 format(formatString: Array<string | number | Fn>, ...valueString: Array<Object>): string 26 geterrorstring(errnum: number): string; 27 errnoToString(errnum: number): string; 28 randomUUID(entropyCache?: boolean): string; 29 randomBinaryUUID(entropyCache?: boolean): Uint8Array; 30 parseUUID(uuid: string): Uint8Array; 31} 32 33interface Fn { 34 (): void; 35} 36 37type AnyType = Object | null | undefined; 38 39declare function requireInternal(s: string): HelpUtil; 40const helpUtil = requireInternal('util'); 41let textEncoder = helpUtil.TextEncoder; 42let base64 = helpUtil.Base64; 43let types = helpUtil.Types; 44 45interface NativeBase64 { 46 new(): NativeBase64; 47 encodeSync(src: Uint8Array): Uint8Array; 48 encodeToStringSync(src: Uint8Array, options?: Type): string; 49 decodeSync(src: Uint8Array | string, options?: Type): Uint8Array; 50 encode(src: Uint8Array): Promise<Uint8Array>; 51 encodeToString(src: Uint8Array, options?: Type): Promise<string>; 52 decode(src: Uint8Array | string, options?: Type): Promise<Uint8Array>; 53} 54 55interface Base64Helper { 56 Base64Helper: NativeBase64; 57} 58 59enum Type { 60 BASIC, 61 MIME 62} 63 64class Base64Helper { 65 base64: NativeBase64; 66 constructor() { 67 this.base64 = new helpUtil.Base64Helper(); 68 } 69 70 encodeSync(src: Uint8Array): Uint8Array { 71 let result: Uint8Array = this.base64.encodeSync(src); 72 return result; 73 } 74 75 private addBreaks(resultString: string): string { 76 const chunkSize = 76; // 76 : MIME format encoding data limitations 77 let i = 0; 78 let newString: string = ''; 79 let stringLength = resultString.length; 80 if (stringLength < chunkSize) { 81 throw new Error('The parameter length does not meet the MIME encoding format'); 82 } 83 while (i < stringLength && stringLength > chunkSize) { 84 let index = i + chunkSize; 85 if (i + chunkSize > stringLength) { 86 index = stringLength; 87 } 88 let temp: string = resultString.substring(i, index); 89 newString = newString + temp + '\r\n'; 90 i += chunkSize; 91 } 92 return newString; 93 } 94 95 encodeToStringSync(src: Uint8Array, options?: Type): string { 96 let resultString: string = this.base64.encodeToStringSync(src); 97 if (options === Type.MIME) { 98 let breakString: string = this.addBreaks(resultString); 99 return breakString; 100 } 101 return resultString; 102 } 103 104 decodeSync(src: Uint8Array | string, options?: Type): Uint8Array { 105 if (typeof src === 'string' && options === Type.MIME) { 106 src = src.replace(/[\r\n]/g, ''); 107 } 108 let result: Uint8Array = this.base64.decodeSync(src); 109 return result; 110 } 111 112 encode(src: Uint8Array): Promise<Uint8Array> { 113 let result: Promise<Uint8Array> = this.base64.encode(src); 114 return result; 115 } 116 117 async processData(src: Uint8Array): Promise<string> { 118 return this.base64.encodeToString(src).then((result: string) => { 119 let breakString: string = this.addBreaks(result); 120 return breakString; 121 }); 122 } 123 124 encodeToString(src: Uint8Array, options?: Type): Promise<string> { 125 if (options === Type.MIME) { 126 let result: Promise<string> = this.processData(src); 127 return result; 128 } 129 let base64Result: Promise<string> = this.base64.encodeToString(src); 130 return base64Result; 131 } 132 133 decode(src: Uint8Array | string, options?: Type): Promise<Uint8Array> { 134 if (typeof src === 'string' && options === Type.MIME) { 135 src = src.replace(/[\r\n]/g, ''); 136 } 137 let result: Promise<Uint8Array> = this.base64.decode(src); 138 return result; 139 } 140} 141 142const typeErrorCode = 401; 143const syntaxErrorCode = 10200002; 144class BusinessError extends Error { 145 code: number; 146 constructor(msg: string) { 147 super(msg); 148 this.name = 'BusinessError'; 149 this.code = typeErrorCode; 150 } 151} 152 153function switchLittleObject(enter: string, obj: Object, count: number): string | Object { 154 let str: string = ''; 155 if (obj === null) { 156 str += obj; 157 } else if (obj instanceof Array) { 158 str += '[ ' + arrayToString(enter, obj, count) + '[length]: ' + obj.length + ' ]'; 159 } else if (typeof obj === 'function') { 160 str += '{ [Function: ' + obj.name + ']' + enter + 161 '[length]: ' + obj.length + ',' + enter + 162 '[name] :\'' + obj.name + '\',' + enter + 163 '[prototype]: ' + obj.name + ' { [constructor]: [Circular] } }'; 164 } else if (typeof obj === 'object') { 165 str += '{ '; 166 let i: string; 167 let flag: boolean = false; 168 for (i in obj) { 169 flag = true; 170 str += switchLittleValue(enter, i, obj, count); 171 } 172 if (!flag) { 173 return obj; 174 } 175 str = str.substr(0, str.length - enter.length - 1); 176 str += ' }'; 177 } else if (typeof obj === 'string') { 178 str += '\'' + obj + '\''; 179 } else { 180 str += obj; 181 } 182 return str; 183} 184 185function switchLittleValue(enter: string, protoName: string, obj: Object, count: number): string { 186 let str: string = ''; 187 if (obj[protoName] === null) { 188 str += protoName + ': null,' + enter; 189 } else if (obj[protoName] instanceof Array) { 190 str += protoName + ':' + enter + 191 '[ ' + arrayToString(enter + ' ', obj[protoName], count) + '[length]: ' + 192 obj[protoName].length + ' ],' + enter; 193 } else if (typeof obj[protoName] === 'object') { 194 if (obj[protoName] === obj) { 195 str += protoName + ': [Circular]' + enter; 196 } else { 197 str += protoName + ':' + enter; 198 str += switchLittleObject(enter + ' ', obj[protoName], count + 1) + ',' + enter; 199 } 200 } else if (typeof obj[protoName] === 'function') { 201 let space: string = enter; 202 if (obj[protoName].name !== '') { 203 str += obj[protoName].name + ':' + space; 204 } 205 space += ' '; 206 str += '{ [Function: ' + obj[protoName].name + ']' + space + 207 '[length]: ' + obj[protoName].length + ',' + space + 208 '[name] :\'' + obj[protoName].name + '\',' + space + 209 '[prototype]: ' + obj[protoName].name + 210 ' { [constructor]: [Circular] } },' + enter; 211 } else { 212 if (typeof obj[protoName] === 'string') { 213 str += protoName + ': \'' + obj[protoName] + '\',' + enter; 214 } else { 215 str += protoName + ': ' + obj[protoName] + ',' + enter; 216 } 217 } 218 return str; 219} 220 221function arrayToString(enter: string, arr: Array<string | number | Fn>, count: number): string { 222 let str: string = ''; 223 if (!arr.length) { 224 return ''; 225 } 226 let arrayEnter: string = ', '; 227 for (let k in arr) { 228 if (arr[k] !== null && (typeof arr[k] === 'function' || typeof arr[k] === 'object') && count <= 2) { 229 arrayEnter += enter; 230 break; 231 } 232 } 233 for (let i of arr) { 234 if (typeof i === 'string') { 235 str += '\'' + i.toString() + '\'' + arrayEnter; 236 } else if (typeof i === 'object') { 237 str += switchLittleObject(enter + ' ', i, count + 1); 238 str += arrayEnter; 239 } else if (typeof i === 'function') { 240 let space: string = enter; 241 space += ' '; 242 let end: string = ''; 243 if (i.name !== '') { 244 str += '{ [Function: ' + i.name + ']' + space; 245 end = i.name + ' { [constructor]: [Circular] } }' + arrayEnter; 246 } else { 247 str += '{ [Function]' + space; 248 end = '{ [constructor]: [Circular] } }' + arrayEnter; 249 } 250 str += '[length]: ' + 251 i.length + ',' + space + 252 '[name] :\'' + i.name + '\',' + space + 253 '[prototype]: ' + end; 254 } else { 255 str += i + arrayEnter; 256 } 257 } 258 return str; 259} 260 261function switchBigObject(enter: string, obj: Object, count: number): string | Object { 262 let str: string = ''; 263 if (obj === null) { 264 str += obj; 265 } else if (obj instanceof Array) { 266 str += '[ ' + arrayToBigString(enter, obj, count) + ' ]'; 267 } else if (typeof obj === 'function') { 268 str += '{ [Function: ' + obj.name + '] }'; 269 } else if (typeof obj === 'object') { 270 str += '{ '; 271 let i: string; 272 let flag: boolean = false; 273 for (i in obj) { 274 flag = true; 275 str += switchBigValue(enter, i, obj, count); 276 } 277 if (!flag) { 278 return obj; 279 } 280 str = str.substr(0, str.length - enter.length - 1); 281 str += ' }'; 282 } else if (typeof obj === 'string') { 283 str += '\'' + obj + '\''; 284 } else { 285 str += obj; 286 } 287 return str; 288} 289 290function switchBigValue(enter: string, protoName: string, obj: Object, count: number): string { 291 let str: string = ''; 292 if (obj[protoName] === null) { 293 str += protoName + ': null,' + enter; 294 } else if (obj[protoName] instanceof Array) { 295 str += protoName + ':' + enter + 296 '[ ' + arrayToBigString(enter + ' ', obj[protoName], count) + ' ],' + enter; 297 } else if (typeof obj[protoName] === 'object') { 298 if (obj[protoName] === obj) { 299 str += protoName + ': [Circular]' + enter; 300 } else { 301 str += protoName + ':' + enter; 302 str += switchBigObject(enter + ' ', obj[protoName], count + 1) + ',' + enter; 303 } 304 } else if (typeof obj[protoName] === 'function') { 305 if (obj[protoName].name !== '') { 306 str += obj[protoName].name + ': '; 307 } 308 str += '[Function: ' + obj[protoName].name + '],' + enter; 309 } else { 310 if (typeof obj[protoName] === 'string') { 311 str += protoName + ': \'' + obj[protoName] + '\',' + enter; 312 } else { 313 str += protoName + ': ' + obj[protoName] + ',' + enter; 314 } 315 } 316 return str; 317} 318 319function arrayToBigString(enter: string, arr: Array<string | number | Fn>, count: number): string { 320 let str: string = ''; 321 if (!arr.length) { 322 return ''; 323 } 324 325 let arrayEnter = ', '; 326 for (let i of arr) { 327 if (i !== null && (typeof i === 'object') && count <= 2) { 328 arrayEnter += enter; 329 break; 330 } 331 } 332 for (let j of arr) { 333 if (typeof j === 'string') { 334 str += '\'' + j + '\'' + arrayEnter; 335 } else if (typeof j === 'object') { 336 str += switchBigObject(enter + ' ', j, count + 1); 337 str += arrayEnter; 338 } else if (typeof j === 'function') { 339 if (j.name !== '') { 340 str += '[Function: ' + j.name + ']' + arrayEnter; 341 } else { 342 str += '[Function]' + arrayEnter; 343 } 344 } else { 345 str += j + arrayEnter; 346 } 347 } 348 str = str.substr(0, str.length - arrayEnter.length); 349 return str; 350} 351 352function switchIntValue(value: Object | symbol): string { 353 let str: string = ''; 354 if (value === '') { 355 str += 'NaN'; 356 } else if (typeof value === 'bigint') { 357 str += value + 'n'; 358 } else if (typeof value === 'symbol') { 359 str += 'NaN'; 360 } else if (typeof value === 'number') { 361 str += parseInt(value.toString(), 10); // 10:The function uses decimal. 362 } else if (value instanceof Array) { 363 if (typeof value[0] === 'number') { 364 str += parseInt(value[0].toString(), 10); // 10:The function uses decimal. 365 } else if (typeof value[0] === 'string') { 366 if (isNaN(Number(value[0]))) { 367 str += 'NaN'; 368 } else { 369 str += parseInt(value[0], 10); // 10:The function uses decimal. 370 } 371 } 372 } else if (typeof value === 'string') { 373 if (isNaN(Number(value))) { 374 str += 'NaN'; 375 } else { 376 str += parseInt(value, 10); // 10:The function uses decimal. 377 } 378 } else { 379 str += 'NaN'; 380 } 381 return str; 382} 383 384function switchFloatValue(value: Object | symbol): string { 385 let str: string = ''; 386 if (value === '') { 387 str += 'NaN'; 388 } else if (typeof value === 'symbol') { 389 str += 'NaN'; 390 } else if (typeof value === 'number') { 391 str += value; 392 } else if (value instanceof Array) { 393 if (typeof value[0] === 'number') { 394 str += parseFloat(value.toString()); 395 } else if (typeof value[0] === 'string') { 396 if (isNaN(Number(value[0]))) { 397 str += 'NaN'; 398 } else { 399 str += parseFloat(value[0]); 400 } 401 } 402 } else if (typeof value === 'string') { 403 if (isNaN(Number(value))) { 404 str += 'NaN'; 405 } else { 406 str += parseFloat(value); 407 } 408 } else if (typeof value === 'bigint') { 409 str += value; 410 } else { 411 str += 'NaN'; 412 } 413 return str; 414} 415 416function switchNumberValue(value: Object | symbol): string { 417 let str: string = ''; 418 if (value === '') { 419 str += '0'; 420 } else if (typeof value === 'symbol') { 421 str += 'NaN'; 422 } else if (typeof value === 'number') { 423 str += value; 424 } else if (value instanceof Array) { 425 str += 'NaN'; 426 } else if (typeof value === 'string') { 427 if (isNaN(Number(value))) { 428 str += 'NaN'; 429 } else { 430 str += Number(value); 431 } 432 } else if (typeof value === 'bigint') { 433 str += value.toString() + 'n'; 434 } else { 435 str += 'NaN'; 436 } 437 return str; 438} 439 440function switchStringValue(value: Object | symbol): string { 441 let str: string = ''; 442 if (typeof value === 'undefined') { 443 str += 'undefined'; 444 } else if (typeof value === 'object') { 445 if (value === null) { 446 str += 'null'; 447 } else { 448 str += value; 449 } 450 } else if (typeof value === 'symbol') { 451 str += value.toString(); 452 } else { 453 str += value; 454 } 455 return str; 456} 457 458// printf(formatString : string | Array<string | number | Fn>, 459// ...valueString : Array<string | number | Fn | object>) : string; 460function printf(formatString: Array<string | number | Fn>, ...valueString: Array<Object>): string { 461 let formats: string = helpUtil.dealwithformatstring(formatString); 462 let arr: Array<Object> = []; 463 arr = formats.split(' '); 464 let switchString: Array<Object> = []; 465 let valueLength: number = valueString.length; 466 let arrLength: number = arr.length; 467 let i: number = 0; 468 for (let sub of valueString) { 469 if (i >= arrLength) { 470 break; 471 } 472 if (arr[i] === 'o') { 473 switchString.push(switchLittleObject('\n ', sub, 1)); 474 } else if (arr[i] === 'O') { 475 switchString.push(switchBigObject('\n ', sub, 1)); 476 } else if (arr[i] === 'i') { 477 switchString.push(switchIntValue(sub)); 478 } else if (arr[i] === 'j') { 479 switchString.push(JSON.stringify(sub)); 480 } else if (arr[i] === 'd') { 481 switchString.push(switchNumberValue(sub)); 482 } else if (arr[i] === 's') { 483 switchString.push(switchStringValue(sub)); 484 } else if (arr[i] === 'f') { 485 switchString.push(switchFloatValue(sub)); 486 } else if (arr[i] === 'c') { 487 switchString.push(sub.toString()); 488 } 489 ++i; 490 } 491 while (i < valueLength) { 492 switchString.push(valueString[i].toString()); 493 i++; 494 } 495 let helpUtilString: string = helpUtil.printf(formatString, ...switchString); 496 return helpUtilString; 497} 498 499function format(formatString: Array<string | number | Fn>, ...valueString: Array<Object>): string { 500 if (!(formatString instanceof Array) && (typeof formatString !== 'string')) { 501 let error = new BusinessError(`Parameter error.The type of ${formatString} must be string or array`); 502 throw error; 503 } 504 let valueLength: number = valueString.length; 505 if (valueLength !== 0) { 506 for (let val of valueString) { 507 if (typeof val !== 'object' && typeof val !== 'number' && 508 typeof val !== 'function' && typeof val !== 'string') { 509 let error = new BusinessError('Parameter error.The type of last parameters must be object'); 510 throw error; 511 } 512 } 513 } 514 let formats: string = helpUtil.dealwithformatstring(formatString); 515 let arr: Array<Object> = []; 516 arr = formats.split(' '); 517 let switchString: Array<Object> = []; 518 let arrLength: number = arr.length; 519 let i: number = 0; 520 for (let sub of valueString) { 521 if (i >= arrLength) { 522 break; 523 } 524 if (arr[i] === 'o') { 525 switchString.push(switchLittleObject('\n ', sub, 1)); 526 } else if (arr[i] === 'O') { 527 switchString.push(switchBigObject('\n ', sub, 1)); 528 } else if (arr[i] === 'i') { 529 switchString.push(switchIntValue(sub)); 530 } else if (arr[i] === 'j') { 531 switchString.push(JSON.stringify(sub)); 532 } else if (arr[i] === 'd') { 533 switchString.push(switchNumberValue(sub)); 534 } else if (arr[i] === 's') { 535 switchString.push(switchStringValue(sub)); 536 } else if (arr[i] === 'f') { 537 switchString.push(switchFloatValue(sub)); 538 } else if (arr[i] === 'c') { 539 switchString.push(sub.toString()); 540 } 541 ++i; 542 } 543 while (i < valueLength) { 544 switchString.push(valueString[i].toString()); 545 i++; 546 } 547 let helpUtilString: string = helpUtil.printf(formatString, ...switchString); 548 return helpUtilString; 549} 550 551function getErrorString(errnum: number): string { 552 let errorString: string = helpUtil.geterrorstring(errnum); 553 return errorString; 554} 555 556function errnoToString(errnum: number): string { 557 if (typeof errnum !== 'number') { 558 let error = new BusinessError(`Parameter error.The type of ${errnum} must be number`); 559 throw error; 560 } 561 let errorString: string = helpUtil.geterrorstring(errnum); 562 return errorString; 563} 564 565function randomUUID(entropyCache?: boolean): string { 566 if (entropyCache === undefined || entropyCache === null) { 567 entropyCache = true; 568 } 569 if (typeof entropyCache !== 'boolean') { 570 let error = new BusinessError(`Parameter error.The type of ${entropyCache} must be boolean`); 571 throw error; 572 } 573 let uuidString: string = helpUtil.randomUUID(entropyCache); 574 return uuidString; 575} 576 577function randomBinaryUUID(entropyCache?: boolean): Uint8Array { 578 if (entropyCache === undefined || entropyCache === null) { 579 entropyCache = true; 580 } 581 if (typeof entropyCache !== 'boolean') { 582 let error = new BusinessError(`Parameter error.The type of ${entropyCache} must be boolean`); 583 throw error; 584 } 585 let uuidArray: Uint8Array = helpUtil.randomBinaryUUID(entropyCache); 586 return uuidArray; 587} 588 589function parseUUID(uuid: string): Uint8Array { 590 let format = /[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}/; 591 if (!format.test(uuid)) { 592 let error = new BusinessError(`Syntax Error.Invalid ${uuid} string`); 593 error.code = syntaxErrorCode; 594 throw error; 595 } 596 let uuidArray: Uint8Array = helpUtil.parseUUID(uuid); 597 return uuidArray; 598} 599 600function callbackified(original: Fn, ...args: Array<string | number | Fn>): void { 601 const maybeCb = args.pop(); 602 if (typeof maybeCb !== 'function') { 603 throw new Error('maybe is not function'); 604 } 605 const cb = (...args: Array<null>) => { 606 Reflect.apply(maybeCb, this, args); 607 }; 608 Reflect.apply(original, this, args).then((ret: null) => cb(null, ret), (rej: null) => cb(rej)); 609} 610 611function getOwnPropertyDescriptors(obj: Fn): PropertyDescriptorMap { 612 const result: PropertyDescriptorMap = {}; 613 for (let key of Reflect.ownKeys(obj)) { 614 if (typeof key === 'string') { 615 result[key] = Object.getOwnPropertyDescriptor(obj, key); 616 } 617 } 618 return result; 619} 620 621function callbackWrapper(original: Fn): Function { 622 if (typeof original !== 'function') { 623 let error = new BusinessError(`Parameter error.The type of ${original} must be function`); 624 throw error; 625 } 626 const descriptors = getOwnPropertyDescriptors(original); 627 if (typeof descriptors.length.value === 'number') { 628 descriptors.length.value++; 629 } 630 if (typeof descriptors.name.value === 'string') { 631 descriptors.name.value += 'callbackified'; 632 } 633 function cb(...args: Array<string | number | Fn>) { 634 callbackified(original, ...args); 635 } 636 Object.defineProperties(cb, descriptors); 637 return cb; 638} 639 640function promiseWrapper(func: Function): Object { 641 return function (...args: Array<Object>) { 642 return new Promise((resolve, reject) => { 643 let callback: Function = function (err: Object | string, ...values: Array<Object>) { 644 if (err) { 645 reject(err); 646 } else { 647 resolve(values); 648 } 649 }; 650 func.apply(null, [...args, callback]); 651 }); 652 }; 653} 654 655function promisify(func: Function): Function { 656 if (typeof func !== 'function') { 657 let error = new BusinessError(`Parameter error.The type of ${func} must be function`); 658 throw error; 659 } 660 return function (...args: Array<Object>) { 661 return new Promise((resolve, reject) => { 662 let callback: Function = function (err: Object | string, ...values: Array<Object>) { 663 if (err) { 664 reject(err); 665 } else { 666 resolve(values); 667 } 668 }; 669 func.apply(null, [...args, callback]); 670 }); 671 }; 672} 673 674interface TextDecoder { 675 new(encoding?: string, options?: { fatal?: boolean; ignoreBOM?: boolean }): TextDecoder; 676} 677 678class TextDecoder { 679 static encodeStr: string = ''; 680 textDecoder: TextDecoder; 681 constructor(encoding?: string, options?: { fatal?: boolean; ignoreBOM?: boolean }) { 682 if (arguments.length === 0) { 683 this.textDecoder = new helpUtil.TextDecoder(); 684 } else if (arguments.length === 1) { 685 this.textDecoder = new helpUtil.TextDecoder(encoding); 686 } else { 687 this.textDecoder = new helpUtil.TextDecoder(encoding, options); 688 } 689 } 690 691 static create(encoding?: string, options?: { fatal?: boolean; ignoreBOM?: boolean }): TextDecoder { 692 if (arguments.length === 0) { 693 TextDecoder.encodeStr = 'utf-8'; 694 return new TextDecoder(); 695 } else if (arguments.length === 1) { 696 if (typeof encoding !== 'string' && encoding !== undefined && encoding !== null) { 697 throw new BusinessError('The type of Parameter must be string.'); 698 } 699 TextDecoder.encodeStr = encoding; 700 return new TextDecoder(encoding); 701 } else { 702 if (typeof encoding !== 'string' && encoding !== undefined && encoding !== null) { 703 throw new BusinessError('The type of Parameter must be string.'); 704 } 705 if (typeof options !== 'object' && options !== undefined && options !== null) { 706 throw new BusinessError('The type of Parameter must be object.'); 707 } 708 TextDecoder.encodeStr = encoding; 709 return new TextDecoder(encoding, options); 710 } 711 } 712 713 public decodeWithStream(input: Uint8Array, options?: { stream?: boolean }): string { 714 const space: number = 32; // space 715 const endString: number = 0; // null 716 let uint8: Uint8Array = new Uint8Array(input); 717 if (TextDecoder.encodeStr === 'utf-8' || TextDecoder.encodeStr === undefined) { 718 uint8.forEach((element, index, array) => { 719 if (element === endString) { 720 array[index] = space; 721 } 722 }); 723 } 724 if (arguments.length === 1) { 725 return this.textDecoder.decodeWithStream(uint8); 726 } 727 return this.textDecoder.decodeWithStream(uint8, options); 728 } 729 730 public decode(input: Uint8Array, options?: { stream?: boolean }): string { 731 if (arguments.length === 1) { 732 return this.textDecoder.decode(input); 733 } 734 return this.textDecoder.decode(input, options); 735 } 736 737 get encoding(): string { 738 return this.textDecoder.encoding; 739 } 740 741 get fatal(): boolean { 742 return this.textDecoder.fatal; 743 } 744 745 get ignoreBOM(): boolean { 746 return this.textDecoder.ignoreBOM; 747 } 748} 749 750class LruBuffer { 751 private cache: Map<Object | undefined, Object | undefined>; 752 // Default current size 753 private maxSize: number = 64; 754 // Default maximum size 755 private maxNumber: number = 2147483647; 756 private putCount: number = 0; 757 private createCount: number = 0; 758 private evictionCount: number = 0; 759 private hitCount: number = 0; 760 private missCount: number = 0; 761 public length: number = 0; 762 763 public constructor(capacity?: number) { 764 if (capacity !== undefined && capacity !== null) { 765 if (capacity <= 0 || capacity % 1 !== 0 || capacity > this.maxNumber) { 766 throw new Error('data error'); 767 } 768 this.maxSize = capacity; 769 } 770 this.cache = new Map(); 771 } 772 773 public updateCapacity(newCapacity: number): void { 774 if (newCapacity <= 0 || newCapacity % 1 !== 0 || newCapacity > this.maxNumber) { 775 throw new Error('data error'); 776 } else if (this.cache.size > newCapacity) { 777 this.changeCapacity(newCapacity); 778 } 779 this.length = this.cache.size; 780 this.maxSize = newCapacity; 781 } 782 783 public get(key: Object): Object { 784 if (key === null) { 785 throw new Error('key not be null'); 786 } 787 let value: Object; 788 if (this.cache.has(key)) { 789 value = this.cache.get(key); 790 this.hitCount++; 791 this.cache.delete(key); 792 this.cache.set(key, value); 793 return value; 794 } 795 796 this.missCount++; 797 let createValue: Object = this.createDefault(key); 798 if (createValue === undefined) { 799 return undefined; 800 } else { 801 value = this.put(key, createValue); 802 this.createCount++; 803 if (value !== undefined) { 804 this.put(key, value); 805 this.afterRemoval(false, key, createValue, value); 806 return value; 807 } 808 return createValue; 809 } 810 } 811 812 public put(key: Object, value: Object): Object { 813 if (key === null || value === null) { 814 throw new Error('key or value not be null'); 815 } 816 let former: Object = undefined; 817 this.putCount++; 818 if (this.cache.has(key)) { 819 former = this.cache.get(key); 820 this.cache.delete(key); 821 this.afterRemoval(false, key, former, value); 822 } else if (this.cache.size >= this.maxSize) { 823 this.afterRemoval(true, this.cache.keys().next().value, this.cache.values().next().value, null); 824 this.cache.delete(this.cache.keys().next().value); 825 this.evictionCount++; 826 } 827 this.cache.set(key, value); 828 this.length = this.cache.size; 829 former = this.cache.get(key); 830 return former; 831 } 832 833 public getCreateCount(): number { 834 return this.createCount; 835 } 836 837 public getMissCount(): number { 838 return this.missCount; 839 } 840 841 public getRemovalCount(): number { 842 return this.evictionCount; 843 } 844 845 public getMatchCount(): number { 846 return this.hitCount; 847 } 848 849 public getPutCount(): number { 850 return this.putCount; 851 } 852 853 public getCapacity(): number { 854 return this.maxSize; 855 } 856 857 public clear(): void { 858 this.afterRemoval(false, this.cache.keys(), this.cache.values(), null); 859 this.cache.clear(); 860 this.length = this.cache.size; 861 } 862 863 public isEmpty(): boolean { 864 let temp: boolean = false; 865 if (this.cache.size === 0) { 866 temp = true; 867 } 868 return temp; 869 } 870 871 public contains(key: Object): boolean { 872 let flag: boolean = false; 873 if (this.cache.has(key)) { 874 flag = true; 875 let value: Object; 876 this.hitCount++; 877 value = this.cache.get(key); 878 this.cache.delete(key); 879 this.cache.set(key, value); 880 this.length = this.cache.size; 881 return flag; 882 } 883 this.missCount++; 884 return flag; 885 } 886 887 public remove(key: Object): Object { 888 if (key === null) { 889 throw new Error('key not be null'); 890 } else if (this.cache.has(key)) { 891 let former: Object; 892 former = this.cache.get(key); 893 this.cache.delete(key); 894 if (former !== null) { 895 this.afterRemoval(false, key, former, null); 896 this.length = this.cache.size; 897 return former; 898 } 899 } 900 this.length = this.cache.size; 901 return undefined; 902 } 903 904 public toString(): string { 905 let peek: number = 0; 906 let hitRate: number = 0; 907 peek = this.hitCount + this.missCount; 908 if (peek !== 0) { 909 // The value is 100 times larger 910 hitRate = 100 * this.hitCount / peek; 911 } else { 912 hitRate = 0; 913 } 914 let str: string = ''; 915 str = 'Lrubuffer[ maxSize = ' + this.maxSize + ', hits = ' + this.hitCount + 916 ', misses = ' + this.missCount + ', hitRate = ' + hitRate + '% ]'; 917 return str; 918 } 919 920 public values(): Object[] { 921 let arr: Array<Object> = []; 922 for (let value of this.cache.values()) { 923 arr.push(value); 924 } 925 return arr; 926 } 927 928 public keys(): Object[] { 929 let arr: Array<Object> = []; 930 for (let key of this.cache.keys()) { 931 arr.push(key); 932 } 933 return arr; 934 } 935 936 protected afterRemoval(isEvict: boolean, key: Object | undefined | null, value: Object | undefined | null, 937 newValue: Object | undefined | null): void { 938 } 939 940 protected createDefault(key: Object): Object { 941 return undefined; 942 } 943 944 public entries(): IterableIterator<[Object, Object]> { 945 return this.cache.entries(); 946 } 947 948 public [Symbol.iterator](): IterableIterator<[Object, Object]> { 949 return this.cache.entries(); 950 } 951 952 private changeCapacity(newCapacity: number): void { 953 while (this.cache.size > newCapacity) { 954 this.cache.delete(this.cache.keys().next().value); 955 this.evictionCount++; 956 this.afterRemoval(true, this.cache.keys(), this.cache.values(), null); 957 } 958 } 959} 960 961class LRUCache { 962 private cache: Map<Object | undefined, Object | undefined>; 963 // Default current size 964 private maxSize: number = 64; 965 // Default maximum size 966 private maxNumber: number = 2147483647; 967 private putCount: number = 0; 968 private createCount: number = 0; 969 private evictionCount: number = 0; 970 private hitCount: number = 0; 971 private missCount: number = 0; 972 public length: number = 0; 973 974 public constructor(capacity?: number) { 975 if (capacity !== undefined && capacity !== null) { 976 if (capacity <= 0 || capacity % 1 !== 0 || capacity > this.maxNumber) { 977 throw new Error('data error'); 978 } 979 this.maxSize = capacity; 980 } 981 this.cache = new Map(); 982 } 983 984 private changeCapacity(newCapacity: number): void { 985 while (this.cache.size > newCapacity) { 986 this.cache.delete(this.cache.keys().next().value); 987 this.evictionCount++; 988 this.afterRemoval(true, this.cache.keys(), this.cache.values(), null); 989 } 990 } 991 992 protected afterRemoval(isEvict: boolean, key: Object | undefined | null, value: Object | undefined | null, 993 newValue: Object | undefined | null): void { 994 } 995 996 protected createDefault(key: Object): Object { 997 if (typeof (key as Object) === 'undefined') { 998 let error = new BusinessError(`Parameter error.The type of ${key} must be Object`); 999 throw error; 1000 } 1001 return undefined; 1002 } 1003 1004 public updateCapacity(newCapacity: number): void { 1005 if (typeof newCapacity !== 'number') { 1006 let error = new BusinessError(`Parameter error.The type of ${newCapacity} must be number`); 1007 throw error; 1008 } 1009 if (newCapacity <= 0 || newCapacity % 1 !== 0 || newCapacity > this.maxNumber) { 1010 throw new Error('data error'); 1011 } else if (this.cache.size > newCapacity) { 1012 this.changeCapacity(newCapacity); 1013 } 1014 this.length = this.cache.size; 1015 this.maxSize = newCapacity; 1016 } 1017 1018 public get(key: Object): Object { 1019 if (typeof (key as Object) === 'undefined') { 1020 let error = new BusinessError(`Parameter error.The type of ${key} must be Object`); 1021 throw error; 1022 } 1023 if (key === null) { 1024 throw new Error('key not be null'); 1025 } 1026 let value: Object; 1027 if (this.cache.has(key)) { 1028 value = this.cache.get(key); 1029 this.hitCount++; 1030 this.cache.delete(key); 1031 this.cache.set(key, value); 1032 return value; 1033 } 1034 1035 this.missCount++; 1036 let createValue: Object = this.createDefault(key); 1037 if (createValue === undefined) { 1038 return undefined; 1039 } else { 1040 value = this.put(key, createValue); 1041 this.createCount++; 1042 if (value !== undefined) { 1043 this.put(key, value); 1044 this.afterRemoval(false, key, createValue, value); 1045 return value; 1046 } 1047 return createValue; 1048 } 1049 } 1050 1051 public put(key: Object, value: Object): Object { 1052 if (typeof (key as Object) === 'undefined') { 1053 let error = new BusinessError(`Parameter error.The type of ${key} must be Object`); 1054 throw error; 1055 } 1056 if (typeof (value as Object) === 'undefined') { 1057 let error = new BusinessError(`Parameter error.The type of ${value} must be Object`); 1058 throw error; 1059 } 1060 if (key === null || value === null) { 1061 throw new Error('key or value not be null'); 1062 } 1063 let former: Object = undefined; 1064 this.putCount++; 1065 if (this.cache.has(key)) { 1066 former = this.cache.get(key); 1067 this.cache.delete(key); 1068 this.afterRemoval(false, key, former, value); 1069 } else if (this.cache.size >= this.maxSize) { 1070 this.afterRemoval(true, this.cache.keys().next().value, this.cache.values().next().value, null); 1071 this.cache.delete(this.cache.keys().next().value); 1072 this.evictionCount++; 1073 } 1074 this.cache.set(key, value); 1075 this.length = this.cache.size; 1076 former = this.cache.get(key); 1077 return former; 1078 } 1079 1080 public remove(key: Object): Object { 1081 if (typeof (key as Object) === 'undefined') { 1082 let error = new BusinessError(`Parameter error.The type of ${key} must be Object`); 1083 throw error; 1084 } 1085 if (key === null) { 1086 throw new Error('key not be null'); 1087 } else if (this.cache.has(key)) { 1088 let former: Object = this.cache.get(key); 1089 this.cache.delete(key); 1090 if (former !== null) { 1091 this.afterRemoval(false, key, former, null); 1092 this.length = this.cache.size; 1093 return former; 1094 } 1095 } 1096 this.length = this.cache.size; 1097 return undefined; 1098 } 1099 1100 public contains(key: Object): boolean { 1101 if (typeof (key as Object) === 'undefined') { 1102 let error = new BusinessError(`Parameter error.The type of ${key} must be Object`); 1103 throw error; 1104 } 1105 let flag: boolean = false; 1106 if (this.cache.has(key)) { 1107 flag = true; 1108 this.hitCount++; 1109 let value: Object = this.cache.get(key); 1110 this.cache.delete(key); 1111 this.cache.set(key, value); 1112 this.length = this.cache.size; 1113 return flag; 1114 } 1115 this.missCount++; 1116 return flag; 1117 } 1118 1119 public getCreateCount(): number { 1120 return this.createCount; 1121 } 1122 1123 public getMissCount(): number { 1124 return this.missCount; 1125 } 1126 1127 public getRemovalCount(): number { 1128 return this.evictionCount; 1129 } 1130 1131 public getMatchCount(): number { 1132 return this.hitCount; 1133 } 1134 1135 public getPutCount(): number { 1136 return this.putCount; 1137 } 1138 1139 public getCapacity(): number { 1140 return this.maxSize; 1141 } 1142 1143 public clear(): void { 1144 this.afterRemoval(false, this.cache.keys(), this.cache.values(), null); 1145 this.cache.clear(); 1146 this.length = this.cache.size; 1147 } 1148 1149 public isEmpty(): boolean { 1150 return this.cache.size === 0; 1151 } 1152 1153 public toString(): string { 1154 let peek: number = 0; 1155 let hitRate: number = 0; 1156 peek = this.hitCount + this.missCount; 1157 if (peek !== 0) { 1158 // The value is 100 times larger 1159 hitRate = 100 * this.hitCount / peek; 1160 } 1161 let str: string = ''; 1162 str = 'LRUCache[ maxSize = ' + this.maxSize + ', hits = ' + this.hitCount + 1163 ', misses = ' + this.missCount + ', hitRate = ' + hitRate + '% ]'; 1164 return str; 1165 } 1166 1167 public values(): Object[] { 1168 let arr: Array<Object> = []; 1169 for (let value of this.cache.values()) { 1170 arr.push(value); 1171 } 1172 return arr; 1173 } 1174 1175 public keys(): Object[] { 1176 let arr: Array<Object> = []; 1177 for (let key of this.cache.keys()) { 1178 arr.push(key); 1179 } 1180 return arr; 1181 } 1182 1183 public entries(): IterableIterator<[Object, Object]> { 1184 return this.cache.entries(); 1185 } 1186 1187 public [Symbol.iterator](): IterableIterator<[Object, Object]> { 1188 return this.cache.entries(); 1189 } 1190} 1191 1192class RationalNumber { 1193 private mnum: number = 0; 1194 private mden: number = 0; 1195 1196 public constructor() 1197 public constructor(num: number, den: number) 1198 public constructor(num?: number, den?: number) { 1199 if (!num && !den) { 1200 1201 } 1202 else { 1203 num = den < 0 ? num * (-1) : num; 1204 den = den < 0 ? den * (-1) : den; 1205 if (den === 0) { 1206 if (num > 0) { 1207 this.mnum = 1; 1208 this.mden = 0; 1209 } else if (num < 0) { 1210 this.mnum = -1; 1211 this.mden = 0; 1212 } else { 1213 this.mnum = 0; 1214 this.mden = 0; 1215 } 1216 } else if (num === 0) { 1217 this.mnum = 0; 1218 this.mden = 1; 1219 } else { 1220 let gnum: number = 0; 1221 gnum = this.getCommonDivisor(num, den); 1222 if (gnum !== 0) { 1223 this.mnum = num / gnum; 1224 this.mden = den / gnum; 1225 } 1226 } 1227 } 1228 } 1229 1230 static parseRationalNumber(num: number, den: number): RationalNumber { 1231 if (typeof num !== 'number') { 1232 let error = new BusinessError(`Parameter error.The type of ${num} must be number`); 1233 throw error; 1234 } 1235 if (typeof den !== 'number') { 1236 let error = new BusinessError(`Parameter error.The type of ${den} must be number`); 1237 throw error; 1238 } 1239 1240 num = den < 0 ? num * (-1) : num; 1241 den = den < 0 ? den * (-1) : den; 1242 let ratNum = new RationalNumber(); 1243 if (den === 0) { 1244 if (num > 0) { 1245 ratNum.mnum = 1; 1246 ratNum.mden = 0; 1247 } else if (num < 0) { 1248 ratNum.mnum = -1; 1249 ratNum.mden = 0; 1250 } else { 1251 ratNum.mnum = 0; 1252 ratNum.mden = 0; 1253 } 1254 } else if (num === 0) { 1255 ratNum.mnum = 0; 1256 ratNum.mden = 1; 1257 } else { 1258 let gnum: number = 0; 1259 gnum = this.getCommonFactor(num, den); 1260 if (gnum !== 0) { 1261 ratNum.mnum = num / gnum; 1262 ratNum.mden = den / gnum; 1263 } 1264 } 1265 return ratNum; 1266 } 1267 1268 static createRationalFromString(str: string): RationalNumber { 1269 if (typeof str !== 'string') { 1270 let error = new BusinessError(`Parameter error.The type of ${str} must be string`); 1271 throw error; 1272 } 1273 if (str === null) { 1274 throw new Error('string invalid!'); 1275 } 1276 let colon: number = str.indexOf(':'); 1277 let semicolon: number = str.indexOf('/'); 1278 if ((colon < 0 && semicolon < 0) || (colon > 0 && semicolon > 0)) { 1279 throw new Error('string invalid!'); 1280 } 1281 let index: number = (colon > 0) ? colon : semicolon; 1282 let s1: string = str.substr(0, index); 1283 let s2: string = str.substr(index + 1, str.length); 1284 let num1: number = Number(s1); 1285 let num2: number = Number(s2); 1286 return RationalNumber.parseRationalNumber(num1, num2); 1287 } 1288 1289 public compareTo(other: RationalNumber): number { 1290 if (this.mnum === other.mnum && this.mden === other.mden) { 1291 return 0; 1292 } else if (this.mnum === 0 && this.mden === 0) { 1293 return 1; 1294 } else if ((other.mnum === 0) && (other.mden === 0)) { 1295 return -1; 1296 } else if ((this.mden === 0 && this.mnum > 0) || (other.mden === 0 && other.mnum < 0)) { 1297 return 1; 1298 } else if ((this.mden === 0 && this.mnum < 0) || (other.mden === 0 && other.mnum > 0)) { 1299 return -1; 1300 } 1301 let thisnum: number = this.mnum * other.mden; 1302 let othernum: number = other.mnum * this.mden; 1303 if (thisnum < othernum) { 1304 return -1; 1305 } else if (thisnum > othernum) { 1306 return 1; 1307 } else { 1308 return 0; 1309 } 1310 } 1311 1312 public compare(other: RationalNumber): number { 1313 if (!(other instanceof RationalNumber)) { 1314 let error = new BusinessError(`Parameter error.The type of ${other} must be RationalNumber`); 1315 throw error; 1316 } 1317 if (this.mnum === other.mnum && this.mden === other.mden) { 1318 return 0; 1319 } else if (this.mnum === 0 && this.mden === 0) { 1320 return 1; 1321 } else if ((other.mnum === 0) && (other.mden === 0)) { 1322 return -1; 1323 } else if ((this.mden === 0 && this.mnum > 0) || (other.mden === 0 && other.mnum < 0)) { 1324 return 1; 1325 } else if ((this.mden === 0 && this.mnum < 0) || (other.mden === 0 && other.mnum > 0)) { 1326 return -1; 1327 } 1328 let thisnum: number = this.mnum * other.mden; 1329 let othernum: number = other.mnum * this.mden; 1330 if (thisnum < othernum) { 1331 return -1; 1332 } else if (thisnum > othernum) { 1333 return 1; 1334 } else { 1335 return 0; 1336 } 1337 } 1338 1339 public equals(obj: object): boolean { 1340 if (!(obj instanceof RationalNumber)) { 1341 return false; 1342 } 1343 let thisnum: number = this.mnum * obj.mden; 1344 let objnum: number = obj.mnum * this.mden; 1345 if (this.mnum === obj.mnum && this.mden === obj.mden) { 1346 return true; 1347 } else if ((thisnum === objnum) && (this.mnum !== 0 && this.mden !== 0) && (obj.mnum !== 0 && obj.mden !== 0)) { 1348 return true; 1349 } else if ((this.mnum === 0 && this.mden !== 0) && (obj.mnum === 0 && obj.mden !== 0)) { 1350 return true; 1351 } else if ((this.mnum > 0 && this.mden === 0) && (obj.mnum > 0 && obj.mden === 0)) { 1352 return true; 1353 } else if ((this.mnum < 0 && this.mden === 0) && (obj.mnum < 0 && obj.mden === 0)) { 1354 return true; 1355 } else { 1356 return false; 1357 } 1358 } 1359 1360 public valueOf(): number { 1361 if (this.mnum > 0 && this.mden === 0) { 1362 return Number.POSITIVE_INFINITY; 1363 } else if (this.mnum < 0 && this.mden === 0) { 1364 return Number.NEGATIVE_INFINITY; 1365 } else if ((this.mnum === 0) && (this.mden === 0)) { 1366 return Number.NaN; 1367 } else { 1368 return this.mnum / this.mden; 1369 } 1370 } 1371 1372 public getCommonDivisor(number1: number, number2: number): number { 1373 if (number1 === 0 || number2 === 0) { 1374 throw new Error('Parameter cannot be zero!'); 1375 } 1376 let temp: number = 0; 1377 if (number1 < number2) { 1378 temp = number1; 1379 number1 = number2; 1380 number2 = temp; 1381 } 1382 while (number1 % number2 !== 0) { 1383 temp = number1 % number2; 1384 number1 = number2; 1385 number2 = temp; 1386 } 1387 return number2; 1388 } 1389 1390 static getCommonFactor(firNum: number, SecNum: number): number { 1391 if (typeof firNum !== 'number') { 1392 let error = new BusinessError(`Parameter error.The type of ${firNum} must be number`); 1393 throw error; 1394 } 1395 if (typeof SecNum !== 'number') { 1396 let error = new BusinessError(`Parameter error.The type of ${SecNum} must be number`); 1397 throw error; 1398 } 1399 if (firNum === 0 || SecNum === 0) { 1400 throw new Error('Parameter cannot be zero!'); 1401 } 1402 let temp: number = 0; 1403 if (firNum < SecNum) { 1404 temp = firNum; 1405 firNum = SecNum; 1406 SecNum = temp; 1407 } 1408 while (firNum % SecNum !== 0) { 1409 temp = firNum % SecNum; 1410 firNum = SecNum; 1411 SecNum = temp; 1412 } 1413 return SecNum; 1414 } 1415 1416 public getDenominator(): number { 1417 return this.mden; 1418 } 1419 1420 public getNumerator(): number { 1421 return this.mnum; 1422 } 1423 1424 public isFinite(): boolean { 1425 return this.mden !== 0; 1426 } 1427 1428 public isNaN(): boolean { 1429 return this.mnum === 0 && this.mden === 0; 1430 } 1431 1432 public isZero(): boolean { 1433 return this.mnum === 0 && this.mden !== 0; 1434 } 1435 1436 public toString(): string { 1437 let buf: string; 1438 if (this.mnum === 0 && this.mden === 0) { 1439 buf = 'NaN'; 1440 } else if (this.mnum > 0 && this.mden === 0) { 1441 buf = 'Infinity'; 1442 } else if (this.mnum < 0 && this.mden === 0) { 1443 buf = '-Infinity'; 1444 } else { 1445 buf = String(this.mnum) + '/' + String(this.mden); 1446 } 1447 return buf; 1448 } 1449} 1450 1451interface ScopeComparable { 1452 compareTo(other: ScopeComparable): boolean; 1453} 1454 1455type ScopeType = ScopeComparable; 1456 1457class Scope { 1458 private readonly _lowerLimit: ScopeType; 1459 private readonly _upperLimit: ScopeType; 1460 1461 public constructor(readonly lowerObj: ScopeType, readonly upperObj: ScopeType) { 1462 this.checkNull(lowerObj, 'lower limit not be null'); 1463 this.checkNull(upperObj, 'upper limit not be null'); 1464 1465 if (lowerObj.compareTo(upperObj)) { 1466 throw new Error('lower limit must be less than or equal to upper limit'); 1467 } 1468 this._lowerLimit = lowerObj; 1469 this._upperLimit = upperObj; 1470 } 1471 1472 public getLower(): ScopeType { 1473 return this._lowerLimit; 1474 } 1475 1476 public getUpper(): ScopeType { 1477 return this._upperLimit; 1478 } 1479 1480 public compareTo(): boolean { 1481 return false; 1482 } 1483 1484 public contains(value: ScopeType): boolean; 1485 public contains(scope: Scope): boolean; 1486 public contains(x: Scope | ScopeType): boolean { 1487 let resLower: boolean; 1488 let resUpper: boolean; 1489 this.checkNull(x, 'value must not be null'); 1490 if (x instanceof Scope) { 1491 resLower = x._lowerLimit.compareTo(this._lowerLimit); 1492 resUpper = this._upperLimit.compareTo(x._upperLimit); 1493 } else { 1494 resLower = x.compareTo(this._lowerLimit); 1495 resUpper = this._upperLimit.compareTo(x); 1496 } 1497 return resLower && resUpper; 1498 } 1499 1500 public clamp(value: ScopeType): ScopeType { 1501 this.checkNull(value, 'value must not be null'); 1502 if (!value.compareTo(this._lowerLimit)) { 1503 return this._lowerLimit; 1504 } else if (value.compareTo(this._upperLimit)) { 1505 return this._upperLimit; 1506 } else { 1507 return value; 1508 } 1509 } 1510 1511 public intersect(scope: Scope): Scope; 1512 public intersect(lowerObj: ScopeType, upperObj: ScopeType): Scope; 1513 public intersect(x: Scope, y?: Scope | ScopeType): Scope { 1514 let reLower: boolean; 1515 let reUpper: boolean; 1516 let mLower: ScopeType; 1517 let mUpper: ScopeType; 1518 if (y) { 1519 this.checkNull(x, 'lower limit must not be null'); 1520 this.checkNull(y, 'upper limit must not be null'); 1521 reLower = this._lowerLimit.compareTo(x); 1522 reUpper = y.compareTo(this._upperLimit); 1523 if (reLower && reUpper) { 1524 return this; 1525 } else { 1526 mLower = reLower ? this._lowerLimit : x; 1527 mUpper = reUpper ? this._upperLimit : y; 1528 return new Scope(mLower, mUpper); 1529 } 1530 } else { 1531 this.checkNull(x, 'scope must not be null'); 1532 reLower = this._lowerLimit.compareTo(x._lowerLimit); 1533 reUpper = x._upperLimit.compareTo(this._upperLimit); 1534 if (!reLower && !reUpper) { 1535 return x; 1536 } else if (reLower && reUpper) { 1537 return this; 1538 } else { 1539 mLower = reLower ? this._lowerLimit : x._lowerLimit; 1540 mUpper = reUpper ? this._upperLimit : x._upperLimit; 1541 return new Scope(mLower, mUpper); 1542 } 1543 } 1544 } 1545 1546 public expand(obj: ScopeType): Scope; 1547 public expand(scope: Scope): Scope; 1548 public expand(lowerObj: ScopeType, upperObj: ScopeType): Scope; 1549 public expand(x: ScopeType, y?: ScopeType): Scope { 1550 let reLower: boolean; 1551 let reUpper: boolean; 1552 let mLower: ScopeType; 1553 let mUpper: ScopeType; 1554 if (!y) { 1555 this.checkNull(x, 'value must not be null'); 1556 if (!(x instanceof Scope)) { 1557 this.checkNull(x, 'value must not be null'); 1558 return this.expand(x, x); 1559 } 1560 reLower = x._lowerLimit.compareTo(this._lowerLimit); 1561 reUpper = this._upperLimit.compareTo(x._upperLimit); 1562 if (reLower && reUpper) { 1563 return this; 1564 } else if (!reLower && !reUpper) { 1565 return x; 1566 } else { 1567 mLower = reLower ? this._lowerLimit : x._lowerLimit; 1568 mUpper = reUpper ? this._upperLimit : x._upperLimit; 1569 return new Scope(mLower, mUpper); 1570 } 1571 1572 } else { 1573 this.checkNull(x, 'lower limit must not be null'); 1574 this.checkNull(y, 'upper limit must not be null'); 1575 reLower = x.compareTo(this._lowerLimit); 1576 reUpper = this._upperLimit.compareTo(y); 1577 if (reLower && reUpper) { 1578 return this; 1579 } 1580 mLower = reLower ? this._lowerLimit : x; 1581 mUpper = reUpper ? this._upperLimit : y; 1582 return new Scope(mLower, mUpper); 1583 } 1584 } 1585 1586 public toString(): string { 1587 let strLower: string = this._lowerLimit.toString(); 1588 let strUpper: string = this._upperLimit.toString(); 1589 return `[${strLower}, ${strUpper}]`; 1590 } 1591 1592 public checkNull(o: ScopeType, str: string): void { 1593 if (o === null) { 1594 throw new Error(str); 1595 } 1596 } 1597} 1598 1599class ScopeHelper { 1600 private readonly _lowerLimit: ScopeType; 1601 private readonly _upperLimit: ScopeType; 1602 public constructor(readonly lowerObj: ScopeType, readonly upperObj: ScopeType) { 1603 if (typeof lowerObj !== 'object') { 1604 let error = new BusinessError(`Parameter error.The type of ${lowerObj} must be object`); 1605 throw error; 1606 } 1607 if (typeof upperObj !== 'object') { 1608 let error = new BusinessError(`Parameter error.The type of ${upperObj} must be object`); 1609 throw error; 1610 } 1611 1612 this.checkNull(lowerObj, 'lower limit not be null'); 1613 this.checkNull(upperObj, 'upper limit not be null'); 1614 1615 if (lowerObj.compareTo(upperObj)) { 1616 throw new Error('lower limit must be less than or equal to upper limit'); 1617 } 1618 this._lowerLimit = lowerObj; 1619 this._upperLimit = upperObj; 1620 } 1621 1622 public getLower(): ScopeType { 1623 return this._lowerLimit; 1624 } 1625 1626 public getUpper(): ScopeType { 1627 return this._upperLimit; 1628 } 1629 1630 public compareTo(): boolean { 1631 return false; 1632 } 1633 1634 public contains(value: ScopeType): boolean; 1635 public contains(scope: ScopeHelper): boolean; 1636 public contains(x: ScopeHelper | ScopeType): boolean { 1637 this.checkNull(x, 'value must not be null'); 1638 if (typeof x !== 'object') { 1639 let error = new BusinessError(`Parameter error.The type of ${x} must be object or ScopeHelper`); 1640 throw error; 1641 } 1642 let resLower: boolean; 1643 let resUpper: boolean; 1644 if (x instanceof ScopeHelper) { 1645 resLower = x._lowerLimit.compareTo(this._lowerLimit); 1646 resUpper = this._upperLimit.compareTo(x._upperLimit); 1647 } else { 1648 resLower = x.compareTo(this._lowerLimit); 1649 resUpper = this._upperLimit.compareTo(x); 1650 } 1651 return resLower && resUpper; 1652 } 1653 1654 public clamp(value: ScopeType): ScopeType { 1655 this.checkNull(value, 'value must not be null'); 1656 if (typeof value !== 'object') { 1657 let error = new BusinessError(`Parameter error.The type of ${value} must be object`); 1658 throw error; 1659 } 1660 1661 if (!value.compareTo(this._lowerLimit)) { 1662 return this._lowerLimit; 1663 } else if (value.compareTo(this._upperLimit)) { 1664 return this._upperLimit; 1665 } else { 1666 return value; 1667 } 1668 } 1669 1670 public intersect(scope: ScopeHelper): ScopeHelper; 1671 public intersect(lowerObj: ScopeType, upperObj: ScopeType): ScopeHelper; 1672 public intersect(x: ScopeHelper, y?: ScopeType): ScopeHelper { 1673 if (typeof x !== 'object') { 1674 let error = new BusinessError(`Parameter error.The type of ${x} must be ScopeHelper or ScopeType`); 1675 throw error; 1676 } 1677 let reLower: boolean; 1678 let reUpper: boolean; 1679 let mLower: ScopeType; 1680 let mUpper: ScopeType; 1681 if (y) { 1682 this.checkNull(x, 'lower limit must not be null'); 1683 this.checkNull(y, 'upper limit must not be null'); 1684 if (typeof y !== 'object') { 1685 let error = new BusinessError(`Parameter error.The type of ${y} must be ScopeType`); 1686 throw error; 1687 } 1688 reLower = this._lowerLimit.compareTo(x); 1689 reUpper = y.compareTo(this._upperLimit); 1690 if (reLower && reUpper) { 1691 return this; 1692 } else { 1693 mLower = reLower ? this._lowerLimit : x; 1694 mUpper = reUpper ? this._upperLimit : y; 1695 return new ScopeHelper(mLower, mUpper); 1696 } 1697 } else { 1698 this.checkNull(x, 'scope must not be null'); 1699 reLower = this._lowerLimit.compareTo(x._lowerLimit); 1700 reUpper = x._upperLimit.compareTo(this._upperLimit); 1701 if (!reLower && !reUpper) { 1702 return x; 1703 } else if (reLower && reUpper) { 1704 return this; 1705 } else { 1706 mLower = reLower ? this._lowerLimit : x._lowerLimit; 1707 mUpper = reUpper ? this._upperLimit : x._upperLimit; 1708 return new ScopeHelper(mLower, mUpper); 1709 } 1710 } 1711 } 1712 1713 public expand(obj: ScopeType): ScopeHelper; 1714 public expand(scope: ScopeHelper): ScopeHelper; 1715 public expand(lowerObj: ScopeType, upperObj: ScopeType): ScopeHelper; 1716 public expand(x: ScopeType, y?: ScopeType): ScopeHelper { 1717 if (typeof x !== 'object') { 1718 let error = new BusinessError(`Parameter error.The type of ${x} must be ScopeHelper or ScopeType`); 1719 throw error; 1720 } 1721 let reLower: boolean; 1722 let reUpper: boolean; 1723 let mLower: ScopeType; 1724 let mUpper: ScopeType; 1725 if (!y) { 1726 this.checkNull(x, 'value must not be null'); 1727 if (!(x instanceof ScopeHelper)) { 1728 this.checkNull(x, 'value must not be null'); 1729 return this.expand(x, x); 1730 } 1731 reLower = x._lowerLimit.compareTo(this._lowerLimit); 1732 reUpper = this._upperLimit.compareTo(x._upperLimit); 1733 if (reLower && reUpper) { 1734 return this; 1735 } else if (!reLower && !reUpper) { 1736 return x; 1737 } else { 1738 mLower = reLower ? this._lowerLimit : x._lowerLimit; 1739 mUpper = reUpper ? this._upperLimit : x._upperLimit; 1740 return new ScopeHelper(mLower, mUpper); 1741 } 1742 1743 } else { 1744 if (typeof y !== 'object') { 1745 let error = new BusinessError(`Parameter error.The type of ${y} must be ScopeType`); 1746 throw error; 1747 } 1748 1749 this.checkNull(x, 'lower limit must not be null'); 1750 this.checkNull(y, 'upper limit must not be null'); 1751 reLower = x.compareTo(this._lowerLimit); 1752 reUpper = this._upperLimit.compareTo(y); 1753 if (reLower && reUpper) { 1754 return this; 1755 } 1756 mLower = reLower ? this._lowerLimit : x; 1757 mUpper = reUpper ? this._upperLimit : y; 1758 return new ScopeHelper(mLower, mUpper); 1759 } 1760 } 1761 1762 public toString(): string { 1763 let strLower: string = this._lowerLimit.toString(); 1764 let strUpper: string = this._upperLimit.toString(); 1765 return `[${strLower}, ${strUpper}]`; 1766 } 1767 1768 public checkNull(o: ScopeType, str: string): void { 1769 if (o === null) { 1770 throw new Error(str); 1771 } 1772 } 1773} 1774 1775class Aspect { 1776 private static checkMethodType(func: Function, methodName: string): boolean { 1777 if (typeof func !== 'function') { 1778 let error = new BusinessError(`Parameter error. ${methodName} must be a method of targetClass, but it is ${func}`); 1779 throw error; 1780 } 1781 return func.constructor.name === 'AsyncFunction'; 1782 } 1783 1784 private static checkParameters(targetClass: Object, methodName: string, isStatic: boolean): void { 1785 if (typeof (targetClass as Object) === 'undefined') { 1786 let error = new BusinessError(`Parameter error. The type of targetClass should be Object, but it is ${targetClass}`); 1787 throw error; 1788 } 1789 if (typeof methodName !== 'string') { 1790 let error = new BusinessError(`Parameter error. The type of methodName should be string, but it is ${methodName}`); 1791 throw error; 1792 } 1793 if (typeof isStatic !== 'boolean') { 1794 let error = new BusinessError(`Parameter error. The type of isStatic should be boolean, but it is ${isStatic}`); 1795 throw error; 1796 } 1797 } 1798 1799 static addBefore(targetClass: Object, methodName: string, isStatic: boolean, before: Function): void { 1800 Aspect.checkParameters(targetClass, methodName, isStatic); 1801 if (typeof before !== 'function') { 1802 let error = new BusinessError(`Parameter error. The type of before should be function, but it is ${before}`); 1803 throw error; 1804 } 1805 let obj = isStatic ? targetClass : Reflect.get(targetClass, 'prototype'); 1806 if (!obj) { 1807 return; 1808 } 1809 let oldFunc = obj[methodName]; 1810 if (!Aspect.checkMethodType(oldFunc, methodName)) { 1811 let newFunc = function(...args : AnyType[]): AnyType { 1812 before(this, ...args); 1813 let ret = oldFunc.bind(this)(...args); 1814 return ret; 1815 }; 1816 obj[methodName] = newFunc; 1817 } else { 1818 let newFunc = async function (...args : AnyType[]): Promise<AnyType> { 1819 before(this, ...args); 1820 let ret = oldFunc.bind(this)(...args); 1821 return ret; 1822 }; 1823 obj[methodName] = newFunc; 1824 } 1825 } 1826 1827 static addAfter(targetClass: Object, methodName: string, isStatic: boolean, after: Function): void { 1828 Aspect.checkParameters(targetClass, methodName, isStatic); 1829 if (typeof after !== 'function') { 1830 let error = new BusinessError(`Parameter error. The type of after should be function, but it is ${after}`); 1831 throw error; 1832 } 1833 let obj = isStatic ? targetClass : Reflect.get(targetClass, 'prototype'); 1834 if (!obj) { 1835 return; 1836 } 1837 let oldFunc = obj[methodName]; 1838 if (!Aspect.checkMethodType(oldFunc, methodName)) { 1839 let newFunc = function(...args : AnyType[]): AnyType { 1840 let ret1 = oldFunc.bind(this)(...args); 1841 let ret2 = after(this, ret1, ...args); 1842 return ret2; 1843 }; 1844 obj[methodName] = newFunc; 1845 } else { 1846 let newFunc = async function (...args : AnyType[]): Promise<AnyType> { 1847 let ret1 = oldFunc.bind(this)(...args); 1848 let ret2 = after(this, ret1, ...args); 1849 return ret2; 1850 }; 1851 obj[methodName] = newFunc; 1852 } 1853 } 1854 1855 static replace(targetClass: Object, methodName: string, isStatic: boolean, instead: Function) : void { 1856 Aspect.checkParameters(targetClass, methodName, isStatic); 1857 if (typeof instead !== 'function') { 1858 let error = new BusinessError(`Parameter error. The type of instead should be function, but it is ${instead}`); 1859 throw error; 1860 } 1861 let obj = isStatic ? targetClass : Reflect.get(targetClass, 'prototype'); 1862 if (!obj) { 1863 return; 1864 } 1865 let oldFunc = obj[methodName]; 1866 if (!Aspect.checkMethodType(oldFunc, methodName)) { 1867 let func = function(...args : AnyType[]): AnyType { 1868 let ret = instead(this, ...args); 1869 return ret; 1870 }; 1871 obj[methodName] = func; 1872 } else { 1873 let func = async function (...args : AnyType[]): Promise<AnyType> { 1874 let ret = instead(this, ...args); 1875 return ret; 1876 }; 1877 obj[methodName] = func; 1878 } 1879 } 1880} 1881 1882export default { 1883 printf: printf, 1884 format: format, 1885 getErrorString: getErrorString, 1886 errnoToString: errnoToString, 1887 callbackWrapper: callbackWrapper, 1888 promiseWrapper: promiseWrapper, 1889 promisify: promisify, 1890 randomUUID: randomUUID, 1891 randomBinaryUUID: randomBinaryUUID, 1892 generateRandomUUID: randomUUID, 1893 generateRandomBinaryUUID: randomBinaryUUID, 1894 parseUUID: parseUUID, 1895 TextEncoder: textEncoder, 1896 TextDecoder: TextDecoder, 1897 Base64: base64, 1898 Base64Helper: Base64Helper, 1899 types: types, 1900 LruBuffer: LruBuffer, 1901 LRUCache: LRUCache, 1902 RationalNumber: RationalNumber, 1903 Scope: Scope, 1904 ScopeHelper: ScopeHelper, 1905 Type: Type, 1906 Aspect: Aspect, 1907}; 1908