• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15interface ArkPrivate {
16  Stack: number;
17  Load(key: number): Object;
18}
19let flag: boolean = false;
20let fastStack: Object = undefined;
21let arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined;
22if (arkPritvate !== undefined) {
23  fastStack = arkPritvate.Load(arkPritvate.Stack);
24} else {
25  flag = true;
26}
27declare function requireNapi(s: string): any;
28if (flag || fastStack === undefined) {
29  const { errorUtil } = requireNapi('util.struct');
30  class HandlerStack<T> {
31    private isOutBounds(obj: Stack<T>, prop: string): void {
32      let index: number = Number.parseInt(prop);
33      if (Number.isInteger(index)) {
34        errorUtil.checkRangeError('index', index, 0, obj.length - 1);
35      }
36    }
37    get(obj: Stack<T>, prop: string): T {
38      if (typeof prop === 'symbol') {
39        return obj[prop];
40      }
41      this.isOutBounds(obj, prop);
42      return obj[prop];
43    }
44    set(obj: Stack<T>, prop: any, value: T): boolean {
45      if (prop === 'elementNum' || prop === 'capacity') {
46        obj[prop] = value;
47        return true;
48      }
49      this.isOutBounds(obj, prop);
50      let index: number = Number.parseInt(prop);
51      if (index >= 0 && index < obj.length && Number.isInteger(index)) {
52        obj[index] = value;
53        return true;
54      }
55      return false;
56    }
57    ownKeys(obj: Stack<T>): Array<string> {
58      let keys: string[] = [];
59      let length: number = obj.length;
60      for (let i: number = 0; i < length; i++) {
61        keys.push(i.toString());
62      }
63      return keys;
64    }
65    defineProperty(): boolean {
66      return true;
67    }
68    getOwnPropertyDescriptor(obj: Stack<T>, prop: string): Object {
69      this.isOutBounds(obj, prop);
70      let index: number = Number.parseInt(prop);
71      if (index >= 0 && index < obj.length && Number.isInteger(index)) {
72        return Object.getOwnPropertyDescriptor(obj, prop);
73      }
74      return Object;
75    }
76    setPrototypeOf(): T {
77      throw new Error(`Can't setPrototype on Stack Object`);
78    }
79  }
80  interface IterableIterator<T> {
81    next: () => {
82      value: T;
83      done: boolean;
84    };
85  }
86  class Stack<T> {
87    private elementNum: number = 0;
88    private capacity: number = 10; // 10 : means number
89    constructor() {
90      errorUtil.checkNewTargetIsNullError('Stack', !new.target);
91      return new Proxy(this, new HandlerStack());
92    }
93    get length(): number {
94      return this.elementNum;
95    }
96    push(item: T): T {
97      errorUtil.checkBindError('push', Stack, this);
98      if (this.isFull()) {
99        this.increaseCapacity();
100      }
101      this[this.elementNum++] = item;
102      return item;
103    }
104    pop(): T {
105      errorUtil.checkBindError('pop', Stack, this);
106      if (this.isEmpty()) {
107        return undefined;
108      }
109      let result: T = undefined;
110      result = this[this.length - 1];
111      this.elementNum--;
112      return result;
113    }
114    peek(): T {
115      errorUtil.checkBindError('peek', Stack, this);
116      if (this.isEmpty()) {
117        return undefined;
118      }
119      return this[this.length - 1];
120    }
121    locate(element: T): number {
122      errorUtil.checkBindError('locate', Stack, this);
123      for (let i: number = 0; i < this.length; i++) {
124        if (this[i] === element) {
125          return i;
126        }
127      }
128      return -1;
129    }
130    isEmpty(): boolean {
131      errorUtil.checkBindError('isEmpty', Stack, this);
132      return this.elementNum === 0;
133    }
134    forEach(callbackfn: (value: T, index?: number, stack?: Stack<T>) => void,
135      thisArg?: Object): void {
136      errorUtil.checkBindError('forEach', Stack, this);
137      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
138      for (let i: number = 0; i < this.length; i++) {
139        callbackfn.call(thisArg, this[i], i, this);
140      }
141    }
142    private isFull(): boolean {
143      return this.elementNum === this.capacity;
144    }
145    private increaseCapacity(): void {
146      this.capacity = 1.5 * this.capacity; // 1.5 : means number
147    }
148    [Symbol.iterator](): IterableIterator<T> {
149      errorUtil.checkBindError('Symbol.iterator', Stack, this);
150      let count: number = 0;
151      let stack: Stack<T> = this;
152      return {
153        next: function (): { done: boolean, value: T } {
154          let done: boolean = false;
155          let value: T = undefined;
156          done = count >= stack.elementNum;
157          value = done ? undefined : stack[count++];
158          return {
159            done: done,
160            value: value,
161          };
162        },
163      };
164    }
165  }
166  Object.freeze(Stack);
167  fastStack = Stack;
168}
169export default fastStack;
170