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 */
15declare function requireNapi(s: string): any;
16interface ArkPrivate {
17  HashMap: number;
18  Load(key: number): Object;
19}
20let flag: boolean = false;
21let fastHashMap: Object = undefined;
22let arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined;
23if (arkPritvate !== undefined) {
24  fastHashMap = arkPritvate.Load(arkPritvate.HashMap);
25} else {
26  flag = true;
27}
28if (flag || fastHashMap === undefined) {
29  let hashMapAbility: any = requireNapi('util.struct');
30  const errorUtil = hashMapAbility.errorUtil;
31  interface IterableIterator<T> {
32    next: () => {
33      value: T | undefined;
34      done: boolean;
35    };
36  }
37  class HandlerHashMap<K, V> {
38    set(target: HashMap<K, V>, p: string, value: string): boolean {
39      if (p in target) {
40        target[p] = value;
41        return true;
42      }
43      return false;
44    }
45    defineProperty(): boolean {
46      throw new Error(`Can't define Property on HashMap Object`);
47    }
48    deleteProperty(): boolean {
49      throw new Error(`Can't delete Property on HashMap Object`);
50    }
51    setPrototypeOf(): boolean {
52      throw new Error(`Can't set Prototype on HashMap Object`);
53    }
54  }
55  class HashMap<K, V> extends hashMapAbility.DictionaryClass<K, V> {
56    constructor() {
57      errorUtil.checkNewTargetIsNullError('HashMap', !new.target);
58      super();
59      return new Proxy(this, new HandlerHashMap());
60    }
61    get length(): number {
62      return this.memberNumber;
63    }
64    isEmpty(): boolean {
65      errorUtil.checkBindError('isEmpty', HashMap, this);
66      return this.memberNumber === 0;
67    }
68    hasKey(key: K): boolean {
69      errorUtil.checkBindError('hasKey', HashMap, this);
70      return super.hasKey(key);
71    }
72    hasValue(value: V): boolean {
73      errorUtil.checkBindError('hasValue', HashMap, this);
74      return super.values().indexOf(value) > -1;
75    }
76    get(key: K): V {
77      errorUtil.checkBindError('get', HashMap, this);
78      return this.getValueByKey(key);
79    }
80    setAll(map: HashMap<K, V>): void {
81      errorUtil.checkBindError('setAll', HashMap, this);
82      errorUtil.checkTypeError('map', 'HashMap', map);
83      let memebers: Array<HashMap<K, V>> = [];
84      memebers = map.keyValueArray;
85      for (let i: number = 0; i < memebers.length; i++) {
86        this.put(memebers[i].key, memebers[i].value);
87      }
88    }
89    set(key: K, value: V): Object {
90      errorUtil.checkBindError('set', HashMap, this);
91      return super.put(key, value);
92    }
93    remove(key: K): V {
94      errorUtil.checkBindError('remove', HashMap, this);
95      let result: V = this.removeMember(key);
96      return result;
97    }
98    clear(): void {
99      errorUtil.checkBindError('clear', HashMap, this);
100      super.clear();
101    }
102    keys(): IterableIterator<K> {
103      errorUtil.checkBindError('keys', HashMap, this);
104      let count: number = 0;
105      return {
106        next: function (): { done: boolean, value: K } {
107          let done: boolean = false;
108          let value: K = undefined;
109          done = count >= this.memberNumber;
110          value = done ? undefined : this.keyValueArray[count].key;
111          count++;
112          return {
113            done: done,
114            value: value,
115          };
116        },
117      };
118    }
119    values(): IterableIterator<V> {
120      errorUtil.checkBindError('values', HashMap, this);
121      let count: number = 0;
122      return {
123        next: function (): { done: boolean, value: V } {
124          let done: boolean = false;
125          let value: V = undefined;
126          done = count >= this.memberNumber;
127          value = done ? undefined : this.keyValueArray[count].value;
128          count++;
129          return {
130            done: done,
131            value: value,
132          };
133        },
134      };
135    }
136    replace(key: K, newValue: V): boolean {
137      errorUtil.checkBindError('replace', HashMap, this);
138      return super.replaceMember(key, newValue);
139    }
140    forEach(callbackfn: (value?: V, key?: K, map?: HashMap<K, V>) => void,
141      thisArg?: Object): void {
142      errorUtil.checkBindError('forEach', HashMap, this);
143      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
144      let tagetArray: Array<HashMap<K, V>> = [];
145      tagetArray = this.keyValueArray;
146      for (let i: number = 0; i < tagetArray.length; i++) {
147        callbackfn.call(thisArg, tagetArray[i].value, tagetArray[i].key, this);
148      }
149    }
150    entries(): IterableIterator<[K, V]> {
151      errorUtil.checkBindError('entries', HashMap, this);
152      let count: number = 0;
153      return {
154        next: function (): { done: boolean, value: [K, V] } {
155          let done: boolean = false;
156          let value: [K, V] = undefined;
157          done = count >= this.memberNumber;
158          value = done ? undefined : this.keyValueArray[count].entry();
159          count++;
160          return {
161            done: done,
162            value: value,
163          };
164        },
165      };
166    }
167    [Symbol.iterator](): IterableIterator<[K, V]> {
168      errorUtil.checkBindError('Symbol.iterator', HashMap, this);
169      return this.entries();
170    }
171  }
172  Object.freeze(HashMap);
173  fastHashMap = HashMap;
174}
175export default fastHashMap;
176