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