/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ interface ArkPrivate { Stack: number; Load(key: number): Object; } let flag: boolean = false; let fastStack: Object = undefined; let arkPritvate: ArkPrivate = globalThis['ArkPrivate'] || undefined; if (arkPritvate !== undefined) { fastStack = arkPritvate.Load(arkPritvate.Stack); } else { flag = true; } declare function requireNapi(s: string): any; if (flag || fastStack === undefined) { const {ErrorUtil} = requireNapi('util.struct'); class HandlerStack { private isOutBounds(obj: Stack, prop: any): void { let index: number = Number.parseInt(prop); if (Number.isInteger(index)) { ErrorUtil.checkRangeError("index", index, 0, obj.length - 1); } } get(obj: Stack, prop: any): T { if (typeof prop === 'symbol') { return obj[prop]; } this.isOutBounds(obj, prop); return obj[prop]; } set(obj: Stack, prop: any, value: T): boolean { if (prop === 'elementNum' || prop === 'capacity') { obj[prop] = value; return true; } this.isOutBounds(obj, prop); let index: number = Number.parseInt(prop); if (index >= 0 && index < obj.length && Number.isInteger(index)) { obj[index] = value; return true; } return false; } ownKeys(obj: Stack): Array { let keys: string[] = []; let length: number = obj.length; for (let i: number = 0; i < length; i++) { keys.push(i.toString()); } return keys; } defineProperty() { return true; } getOwnPropertyDescriptor(obj: Stack, prop: any) { this.isOutBounds(obj, prop); let index: number = Number.parseInt(prop); if (index >= 0 && index < obj.length && Number.isInteger(index)) { return Object.getOwnPropertyDescriptor(obj, prop); } return } setPrototypeOf(): T { throw new Error(`Can't setPrototype on Stack Object`); } } interface IterableIterator { next: () => { value: T; done: boolean; }; } class Stack { private elementNum: number = 0; private capacity: number = 10; constructor() { ErrorUtil.checkNewTargetIsNullError("Stack", !new.target); return new Proxy(this, new HandlerStack()); } get length(): number { return this.elementNum; } push(item: T): T { ErrorUtil.checkBindError("push", Stack, this); if (this.isFull()) { this.increaseCapacity(); } this[this.elementNum++] = item; return item; } pop(): T { ErrorUtil.checkBindError("pop", Stack, this); if (this.isEmpty()) { return undefined; } let result: T = undefined; result = this[this.length - 1]; this.elementNum--; return result; } peek(): T { ErrorUtil.checkBindError("peek", Stack, this); if (this.isEmpty()) { return undefined; } return this[this.length - 1]; } locate(element: T): number { ErrorUtil.checkBindError("locate", Stack, this); for (let i: number = 0; i < this.length; i++) { if (this[i] === element) { return i; } } return -1; } isEmpty(): boolean { ErrorUtil.checkBindError("isEmpty", Stack, this); return this.elementNum === 0; } forEach(callbackfn: (value: T, index?: number, stack?: Stack) => void, thisArg?: Object): void { ErrorUtil.checkBindError("forEach", Stack, this); ErrorUtil.checkTypeError("callbackfn", "callable", callbackfn); for (let i: number = 0; i < this.length; i++) { callbackfn.call(thisArg, this[i], i, this); } } private isFull(): boolean { return this.elementNum === this.capacity; } private increaseCapacity(): void { this.capacity = 1.5 * this.capacity; } [Symbol.iterator](): IterableIterator { ErrorUtil.checkBindError("Symbol.iterator", Stack, this); let count: number = 0; let stack: Stack = this; return { next: function () { let done: boolean = false; let value: T = undefined; done = count >= stack.elementNum; value = done ? undefined : stack[count++]; return { done: done, value: value, }; }, }; } } Object.freeze(Stack); fastStack = Stack; } export default fastStack;