mirror of
https://github.com/openharmony/js_api_module.git
synced 2026-07-21 06:15:27 -04:00
Add TS linear container class
Signed-off-by: wangyong <wangyong237@huawei.com>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# Copyright (c) 2021 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.
|
||||
|
||||
import("//ark/ts2abc/ts2panda/ts2abc_config.gni")
|
||||
import("//build/ohos.gni")
|
||||
import("//build/ohos/ace/ace.gni")
|
||||
import("//foundation/ace/ace_engine/ace_config.gni")
|
||||
|
||||
container_names = [
|
||||
"arraylist",
|
||||
"deque",
|
||||
"queue",
|
||||
"vector",
|
||||
"linkedlist",
|
||||
"list",
|
||||
"stack",
|
||||
]
|
||||
|
||||
# compile .ts to .js.
|
||||
action("build_js_ts") {
|
||||
script = "//base/compileruntime/js_util_module/container/build_ts_js.py"
|
||||
args = [
|
||||
"--dst-file",
|
||||
rebase_path(target_out_dir + "/"),
|
||||
]
|
||||
depfile = "$target_gen_dir/$target_name.d"
|
||||
outputs = []
|
||||
foreach(item, container_names) {
|
||||
dep = target_out_dir + "/js_" + item + ".js"
|
||||
outputs += [ dep ]
|
||||
}
|
||||
}
|
||||
|
||||
# libs
|
||||
template("container_lib") {
|
||||
forward_variables_from(invoker, "*")
|
||||
|
||||
name = target_name
|
||||
base_output_path = get_label_info(":js_" + name, "target_out_dir")
|
||||
js_container_obj_path = base_output_path + name + ".o"
|
||||
gen_js_obj("js_" + name) {
|
||||
input = "$target_out_dir/js_" + name + ".js"
|
||||
output = js_container_obj_path
|
||||
dep = ":build_js_ts"
|
||||
}
|
||||
|
||||
# compile .js to .abc.
|
||||
action("gen_" + name + "_abc") {
|
||||
visibility = [ ":*" ]
|
||||
script = "//ark/ts2abc/ts2panda/scripts/generate_js_bytecode.py"
|
||||
|
||||
args = [
|
||||
"--src-js",
|
||||
rebase_path(target_out_dir + "/js_" + name + ".js"),
|
||||
"--dst-file",
|
||||
rebase_path(target_out_dir + "/" + name + ".abc"),
|
||||
"--node",
|
||||
rebase_path("${node_path}"),
|
||||
"--frontend-tool-path",
|
||||
rebase_path("${ts2abc_build_path}"),
|
||||
"--node-modules",
|
||||
rebase_path("${node_modules}"),
|
||||
"--module",
|
||||
]
|
||||
deps = [
|
||||
":build_js_ts",
|
||||
"//ark/ts2abc/ts2panda:ark_ts2abc_build",
|
||||
]
|
||||
|
||||
inputs = [ target_out_dir + "/js_" + name + ".js" ]
|
||||
outputs = [ target_out_dir + "/" + name + ".abc" ]
|
||||
}
|
||||
|
||||
abc_output_path = get_label_info(":" + name + "_abc", "target_out_dir")
|
||||
arraylist_abc_obj_path = abc_output_path + "/" + name + "_abc.o"
|
||||
gen_js_obj(name + "_abc") {
|
||||
input = "$target_out_dir/" + name + ".abc"
|
||||
output = arraylist_abc_obj_path
|
||||
dep = ":gen_" + target_name
|
||||
}
|
||||
|
||||
ohos_shared_library(name) {
|
||||
include_dirs = [
|
||||
"//third_party/node/src",
|
||||
"//foundation/ace/napi/interfaces/kits",
|
||||
"//base/compileruntime/js_util_module/container/" + name,
|
||||
]
|
||||
|
||||
sources = [ name + "/native_module_" + name + ".cpp" ]
|
||||
|
||||
dep_abc = ":" + name + "_abc"
|
||||
dep_js = ":js_" + name
|
||||
deps = [
|
||||
"//base/compileruntime/js_util_module/container/:js_" + name,
|
||||
"//foundation/ace/napi/:ace_napi",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
deps += [ dep_abc ]
|
||||
deps += [ dep_js ]
|
||||
|
||||
if (is_standard_system) {
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
} else {
|
||||
external_deps = [ "hilog:libhilog" ]
|
||||
}
|
||||
subsystem_name = "ccruntime"
|
||||
part_name = "jsapi_util"
|
||||
|
||||
relative_install_dir = "module"
|
||||
}
|
||||
}
|
||||
|
||||
container_libs = []
|
||||
foreach(item, container_names) {
|
||||
container_lib(item) {
|
||||
}
|
||||
dep = ":" + item
|
||||
container_libs += [ dep ]
|
||||
}
|
||||
|
||||
group("container_packages") {
|
||||
deps = container_libs
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
let flag = false;
|
||||
let fastArrayList = undefined;
|
||||
let arkPritvate = globalThis["ArkPrivate"] || undefined;
|
||||
if (arkPritvate !== undefined) {
|
||||
fastArrayList = arkPritvate.Load(arkPritvate.ArrayList);
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
if (flag || fastArrayList == undefined) {
|
||||
class HandlerArrayList<T> {
|
||||
get(obj: ArrayList<T>, prop: any) {
|
||||
if (typeof prop === "symbol") {
|
||||
return obj[prop];
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("ArrayList: get out-of-bounds");
|
||||
}
|
||||
}
|
||||
return obj[prop];
|
||||
}
|
||||
set(obj: ArrayList<T>, prop: any, value: T) {
|
||||
if (prop === "_length" || prop === "_capacity") {
|
||||
obj[prop] = value;
|
||||
return true;
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index > obj.length) {
|
||||
throw new Error("ArrayList: set out-of-bounds");
|
||||
} else {
|
||||
obj[index] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
deleteProperty(obj: ArrayList<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("ArrayList: deleteProperty out-of-bounds");
|
||||
}
|
||||
obj.removeByIndex(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
has(obj: ArrayList<T>, prop: any) {
|
||||
return obj.has(prop);
|
||||
}
|
||||
ownKeys(obj: ArrayList<T>) {
|
||||
let keys = [];
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
keys.push(i.toString());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
defineProperty(obj: ArrayList<T>, prop: any, desc: any) {
|
||||
return true;
|
||||
}
|
||||
getOwnPropertyDescriptor(obj: ArrayList<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("ArrayList: getOwnPropertyDescriptor out-of-bounds");
|
||||
}
|
||||
return Object.getOwnPropertyDescriptor(obj, prop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
setPrototypeOf(obj: any, prop: any): T {
|
||||
throw new Error("Can setPrototype on ArrayList Object");
|
||||
}
|
||||
}
|
||||
interface IterableIterator<T> {
|
||||
next: () => {
|
||||
value: T;
|
||||
done: boolean;
|
||||
};
|
||||
}
|
||||
class ArrayList<T> {
|
||||
private _length: number = 0;
|
||||
private _capacity: number = 10;
|
||||
constructor() {
|
||||
return new Proxy(this, new HandlerArrayList());
|
||||
}
|
||||
get length() {
|
||||
return this._length;
|
||||
}
|
||||
add(element: T): boolean {
|
||||
if (this.isFull()) {
|
||||
this.resize();
|
||||
}
|
||||
this[this._length++] = element;
|
||||
return true;
|
||||
}
|
||||
insert(element: T, index: number): void {
|
||||
if (this.isFull()) {
|
||||
this.resize();
|
||||
}
|
||||
for (let i = this._length; i > index; i--) {
|
||||
this[i] = this[i - 1];
|
||||
}
|
||||
this[index] = element;
|
||||
this._length++;
|
||||
}
|
||||
has(element: T): boolean {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
if (this[i] === element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getIndexOf(element: T): number {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
if (element === this[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
removeByIndex(index: number): void {
|
||||
for (let i = index; i < this._length - 1; i++) {
|
||||
this[i] = this[i + 1];
|
||||
}
|
||||
this._length--;
|
||||
}
|
||||
remove(element: T): boolean {
|
||||
if (this.has(element)) {
|
||||
let index = this.getIndexOf(element);
|
||||
for (let i = index; i < this._length - 1; i++) {
|
||||
this[i] = this[i + 1];
|
||||
}
|
||||
this._length--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getLastIndexOf(element: T): number {
|
||||
for (let i = this._length - 1; i >= 0; i--) {
|
||||
if (element === this[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
removeByRange(fromIndex: number, toIndex: number): void {
|
||||
if (fromIndex >= toIndex) {
|
||||
throw new Error(`fromIndex cannot be less than or equal to toIndex`);
|
||||
}
|
||||
toIndex = toIndex >= this._length - 1 ? this._length - 1 : toIndex;
|
||||
let i = fromIndex;
|
||||
for (let j = toIndex; j < this._length; j++) {
|
||||
this[i] = this[j];
|
||||
i++;
|
||||
}
|
||||
this._length -= toIndex - fromIndex;
|
||||
}
|
||||
replaceAllElements(callbackfn: (value: T, index?: number, arraylist?: ArrayList<T>) => T,
|
||||
thisArg?: Object): void {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
this[i] = callbackfn.call(thisArg, this[i], i, this);
|
||||
}
|
||||
}
|
||||
forEach(callbackfn: (value: T, index?: number, arraylist?: ArrayList<T>) => void,
|
||||
thisArg?: Object): void {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
callbackfn.call(thisArg, this[i], i, this);
|
||||
}
|
||||
}
|
||||
sort(comparator?: (firstValue: T, secondValue: T) => number): void {
|
||||
let isSort = true;
|
||||
if (comparator) {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
for (let j = 0; j < this._length - 1 - i; j++) {
|
||||
if (comparator(this[j], this[j + 1]) > 0) {
|
||||
isSort = false;
|
||||
let temp = this[j];
|
||||
this[j] = this[j + 1];
|
||||
this[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < this.length - 1; i++) {
|
||||
for (let j = 0; j < this._length - 1 - i; j++) {
|
||||
if (this.asciSort(this[j], this[j + 1])) {
|
||||
isSort = false;
|
||||
let temp = this[j];
|
||||
this[j] = this[j + 1];
|
||||
this[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
if (isSort) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private asciSort(curElement: any, nextElement: any): boolean {
|
||||
if ((Object.prototype.toString.call(curElement) === "[object String]" ||
|
||||
Object.prototype.toString.call(curElement) === "[object Number]") &&
|
||||
(Object.prototype.toString.call(nextElement) === "[object String]" ||
|
||||
Object.prototype.toString.call(nextElement) === "[object Number]")) {
|
||||
curElement = curElement.toString();
|
||||
nextElement = nextElement.toString();
|
||||
if(curElement > nextElement) {
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false;
|
||||
}
|
||||
subArrayList(fromIndex: number, toIndex: number): ArrayList<T> {
|
||||
if (fromIndex >= toIndex) {
|
||||
throw new Error(`fromIndex cannot be less than or equal to toIndex`);
|
||||
}
|
||||
toIndex = toIndex >= this._length - 1 ? this._length - 1 : toIndex;
|
||||
let arraylist = new ArrayList<T>();
|
||||
for (let i = fromIndex; i < toIndex; i++) {
|
||||
arraylist.add(this[i]);
|
||||
}
|
||||
return arraylist;
|
||||
}
|
||||
clear(): void {
|
||||
this._length = 0;
|
||||
}
|
||||
clone(): ArrayList<T> {
|
||||
let clone = new ArrayList<T>();
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
clone.add(this[i]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
getCapacity(): number {
|
||||
return this._capacity;
|
||||
}
|
||||
convertToArray(): Array<T> {
|
||||
let arr = [];
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
arr[i] = this[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
private isFull(): boolean {
|
||||
return this._length === this._capacity;
|
||||
}
|
||||
private resize(): void {
|
||||
this._capacity = 1.5 * this._capacity;
|
||||
}
|
||||
increaseCapacityTo(newCapacity: number): void {
|
||||
if (newCapacity >= this._length) {
|
||||
this._capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
trimToCurrentSize(): void {
|
||||
this._capacity = this._length;
|
||||
}
|
||||
[Symbol.iterator](): IterableIterator<T> {
|
||||
let count = 0;
|
||||
let arraylist = this;
|
||||
return {
|
||||
next: function () {
|
||||
var done = count >= arraylist._length;
|
||||
var value = !done ? arraylist[count++] : undefined;
|
||||
return {
|
||||
done: done,
|
||||
value: value,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Object.freeze(ArrayList);
|
||||
fastArrayList = ArrayList;
|
||||
}
|
||||
export default {
|
||||
ArrayList: fastArrayList,
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
extern const char _binary_js_arraylist_js_start[];
|
||||
extern const char _binary_js_arraylist_js_end[];
|
||||
extern const char _binary_arraylist_abc_start[];
|
||||
extern const char _binary_arraylist_abc_end[];
|
||||
|
||||
namespace OHOS::Util {
|
||||
static napi_value ArrayListInit(napi_env env, napi_value exports)
|
||||
{
|
||||
return exports;
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_arraylist_GetJSCode(const char **buf, int *bufLen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_js_arraylist_js_start;
|
||||
}
|
||||
if (bufLen != nullptr) {
|
||||
*bufLen = _binary_js_arraylist_js_end - _binary_js_arraylist_js_start;
|
||||
}
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_arraylist_GetABCCode(const char **buf, int *buflen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_arraylist_abc_start;
|
||||
}
|
||||
if (buflen != nullptr) {
|
||||
*buflen = _binary_arraylist_abc_end - _binary_arraylist_abc_start;
|
||||
}
|
||||
}
|
||||
|
||||
static napi_module arrayListModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = ArrayListInit,
|
||||
.nm_modname = "ArrayList",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = {0},
|
||||
};
|
||||
|
||||
extern "C" __attribute__((constructor)) void RegisterModule()
|
||||
{
|
||||
napi_module_register(&arrayListModule);
|
||||
}
|
||||
}
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021 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.
|
||||
import os
|
||||
import platform
|
||||
import argparse
|
||||
import subprocess
|
||||
|
||||
def run_command(command):
|
||||
print(" ".join(command))
|
||||
proc = subprocess.Popen(command, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, universal_newlines=True)
|
||||
out, err = proc.communicate()
|
||||
if out != "":
|
||||
print(out)
|
||||
exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
build_path = os.path.abspath(os.path.join(os.getcwd(), "../.."))
|
||||
os.chdir("%s/base/compileruntime/js_util_module/container/" % build_path)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--dst-file',
|
||||
help='the converted target file')
|
||||
input_arguments = parser.parse_args()
|
||||
|
||||
node = '../../../../prebuilts/build-tools/common/nodejs/\
|
||||
node-v12.18.4-linux-x64/bin/node'
|
||||
tsc = '../../../../ark/ts2abc/ts2panda/node_modules/typescript/bin/tsc'
|
||||
cmd = [node, tsc]
|
||||
run_command(cmd)
|
||||
|
||||
for dirname in os.listdir("./jscode") :
|
||||
filepath = os.path.join("./jscode", dirname)
|
||||
for filename in os.listdir(filepath) :
|
||||
dstpath = os.path.join(input_arguments.dst_file, filename)
|
||||
srcpath = os.path.join(filepath, filename)
|
||||
cmd = ['cp', "-r", srcpath, dstpath]
|
||||
run_command(cmd)
|
||||
|
||||
cmd = ['rm', "-rf", './jscode']
|
||||
run_command(cmd)
|
||||
exit(0)
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
let flag = false;
|
||||
let fastDeque = undefined;
|
||||
let arkPritvate = globalThis["ArkPrivate"] || undefined;
|
||||
if (arkPritvate !== undefined) {
|
||||
fastDeque = arkPritvate.Load(arkPritvate.Deque);
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
if (flag || fastDeque == undefined) {
|
||||
class HandlerDeque<T> {
|
||||
get(obj: Deque<T>, prop: any): T {
|
||||
if (typeof prop === "symbol") {
|
||||
return obj[prop];
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0) {
|
||||
throw new Error("Deque: get out-of-bounds");
|
||||
}
|
||||
}
|
||||
return obj[prop];
|
||||
}
|
||||
set(obj: Deque<T>, prop: any, value: T): boolean {
|
||||
if (prop === "_front" || prop === "_capacity" || prop === "_rear") {
|
||||
obj[prop] = value;
|
||||
return true;
|
||||
}
|
||||
var index = Number(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0) {
|
||||
throw new Error("Deque: set out-of-bounds");
|
||||
} else {
|
||||
obj[index] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
has(obj: Deque<T>, prop: any) {
|
||||
return obj.has(prop);
|
||||
}
|
||||
ownKeys(obj: Deque<T>) {
|
||||
let keys = [];
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
keys.push(i.toString());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
defineProperty(obj: Deque<T>, prop: any, desc: any) {
|
||||
return true;
|
||||
}
|
||||
getOwnPropertyDescriptor(obj: Deque<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("Deque: getOwnPropertyDescriptor out-of-bounds");
|
||||
}
|
||||
return Object.getOwnPropertyDescriptor(obj, prop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
setPrototypeOf(obj: any, prop: any): T {
|
||||
throw new Error("Can setPrototype on ArrayList Object");
|
||||
}
|
||||
}
|
||||
interface IterableIterator<T> {
|
||||
next: () => {
|
||||
value: T;
|
||||
done: boolean;
|
||||
};
|
||||
}
|
||||
class Deque<T> {
|
||||
private _front: number;
|
||||
private _capacity: number;
|
||||
private _rear: number;
|
||||
constructor() {
|
||||
this._front = 0;
|
||||
this._capacity = 8;
|
||||
this._rear = 0;
|
||||
return new Proxy(this, new HandlerDeque());
|
||||
}
|
||||
get length(){
|
||||
let result = (this._rear - this._front + this._capacity) % this._capacity;
|
||||
return result;
|
||||
}
|
||||
insertFront(element: T): void {
|
||||
if (this.isFull()) {
|
||||
this.increaseCapacity();
|
||||
}
|
||||
this._front = (this._front - 1 + this._capacity) % this._capacity;
|
||||
this[this._front] = element;
|
||||
}
|
||||
insertEnd(element: T): void {
|
||||
if (this.isFull()) {
|
||||
this.increaseCapacity();
|
||||
}
|
||||
this[this._rear] = element;
|
||||
this._rear = (this._rear + 1) % (this._capacity + 1);
|
||||
}
|
||||
getFirst(): T {
|
||||
return this[this._front];
|
||||
}
|
||||
getLast(): T {
|
||||
return this[this._rear - 1];
|
||||
}
|
||||
has(element: T): boolean {
|
||||
let result = false;
|
||||
this.forEach(function (value, index) {
|
||||
if (value == element) {
|
||||
result = true;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
popFirst(): T {
|
||||
let result = this[this._front];
|
||||
this._front = (this._front + 1) % (this._capacity + 1);
|
||||
return result;
|
||||
}
|
||||
popLast(): T {
|
||||
let result = this[this._rear - 1];
|
||||
this._rear = (this._rear + this._capacity) % (this._capacity + 1);
|
||||
return result;
|
||||
}
|
||||
forEach(callbackfn: (value: T, index?: number, deque?: Deque<T>) => void,
|
||||
thisArg?: Object): void {
|
||||
let k = 0;
|
||||
let i = this._front;
|
||||
while (true) {
|
||||
callbackfn.call(thisArg, this[i], k, this);
|
||||
i = (i + 1) % this._capacity;
|
||||
k++;
|
||||
if (i === this._rear) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private increaseCapacity(): void {
|
||||
let count = 0;
|
||||
let arr = [];
|
||||
let length = this.length;
|
||||
while (true) {
|
||||
arr[count++] = this[this._front];
|
||||
this._front = (this._front + 1) % this._capacity;
|
||||
if (this._front === this._rear) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < length; i++) {
|
||||
this[i] = arr[i];
|
||||
}
|
||||
this._capacity = 2 * this._capacity;
|
||||
this._front = 0;
|
||||
this._rear = length;
|
||||
}
|
||||
private isFull(): boolean {
|
||||
return (this._rear + 1) % this._capacity === this._front;
|
||||
}
|
||||
[Symbol.iterator](): IterableIterator<T> {
|
||||
let _this = this;
|
||||
let count = _this._front;
|
||||
return {
|
||||
next: function () {
|
||||
var done = count == _this._rear;
|
||||
var value = !done ? _this[count] : undefined;
|
||||
count = (count + 1) % _this._capacity;
|
||||
return {
|
||||
done: done,
|
||||
value: value,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Object.freeze(Deque);
|
||||
fastDeque = Deque;
|
||||
}
|
||||
export default {
|
||||
Deque: fastDeque,
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
extern const char _binary_js_deque_js_start[];
|
||||
extern const char _binary_js_deque_js_end[];
|
||||
extern const char _binary_deque_abc_start[];
|
||||
extern const char _binary_deque_abc_end[];
|
||||
namespace OHOS::Util {
|
||||
static napi_value DequeInit(napi_env env, napi_value exports)
|
||||
{
|
||||
return exports;
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_deque_GetJSCode(const char **buf, int *bufLen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_js_deque_js_start;
|
||||
}
|
||||
|
||||
if (bufLen != nullptr) {
|
||||
*bufLen = _binary_js_deque_js_end - _binary_js_deque_js_start;
|
||||
}
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_deque_GetABCCode(const char **buf, int *buflen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_deque_abc_start;
|
||||
}
|
||||
if (buflen != nullptr) {
|
||||
*buflen = _binary_deque_abc_end - _binary_deque_abc_start;
|
||||
}
|
||||
}
|
||||
|
||||
static napi_module dequeModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = DequeInit,
|
||||
.nm_modname = "Deque",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = {0},
|
||||
};
|
||||
|
||||
extern "C" __attribute__((constructor)) void RegisterModule()
|
||||
{
|
||||
napi_module_register(&dequeModule);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
let flag = false;
|
||||
let fastLinkedList = undefined;
|
||||
let arkPritvate = globalThis["ArkPrivate"] || undefined;
|
||||
if (arkPritvate !== undefined) {
|
||||
fastLinkedList = arkPritvate.Load(arkPritvate.LinkedList);
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
if (flag || fastLinkedList == undefined) {
|
||||
class HandlerLinkedList<T> {
|
||||
get(obj: LinkedList<T>, prop: any, receiver: any) {
|
||||
if (typeof prop === "symbol") {
|
||||
return obj[prop];
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
let length = obj.length;
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= length) {
|
||||
throw new Error("LinkedList: get out-of-bounds");
|
||||
}
|
||||
}
|
||||
return obj[prop];
|
||||
}
|
||||
set(obj: LinkedList<T>, prop: any, value: any) {
|
||||
if (
|
||||
prop === "_length" ||
|
||||
prop === "_capacity" ||
|
||||
prop === "_head" ||
|
||||
prop == "next" ||
|
||||
prop == "_tail") {
|
||||
obj[prop] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
let length = obj.length;
|
||||
if (index < 0 || index >= length) {
|
||||
throw new Error("LinkedList: set out-of-bounds");
|
||||
} else {
|
||||
obj[index] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
deleteProperty(obj: LinkedList<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
let length = obj.length;
|
||||
if (index < 0 || index >= length) {
|
||||
throw new Error("LinkedList: deleteProperty out-of-bounds");
|
||||
}
|
||||
obj.removeByIndex(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
has(obj: LinkedList<T>, prop: any) {
|
||||
return obj.has(prop);
|
||||
}
|
||||
ownKeys(obj: LinkedList<T>) {
|
||||
var keys = [];
|
||||
let length = obj.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
keys.push(i.toString());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
defineProperty(obj: LinkedList<T>, prop: any, desc: any) {
|
||||
return true;
|
||||
}
|
||||
getOwnPropertyDescriptor(obj: LinkedList<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
let length = obj.length;
|
||||
if (index < 0 || index >= length) {
|
||||
throw new Error("LinkedList: getOwnPropertyDescriptor out-of-bounds");
|
||||
}
|
||||
return Object.getOwnPropertyDescriptor(obj, prop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
interface IterableIterator<T> {
|
||||
next: () => {
|
||||
value: T;
|
||||
done: boolean;
|
||||
};
|
||||
}
|
||||
class NodeObj<T> {
|
||||
/* If 'any' is changed to 'T' here, an error will be reported:
|
||||
Type 'unknown' cannot be assigned to type 'T'. */
|
||||
element: any;
|
||||
next?: NodeObj<T> | null;
|
||||
prev?: NodeObj<T> | null;
|
||||
constructor(
|
||||
element: any,
|
||||
next?: NodeObj<T> | null,
|
||||
prev?: NodeObj<T> | null
|
||||
) {
|
||||
this.element = element;
|
||||
this.next = next;
|
||||
this.prev = prev;
|
||||
}
|
||||
}
|
||||
class LinkIterator<T> {
|
||||
/* If 'any' is changed to 'T' here, an error will be reported:
|
||||
Property 'next' does not exist on type 'T' */
|
||||
private linkNode: any;
|
||||
constructor(linkNode: any) {
|
||||
this.linkNode = linkNode;
|
||||
}
|
||||
hasNext(): boolean {
|
||||
if (this.linkNode.next !== null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
next(): NodeObj<T> {
|
||||
this.linkNode = this.linkNode.next;
|
||||
return this.linkNode;
|
||||
}
|
||||
prev(): NodeObj<T> {
|
||||
this.linkNode = this.linkNode.prev;
|
||||
return this.linkNode;
|
||||
}
|
||||
}
|
||||
class LinkedList<T> {
|
||||
private _head?: any;
|
||||
private _tail?: any;
|
||||
private _length : number;
|
||||
private _capacity: number;
|
||||
constructor(_head?: NodeObj<T>, _tail?: NodeObj<T>) {
|
||||
this._head = _head || null;
|
||||
this._tail = _tail || null;
|
||||
this._length = 0;
|
||||
this._capacity = 10;
|
||||
return new Proxy(this, new HandlerLinkedList());
|
||||
}
|
||||
get length() {
|
||||
return this._length;
|
||||
}
|
||||
private getNode(index: number): NodeObj<T> {
|
||||
let current = this._head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current["next"];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
get(index: number): T {
|
||||
let current = this._head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current["next"];
|
||||
}
|
||||
return current.element;
|
||||
}
|
||||
add(element: T): boolean {
|
||||
if (this._length === 0) {
|
||||
let head = this._head;
|
||||
let tail = this._tail;
|
||||
this._head = this._tail = new NodeObj(element, head, tail);
|
||||
} else {
|
||||
let prevNode = this.getNode(this._length - 1);
|
||||
prevNode.next = new NodeObj(element, prevNode["next"], this._tail);
|
||||
}
|
||||
this._length++;
|
||||
return true;
|
||||
}
|
||||
addFirst(element: T): void {
|
||||
if (!element) {
|
||||
throw new Error("element cannot be null");
|
||||
}
|
||||
let node = new NodeObj(element, this._head, this._tail);
|
||||
if (this._length === 0) {
|
||||
this._head = this._tail = node;
|
||||
} else {
|
||||
node.next = this._head;
|
||||
this._head = node;
|
||||
}
|
||||
this._length++;
|
||||
}
|
||||
removeFirst(): T {
|
||||
let result = this.getNode(0).element;
|
||||
this.removeByIndex(0);
|
||||
return result;
|
||||
}
|
||||
popFirst(): T {
|
||||
let result = this.getNode(0).element;
|
||||
this.removeByIndex(0);
|
||||
return result;
|
||||
}
|
||||
popLast(): T {
|
||||
let result = this.getNode(this._length - 1).element;
|
||||
this.removeByIndex(this._length - 1);
|
||||
return result;
|
||||
}
|
||||
removeLast(): T {
|
||||
let result = this.getNode(this._length - 1).element;
|
||||
this.removeByIndex(this._length - 1);
|
||||
return result;
|
||||
}
|
||||
clear(): void {
|
||||
this._head = null;
|
||||
this._tail = null;
|
||||
this._length = 0;
|
||||
}
|
||||
has(element: T): boolean {
|
||||
if (this._head.element === element) {
|
||||
return true;
|
||||
}
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
while (linkIterator.hasNext()) {
|
||||
const newNode = linkIterator.next();
|
||||
if (newNode.element === element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getIndexOf(element: T): number {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
const curNode = this.getNode(i);
|
||||
if (curNode.element === element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
getLastIndexOf(element: T): number {
|
||||
for (let i = this._length - 1; i >= 0; i--) {
|
||||
const curNode = this.getNode(i);
|
||||
if (curNode.element === element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
removeByIndex(index: number): T {
|
||||
let current = this._head;
|
||||
if (index === 0) {
|
||||
this._head = current && current.next;
|
||||
if (this._length == 1) {
|
||||
this._head = this._tail = null;
|
||||
} else {
|
||||
this._head.prev = null;
|
||||
}
|
||||
} else if (index == this._length - 1) {
|
||||
current = this.getNode(index - 1);
|
||||
this._tail = current;
|
||||
current.next = null;
|
||||
} else {
|
||||
const prevNode = this.getNode(index - 1);
|
||||
const nextNode = this.getNode(index + 1);
|
||||
prevNode.next = nextNode;
|
||||
nextNode.prev = prevNode;
|
||||
}
|
||||
this._length--;
|
||||
return current && current.element;
|
||||
}
|
||||
remove(element: T): boolean {
|
||||
if (this.has(element)) {
|
||||
let index = this.getIndexOf(element);
|
||||
this.removeByIndex(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
removeFirstFound(element: T): boolean {
|
||||
if (this.has(element)) {
|
||||
let index = this.getIndexOf(element);
|
||||
this.removeByIndex(index);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
removeLastFound(element: T): boolean {
|
||||
if (this.has(element)) {
|
||||
let index = this.getLastIndexOf(element);
|
||||
this.removeByIndex(index);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
getFirst(): T {
|
||||
let newNode = this.getNode(0);
|
||||
let element = newNode.element;
|
||||
return element;
|
||||
}
|
||||
getLast(): T {
|
||||
let newNode = this.getNode(this._length - 1);
|
||||
let element = newNode.element;
|
||||
return element;
|
||||
}
|
||||
insert(index: number, element: T): void {
|
||||
if (index >= 0 && index < this._length) {
|
||||
let newNode = new NodeObj(element);
|
||||
let current = this._head;
|
||||
if (index === 0) {
|
||||
if (this._head === null) {
|
||||
this._head = newNode;
|
||||
this._tail = newNode;
|
||||
} else {
|
||||
newNode.next = this._head;
|
||||
this._head.prev = newNode;
|
||||
this._head = newNode;
|
||||
}
|
||||
} else {
|
||||
const prevNode = this.getNode(index - 1);
|
||||
current = prevNode.next;
|
||||
newNode.next = current;
|
||||
prevNode.next = newNode;
|
||||
current.prev = newNode;
|
||||
newNode.prev = prevNode;
|
||||
}
|
||||
} else if (index === this._length) {
|
||||
let prevNode = this.getNode(this._length - 1);
|
||||
prevNode.next = new NodeObj(element, prevNode["next"], this._tail);
|
||||
} else {
|
||||
throw new Error("index cannot Less than 0 and more than this length");
|
||||
}
|
||||
this._length++;
|
||||
}
|
||||
set(index: number, element: T): T {
|
||||
const current = this.getNode(index);
|
||||
current.element = element;
|
||||
return current && current.element;
|
||||
}
|
||||
convertToArray(): Array<T> {
|
||||
let arr: Array<T> = [];
|
||||
let index = 0;
|
||||
if (this._length <= 0) {
|
||||
return arr;
|
||||
}
|
||||
arr[index] = this._head.element;
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
while (linkIterator.hasNext()) {
|
||||
const newNode = linkIterator.next();
|
||||
arr[++index] = newNode.element;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
clone(): LinkedList<T> {
|
||||
let clone = new LinkedList<T>();
|
||||
let arr = this.convertToArray();
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let item = arr[i]
|
||||
clone.add(item);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
forEach(callbackfn: (value: T,index?: number,linkedlist?: LinkedList<T>) => void,
|
||||
thisArg?: Object): void {
|
||||
let index = 0;
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
if (this._length > 0) {
|
||||
callbackfn.call(thisArg, this._head.element, index, this);
|
||||
}
|
||||
while (linkIterator.hasNext()) {
|
||||
const newNode = linkIterator.next();
|
||||
callbackfn.call(thisArg, newNode.element, ++index, this);
|
||||
}
|
||||
}
|
||||
[Symbol.iterator](): IterableIterator<T> {
|
||||
let count = 0;
|
||||
let linkedlist = this
|
||||
return {
|
||||
next: function () {
|
||||
var done = count >= linkedlist._length;
|
||||
var value = !done ? linkedlist.getNode(count++).element : undefined;
|
||||
return {
|
||||
done: done,
|
||||
value: value,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Object.freeze(LinkedList);
|
||||
fastLinkedList = LinkedList;
|
||||
}
|
||||
export default {
|
||||
LinkedList: fastLinkedList,
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
extern const char _binary_js_linkedlist_js_start[];
|
||||
extern const char _binary_js_linkedlist_js_end[];
|
||||
extern const char _binary_linkedlist_abc_start[];
|
||||
extern const char _binary_linkedlist_abc_end[];
|
||||
|
||||
namespace OHOS::Util {
|
||||
static napi_value LinkedListInit(napi_env env, napi_value exports)
|
||||
{
|
||||
return exports;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_linkedlist_GetJSCode(const char **buf, int *bufLen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_js_linkedlist_js_start;
|
||||
}
|
||||
|
||||
if (bufLen != nullptr) {
|
||||
*bufLen = _binary_js_linkedlist_js_end - _binary_js_linkedlist_js_start;
|
||||
}
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_linkedlist_GetABCCode(const char **buf, int *buflen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_linkedlist_abc_start;
|
||||
}
|
||||
if (buflen != nullptr) {
|
||||
*buflen = _binary_linkedlist_abc_end - _binary_linkedlist_abc_start;
|
||||
}
|
||||
}
|
||||
|
||||
static napi_module linkedListModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = LinkedListInit,
|
||||
.nm_modname = "LinkedList",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = {0},
|
||||
};
|
||||
|
||||
extern "C" __attribute__((constructor)) void RegisterModule()
|
||||
{
|
||||
napi_module_register(&linkedListModule);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
let flag = false;
|
||||
let fastList = undefined;
|
||||
let arkPritvate = globalThis["ArkPrivate"] || undefined;
|
||||
if (arkPritvate !== undefined) {
|
||||
fastList = arkPritvate.Load(arkPritvate.List);
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
if (flag || fastList == undefined) {
|
||||
class HandlerList<T> {
|
||||
get(obj: List<T>, prop: any) {
|
||||
if (typeof prop === "symbol") {
|
||||
return obj[prop];
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("List: get out-of-bounds");
|
||||
}
|
||||
}
|
||||
return obj[prop];
|
||||
}
|
||||
set(obj: List<T>, prop: any, value: T) {
|
||||
if (
|
||||
prop === "_length" ||
|
||||
prop === "_capacity" ||
|
||||
prop === "_head" ||
|
||||
prop == "next") {
|
||||
obj[prop] = value;
|
||||
return true;
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("List: set out-of-bounds");
|
||||
} else {
|
||||
obj[index] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
deleteProperty(obj: List<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("List: deleteProperty out-of-bounds");
|
||||
}
|
||||
obj.removeByIndex(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
has(obj: List<T>, prop: any) {
|
||||
return obj.has(prop);
|
||||
}
|
||||
ownKeys(obj: List<T>) {
|
||||
var keys = [];
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
keys.push(i.toString());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
defineProperty(obj: List<T>, prop: any, desc: any) {
|
||||
return true;
|
||||
}
|
||||
getOwnPropertyDescriptor(obj: List<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("List: getOwnPropertyDescriptor out-of-bounds");
|
||||
}
|
||||
return Object.getOwnPropertyDescriptor(obj, prop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
interface IterableIterator<T> {
|
||||
next: () => {
|
||||
value: T;
|
||||
done: boolean;
|
||||
};
|
||||
}
|
||||
class NodeObj<T> {
|
||||
/* If 'any' is changed to 'T' here, an error will be reported:
|
||||
Type 'unknown' cannot be assigned to type 'T'. */
|
||||
element: any;
|
||||
next?: NodeObj<T> | null;
|
||||
constructor(element: any, next?: NodeObj<T> | null) {
|
||||
this.element = element;
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
class LinkIterator<T> {
|
||||
/* If 'any' is changed to 'T' here, an error will be reported:
|
||||
Property 'next' does not exist on type 'T' */
|
||||
private linkNode: any;
|
||||
constructor(linkNode: any) {
|
||||
this.linkNode = linkNode;
|
||||
}
|
||||
hasNext(): boolean {
|
||||
if (this.linkNode.next !== null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
next(): NodeObj<T> {
|
||||
this.linkNode = this.linkNode.next;
|
||||
return this.linkNode;
|
||||
}
|
||||
}
|
||||
class List<T> {
|
||||
/* If 'any' is changed to 'NodeObj<T> | null ' here, an error will be reported:
|
||||
Object may be 'null' */
|
||||
private _head: any;
|
||||
private _length: number;
|
||||
private _capacity: number;
|
||||
constructor(_head?: NodeObj<T>) {
|
||||
this._head = _head || null;
|
||||
this._length = 0;
|
||||
this._capacity = 10;
|
||||
return new Proxy(this, new HandlerList());
|
||||
}
|
||||
get length() {
|
||||
return this._length;
|
||||
}
|
||||
private getNode(index: number): NodeObj<T> {
|
||||
let current = this._head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current["next"];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
get(index: number): T {
|
||||
let current = this._head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current["next"];
|
||||
}
|
||||
return current.element;
|
||||
}
|
||||
add(element: T): boolean {
|
||||
if (this._length === 0) {
|
||||
let head = this._head;
|
||||
this._head = new NodeObj(element, head);
|
||||
} else {
|
||||
let prevNode = this.getNode(this._length - 1);
|
||||
prevNode.next = new NodeObj(element, prevNode["next"]);
|
||||
}
|
||||
this._length++;
|
||||
return true;
|
||||
}
|
||||
clear(): void {
|
||||
this._head = null;
|
||||
this._length = 0;
|
||||
}
|
||||
has(element: T): boolean {
|
||||
if (this._head.element === element) {
|
||||
return true;
|
||||
}
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
while (linkIterator.hasNext()) {
|
||||
const newNode = linkIterator.next();
|
||||
if (newNode.element === element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
equals(obj: Object): boolean {
|
||||
if (obj === this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof List)) {
|
||||
return false;
|
||||
} else {
|
||||
let e1 = new LinkIterator<T>(this._head);
|
||||
let e2 = new LinkIterator<T>(obj._head);
|
||||
while (e1.hasNext() && e2.hasNext()) {
|
||||
const newNode1 = e1.next();
|
||||
const newNode2 = e2.next();
|
||||
if (newNode1.element !== newNode2.element) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !(e1.hasNext() || e2.hasNext());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
getIndexOf(element: T): number {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
const curNode = this.getNode(i);
|
||||
if (curNode.element === element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
getLastIndexOf(element: T): number {
|
||||
for (let i = this._length - 1; i >= 0; i--) {
|
||||
const curNode = this.getNode(i);
|
||||
if (curNode.element === element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
removeByIndex(index: number): T {
|
||||
let oldNode = this._head;
|
||||
if (index === 0) {
|
||||
oldNode = this._head;
|
||||
this._head = oldNode && oldNode.next;
|
||||
} else {
|
||||
let prevNode = this.getNode(index - 1);
|
||||
oldNode = prevNode.next;
|
||||
prevNode.next = oldNode.next;
|
||||
}
|
||||
this._length--;
|
||||
return oldNode && oldNode.element;
|
||||
}
|
||||
remove(element: T): boolean {
|
||||
if (this.has(element)) {
|
||||
let index = this.getIndexOf(element);
|
||||
this.removeByIndex(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
replaceAllElements(callbackfn: (value: T, index?: number, list?: List<T>) => T,
|
||||
thisArg?: Object): void {
|
||||
let index = 0;
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
if (this._length > 0) {
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
this.getNode(index).element = callbackfn.call(thisArg, this._head.element, index, this);
|
||||
}
|
||||
while (linkIterator.hasNext()) {
|
||||
const newNode = linkIterator.next();
|
||||
this.getNode(++index).element = callbackfn.call(thisArg, newNode.element, index, this);
|
||||
}
|
||||
}
|
||||
getFirst(): T {
|
||||
let newNode = this.getNode(0);
|
||||
let element = newNode.element;
|
||||
return element;
|
||||
}
|
||||
getLast(): T {
|
||||
let newNode = this.getNode(this._length - 1);
|
||||
let element = newNode.element;
|
||||
return element;
|
||||
}
|
||||
insert(element: T, index: number): void {
|
||||
let newNode = new NodeObj(element);
|
||||
if (index >= 0 && index < this._length) {
|
||||
if (index === 0) {
|
||||
const current = this._head;
|
||||
newNode.next = current;
|
||||
this._head = newNode;
|
||||
} else {
|
||||
const prevNode = this.getNode(index - 1);
|
||||
newNode.next = prevNode.next;
|
||||
prevNode.next = newNode;
|
||||
}
|
||||
this._length++;
|
||||
}
|
||||
}
|
||||
set(index: number, element: T): T {
|
||||
const current = this.getNode(index);
|
||||
current.element = element;
|
||||
return current && current.element;
|
||||
}
|
||||
sort(comparator: (firstValue: T, secondValue: T) => number): void {
|
||||
let isSort = true;
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
for (let j = 0; j < this._length - 1 - i; j++) {
|
||||
if (comparator(this.getNode(j).element, this.getNode(j + 1).element) > 0) {
|
||||
isSort = false;
|
||||
let temp = this.getNode(j).element;
|
||||
this.getNode(j).element = this.getNode(j + 1).element;
|
||||
this.getNode(j + 1).element = temp;
|
||||
}
|
||||
}
|
||||
if (isSort) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
getSubList(fromIndex: number, toIndex: number): List<T> {
|
||||
if (toIndex <= fromIndex) {
|
||||
throw new Error("toIndex cannot be less than or equal to fromIndex");
|
||||
}
|
||||
toIndex = toIndex > this._length ? this._length - 1 : toIndex;
|
||||
let list = new List<T>();
|
||||
for (let i = fromIndex; i < toIndex; i++) {
|
||||
let element = this.getNode(i).element;
|
||||
list.add(element);
|
||||
if (element === null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
convertToArray(): Array<T> {
|
||||
let arr: Array<T> = [];
|
||||
let index = 0;
|
||||
if (this._length <= 0) {
|
||||
return arr;
|
||||
}
|
||||
arr[index] = this._head.element;
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
while (linkIterator.hasNext()) {
|
||||
const newNode = linkIterator.next();
|
||||
arr[++index] = newNode.element;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
forEach(callbackfn: (value: T, index?: number, list?: List<T>) => void,
|
||||
thisArg?: Object): void {
|
||||
let index = 0;
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
if (this._length > 0) {
|
||||
const linkIterator = new LinkIterator<T>(this._head);
|
||||
callbackfn.call(thisArg, this._head.element, index, this);
|
||||
}
|
||||
while (linkIterator.hasNext()) {
|
||||
const newNode = linkIterator.next();
|
||||
callbackfn.call(thisArg, newNode.element, ++index, this);
|
||||
}
|
||||
}
|
||||
[Symbol.iterator](): IterableIterator<T> {
|
||||
let count = 0;
|
||||
let list = this
|
||||
return {
|
||||
next: function () {
|
||||
var done = count >= list._length;
|
||||
var value = !done ? list.getNode(count++).element : undefined;
|
||||
return {
|
||||
done: done,
|
||||
value: value,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Object.freeze(List);
|
||||
fastList = List;
|
||||
}
|
||||
export default {
|
||||
List: fastList,
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
extern const char _binary_js_list_js_start[];
|
||||
extern const char _binary_js_list_js_end[];
|
||||
extern const char _binary_list_abc_start[];
|
||||
extern const char _binary_list_abc_end[];
|
||||
namespace OHOS::Util {
|
||||
static napi_value ListInit(napi_env env, napi_value exports)
|
||||
{
|
||||
return exports;
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_list_GetJSCode(const char **buf, int *bufLen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_js_list_js_start;
|
||||
}
|
||||
|
||||
if (bufLen != nullptr) {
|
||||
*bufLen = _binary_js_list_js_end - _binary_js_list_js_start;
|
||||
}
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_list_GetABCCode(const char **buf, int *buflen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_list_abc_start;
|
||||
}
|
||||
if (buflen != nullptr) {
|
||||
*buflen = _binary_list_abc_end - _binary_list_abc_start;
|
||||
}
|
||||
}
|
||||
|
||||
static napi_module listModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = ListInit,
|
||||
.nm_modname = "List",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = {0},
|
||||
};
|
||||
extern "C" __attribute__((constructor)) void RegisterModule()
|
||||
{
|
||||
napi_module_register(&listModule);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
let flag = false;
|
||||
let fastQueue = undefined;
|
||||
let arkPritvate = globalThis["ArkPrivate"] || undefined;
|
||||
if (arkPritvate !== undefined) {
|
||||
fastQueue = arkPritvate.Load(arkPritvate.Queue);
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
if (flag || fastQueue == undefined) {
|
||||
class HandlerQueue<T> {
|
||||
get(obj: Queue<T>, prop: any): T {
|
||||
if (typeof prop === "symbol") {
|
||||
return obj[prop];
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index > obj.length) {
|
||||
throw new Error("Queue: get out-of-bounds");
|
||||
}
|
||||
}
|
||||
return obj[prop];
|
||||
}
|
||||
set(obj: Queue<T>, prop: any, value: T): boolean {
|
||||
if (prop === "_front" || prop === "_capacity" || prop === "_rear") {
|
||||
obj[prop] = value;
|
||||
return true;
|
||||
}
|
||||
var index = Number(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index > obj.length) {
|
||||
throw new Error("Queue: set out-of-bounds");
|
||||
} else {
|
||||
obj[index] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ownKeys(obj: Queue<T>) {
|
||||
var keys = [];
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
keys.push(i.toString());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
defineProperty(obj: Queue<T>, prop: any, desc: any) {
|
||||
return true;
|
||||
}
|
||||
getOwnPropertyDescriptor(obj: Queue<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("Queue: getOwnPropertyDescriptor out-of-bounds");
|
||||
}
|
||||
return Object.getOwnPropertyDescriptor(obj, prop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
interface IterableIterator<T> {
|
||||
next: () => {
|
||||
value: T;
|
||||
done: boolean;
|
||||
};
|
||||
}
|
||||
class Queue<T> {
|
||||
private _front: number;
|
||||
private _capacity: number;
|
||||
private _rear: number;
|
||||
constructor() {
|
||||
this._front = 0;
|
||||
this._capacity = 8;
|
||||
this._rear = 0;
|
||||
return new Proxy(this, new HandlerQueue());
|
||||
}
|
||||
get length(){
|
||||
return this._rear - this._front;
|
||||
}
|
||||
add(element: T): boolean {
|
||||
if (this.isFull()) {
|
||||
this.increaseCapacity();
|
||||
}
|
||||
this[this._rear] = element;
|
||||
this._rear = (this._rear + 1) % (this._capacity + 1);
|
||||
return true;
|
||||
}
|
||||
getFirst(): T {
|
||||
return this[this._front];
|
||||
}
|
||||
pop(): T {
|
||||
let result = this[this._front];
|
||||
this._front = (this._front + 1) % (this._capacity + 1);
|
||||
return result;
|
||||
}
|
||||
forEach(callbackfn: (value: T, index?: number, queue?: Queue<T>) => void,
|
||||
thisArg?: Object): void {
|
||||
let k = 0;
|
||||
let i = this._front;
|
||||
while (true) {
|
||||
callbackfn.call(thisArg,this[i], k,this);
|
||||
i = (i + 1) % this._capacity;
|
||||
k++;
|
||||
if (i === this._rear) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private isFull(): boolean {
|
||||
return this.length === this._capacity;
|
||||
}
|
||||
[Symbol.iterator](): IterableIterator<T> {
|
||||
let count = this._front;
|
||||
return {
|
||||
next: function () {
|
||||
var done = count == this._rear;
|
||||
var value = !done ? this[count] : undefined;
|
||||
count = (count + 1) % this._capacity;
|
||||
return {
|
||||
done: done,
|
||||
value: value,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
private increaseCapacity(): void {
|
||||
this._capacity = 2 * this._capacity;
|
||||
}
|
||||
}
|
||||
Object.freeze(Queue);
|
||||
fastQueue = Queue;
|
||||
}
|
||||
export default {
|
||||
Queue: fastQueue,
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
extern const char _binary_js_queue_js_start[];
|
||||
extern const char _binary_js_queue_js_end[];
|
||||
extern const char _binary_queue_abc_start[];
|
||||
extern const char _binary_queue_abc_end[];
|
||||
namespace OHOS::Util {
|
||||
static napi_value QueueInit(napi_env env, napi_value exports)
|
||||
{
|
||||
return exports;
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_queue_GetJSCode(const char **buf, int *bufLen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_js_queue_js_start;
|
||||
}
|
||||
|
||||
if (bufLen != nullptr) {
|
||||
*bufLen = _binary_js_queue_js_end - _binary_js_queue_js_start;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_queue_GetABCCode(const char **buf, int *buflen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_queue_abc_start;
|
||||
}
|
||||
if (buflen != nullptr) {
|
||||
*buflen = _binary_queue_abc_end - _binary_queue_abc_start;
|
||||
}
|
||||
}
|
||||
|
||||
static napi_module queueModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = QueueInit,
|
||||
.nm_modname = "Queue",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = {0},
|
||||
};
|
||||
extern "C" __attribute__((constructor)) void RegisterModule()
|
||||
{
|
||||
napi_module_register(&queueModule);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
let flag = false;
|
||||
let fastStack = undefined;
|
||||
let arkPritvate = globalThis["ArkPrivate"] || undefined;
|
||||
if (arkPritvate !== undefined) {
|
||||
fastStack = arkPritvate.Load(arkPritvate.Stack);
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
if (flag || fastStack == undefined) {
|
||||
class HandlerStack<T> {
|
||||
get(obj: Stack<T>, prop: any) {
|
||||
if (typeof prop === "symbol") {
|
||||
return obj[prop];
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
let length = obj.length;
|
||||
if (index < 0 || index >= length) {
|
||||
throw new Error("Stack: get out-of-bounds");
|
||||
}
|
||||
}
|
||||
return obj[prop];
|
||||
}
|
||||
set(obj: Stack<T>, prop: any, value: T) {
|
||||
if (prop === "_length" || prop === "_capacity") {
|
||||
obj[prop] = value;
|
||||
return true;
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
let length = obj.length;
|
||||
if (index < 0 || index >= length) {
|
||||
throw new Error("Stack: set out-of-bounds");
|
||||
} else {
|
||||
obj[index] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ownKeys(obj: Stack<T>) {
|
||||
var keys = [];
|
||||
let length = obj.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
keys.push(i.toString());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
defineProperty(obj: Stack<T>, prop: any, desc: any) {
|
||||
return true;
|
||||
}
|
||||
getOwnPropertyDescriptor(obj: Stack<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
let length = obj.length;
|
||||
if (index < 0 || index >= length) {
|
||||
throw new Error("Stack: getOwnPropertyDescriptor out-of-bounds");
|
||||
}
|
||||
return Object.getOwnPropertyDescriptor(obj, prop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
interface IterableIterator<T> {
|
||||
next: () => {
|
||||
value: T;
|
||||
done: boolean;
|
||||
};
|
||||
}
|
||||
class Stack<T> {
|
||||
private _length: number = 0;
|
||||
private _capacity: number = 10;
|
||||
constructor() {
|
||||
return new Proxy(this, new HandlerStack());
|
||||
}
|
||||
get length() {
|
||||
return this._length;
|
||||
}
|
||||
push(item: T): T {
|
||||
if (this.isFull()) {
|
||||
this.increaseCapacity();
|
||||
}
|
||||
this[this._length++] = item;
|
||||
return item;
|
||||
}
|
||||
pop(): T {
|
||||
let result = this[this.length - 1];
|
||||
this._length--;
|
||||
return result;
|
||||
}
|
||||
peek(): T {
|
||||
return this[this.length - 1];
|
||||
}
|
||||
locate(element: T): number {
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
if (this[i] === element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
isEmpty(): boolean {
|
||||
return this._length == 0;
|
||||
}
|
||||
forEach(callbackfn: (value: T, index?: number, stack?: Stack<T>) => void,
|
||||
thisArg?: Object): void {
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
callbackfn.call(thisArg, this[i], i, this);
|
||||
}
|
||||
}
|
||||
private isFull(): boolean {
|
||||
return this._length === this._capacity;
|
||||
}
|
||||
private increaseCapacity(): void {
|
||||
this._capacity = 1.5 * this._capacity;
|
||||
}
|
||||
[Symbol.iterator](): IterableIterator<T> {
|
||||
let count = 0;
|
||||
let stack = this;
|
||||
return {
|
||||
next: function () {
|
||||
var done = count >= stack._length;
|
||||
var value = !done ? stack[count++] : undefined;
|
||||
return {
|
||||
done: done,
|
||||
value: value,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Object.freeze(Stack);
|
||||
fastStack = Stack;
|
||||
}
|
||||
export default {
|
||||
Stack: fastStack,
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
extern const char _binary_js_stack_js_start[];
|
||||
extern const char _binary_js_stack_js_end[];
|
||||
extern const char _binary_stack_abc_start[];
|
||||
extern const char _binary_stack_abc_end[];
|
||||
namespace OHOS::Util {
|
||||
static napi_value StackInit(napi_env env, napi_value exports)
|
||||
{
|
||||
return exports;
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_stack_GetJSCode(const char **buf, int *bufLen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_js_stack_js_start;
|
||||
}
|
||||
|
||||
if (bufLen != nullptr) {
|
||||
*bufLen = _binary_js_stack_js_end - _binary_js_stack_js_start;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_stack_GetABCCode(const char **buf, int *buflen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_stack_abc_start;
|
||||
}
|
||||
if (buflen != nullptr) {
|
||||
*buflen = _binary_stack_abc_end - _binary_stack_abc_start;
|
||||
}
|
||||
}
|
||||
|
||||
static napi_module stackModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = StackInit,
|
||||
.nm_modname = "Stack",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = {0},
|
||||
};
|
||||
|
||||
extern "C" __attribute__((constructor)) void RegisterModule()
|
||||
{
|
||||
napi_module_register(&stackModule);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "es6",
|
||||
"rootDir": "./",
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "./jscode", /* Specify an output folder for all emitted files. */
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noImplicitThis": false,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
let flag = false;
|
||||
let fastVector = undefined;
|
||||
let arkPritvate = globalThis["ArkPrivate"] || undefined;
|
||||
if (arkPritvate !== undefined) {
|
||||
fastVector = arkPritvate.Load(arkPritvate.Vector);
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
if (flag || fastVector == undefined) {
|
||||
class HandlerVector<T> {
|
||||
get(obj: Vector<T>, prop: any) {
|
||||
if (typeof prop === "symbol") {
|
||||
return obj[prop];
|
||||
}
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("Vector: get out-of-bounds");
|
||||
}
|
||||
}
|
||||
return obj[prop];
|
||||
}
|
||||
set(obj: Vector<T>, prop: any, value: T) {
|
||||
if (prop === "_length" || prop === "_capacity") {
|
||||
obj[prop] = value;
|
||||
return true;
|
||||
}
|
||||
let index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index > obj.length) {
|
||||
throw new Error("Vector: set out-of-bounds");
|
||||
} else {
|
||||
obj[index] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
deleteProperty(obj: Vector<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("vector: deleteProperty out-of-bounds");
|
||||
}
|
||||
obj.removeByIndex(index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
has(obj: Vector<T>, prop: any) {
|
||||
return obj.has(prop);
|
||||
}
|
||||
ownKeys(obj: Vector<T>) {
|
||||
let keys = [];
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
keys.push(i.toString());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
defineProperty(obj: Vector<T>, prop: any, desc: any) {
|
||||
return true;
|
||||
}
|
||||
getOwnPropertyDescriptor(obj: Vector<T>, prop: any) {
|
||||
var index = Number.parseInt(prop);
|
||||
if (Number.isInteger(index)) {
|
||||
if (index < 0 || index >= obj.length) {
|
||||
throw new Error("Vector: getOwnPropertyDescriptor out-of-bounds");
|
||||
}
|
||||
return Object.getOwnPropertyDescriptor(obj, prop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
interface IterableIterator<T> {
|
||||
next: () => {
|
||||
value: T;
|
||||
done: boolean;
|
||||
};
|
||||
}
|
||||
class Vector<T> {
|
||||
private _length: number = 0;
|
||||
private _capacity: number = 10;
|
||||
constructor() {
|
||||
return new Proxy(this, new HandlerVector());
|
||||
}
|
||||
get length() {
|
||||
return this._length;
|
||||
}
|
||||
add(element: T): boolean {
|
||||
if (this.isFull()) {
|
||||
this.resize();
|
||||
}
|
||||
this[this._length++] = element;
|
||||
return true;
|
||||
}
|
||||
insert(element: T, index: number): void {
|
||||
if (this.isFull()) {
|
||||
this.resize();
|
||||
}
|
||||
for (let i = this._length; i > index; i--) {
|
||||
this[i] = this[i - 1];
|
||||
}
|
||||
this[index] = element;
|
||||
this._length++;
|
||||
}
|
||||
has(element: T): boolean {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
if (this[i] === element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
get(index: number): T {
|
||||
return this[index];
|
||||
}
|
||||
getIndexOf(element: T): number {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
if (element === this[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
getFirstElement(): T {
|
||||
return this[0];
|
||||
}
|
||||
set(index: number, element: T): void {
|
||||
this[index] = element;
|
||||
}
|
||||
removeByIndex(index: number): void {
|
||||
for (let i = index; i < this._length - 1; i++) {
|
||||
this[i] = this[i + 1];
|
||||
}
|
||||
this._length--;
|
||||
}
|
||||
remove(element: T): boolean {
|
||||
if (this.has(element)) {
|
||||
let index = this.getIndexOf(element);
|
||||
for (let i = index; i < this._length - 1; i++) {
|
||||
this[i] = this[i + 1];
|
||||
}
|
||||
this._length--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getLastElement(): T {
|
||||
return this[this._length - 1];
|
||||
}
|
||||
getLastIndexOf(element: T): number {
|
||||
for (let i = this._length - 1; i >= 0; i--) {
|
||||
if (element === this[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
getLastIndexOfFrom(element: T, index: number): number {
|
||||
if (this.has(element)) {
|
||||
for (let i = index; i >= 0; i--) {
|
||||
if (this[i] === element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
getIndexOfFrom(element: T, index: number): number {
|
||||
if (this.has(element)) {
|
||||
for (let i = index; i < this._length; i++) {
|
||||
if (this[i] === element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
clear(): void {
|
||||
this._length = 0;
|
||||
}
|
||||
removeByRange(fromIndex: number, toIndex: number): void {
|
||||
if (fromIndex >= toIndex) {
|
||||
throw new Error(`fromIndex cannot be less than or equal to toIndex`);
|
||||
}
|
||||
toIndex = toIndex >= this.length - 1 ? this.length - 1 : toIndex;
|
||||
let i = fromIndex;
|
||||
for (let j = toIndex; j < this._length; j++) {
|
||||
this[i] = this[j];
|
||||
i++;
|
||||
}
|
||||
this._length -= toIndex - fromIndex;
|
||||
}
|
||||
setLength(newSize: number): void {
|
||||
this._length = newSize;
|
||||
}
|
||||
replaceAllElements(callbackfn: (value: T, index?: number, vector?: Vector<T>) => T,
|
||||
thisArg?: Object): void {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
this[i] = callbackfn.call(thisArg, this[i], i, this);
|
||||
}
|
||||
}
|
||||
forEach(callbackfn: (value: T, index?: number, vector?: Vector<T>) => void,
|
||||
thisArg?: Object): void {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
callbackfn.call(thisArg, this[i], i, this);
|
||||
}
|
||||
}
|
||||
sort(comparator?: (firstValue: T, secondValue: T) => number): void {
|
||||
let isSort = true;
|
||||
if (comparator) {
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
for (let j = 0; j < this._length - 1 - i; j++) {
|
||||
if (comparator(this[j], this[j + 1]) > 0) {
|
||||
isSort = false;
|
||||
let temp = this[j];
|
||||
this[j] = this[j + 1];
|
||||
this[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < this.length - 1; i++) {
|
||||
for (let j = 0; j < this._length - 1 - i; j++) {
|
||||
if (this.asciSort(this[j], this[j + 1])) {
|
||||
isSort = false;
|
||||
let temp = this[j];
|
||||
this[j] = this[j + 1];
|
||||
this[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
if (isSort) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private asciSort(curElement: any, nextElement: any): boolean {
|
||||
if ((Object.prototype.toString.call(curElement) === "[object String]" ||
|
||||
Object.prototype.toString.call(curElement) === "[object Number]") &&
|
||||
(Object.prototype.toString.call(nextElement) === "[object String]" ||
|
||||
Object.prototype.toString.call(nextElement) === "[object Number]")) {
|
||||
curElement = curElement.toString();
|
||||
nextElement = nextElement.toString();
|
||||
if(curElement > nextElement){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false;
|
||||
}
|
||||
subVector(fromIndex: number, toIndex: number): Vector<T> {
|
||||
if (fromIndex >= toIndex) {
|
||||
throw new Error(`fromIndex cannot be less than or equal to toIndex`);
|
||||
}
|
||||
toIndex = toIndex >= this._length - 1 ? this._length - 1 : toIndex;
|
||||
let vector = new Vector<T>();
|
||||
for (let i = fromIndex; i < toIndex; i++) {
|
||||
vector.add(this[i]);
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
convertToArray(): Array<T> {
|
||||
let arr = [];
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
arr[i] = this[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
copyToArray(array: Array<T>): void {
|
||||
let arr = this.convertToArray();
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
array[i] = arr[i];
|
||||
}
|
||||
}
|
||||
toString(): string {
|
||||
let str = `${this[0]}`;
|
||||
for (let i = 1; i < this._length; i++) {
|
||||
str = `${str},${this[i]}`;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
clone(): Vector<T> {
|
||||
let clone = new Vector<T>();
|
||||
for (let i = 0; i < this._length; i++) {
|
||||
this.add(this[i]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
getCapacity(): number {
|
||||
return this._capacity;
|
||||
}
|
||||
private isFull(): boolean {
|
||||
return this._length === this._capacity;
|
||||
}
|
||||
private resize(): void {
|
||||
this._capacity = 2 * this._capacity;
|
||||
}
|
||||
increaseCapacityTo(newCapacity: number): void {
|
||||
if (newCapacity >= this._length) {
|
||||
this._capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
trimToCurrentSize(): void {
|
||||
this._capacity = this._length;
|
||||
}
|
||||
setSize(newSize: number): void {
|
||||
this._length = newSize;
|
||||
}
|
||||
[Symbol.iterator](): IterableIterator<T> {
|
||||
let count = 0;
|
||||
let vector = this
|
||||
return {
|
||||
next: function () {
|
||||
var done = count >= vector._length;
|
||||
var value = !done ? vector[count++] : undefined;
|
||||
return {
|
||||
done: done,
|
||||
value: value,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Object.freeze(Vector);
|
||||
fastVector = Vector;
|
||||
}
|
||||
export default {
|
||||
Vector: fastVector,
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
extern const char _binary_js_vector_js_start[];
|
||||
extern const char _binary_js_vector_js_end[];
|
||||
extern const char _binary_vector_abc_start[];
|
||||
extern const char _binary_vector_abc_end[];
|
||||
namespace OHOS::Util {
|
||||
static napi_value VectorInit(napi_env env, napi_value exports)
|
||||
{
|
||||
return exports;
|
||||
}
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_vector_GetJSCode(const char **buf, int *bufLen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_js_vector_js_start;
|
||||
}
|
||||
|
||||
if (bufLen != nullptr) {
|
||||
*bufLen = _binary_js_vector_js_end - _binary_js_vector_js_start;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__attribute__((visibility("default"))) void NAPI_vector_GetABCCode(const char **buf, int *buflen)
|
||||
{
|
||||
if (buf != nullptr) {
|
||||
*buf = _binary_vector_abc_start;
|
||||
}
|
||||
if (buflen != nullptr) {
|
||||
*buflen = _binary_vector_abc_end - _binary_vector_abc_start;
|
||||
}
|
||||
}
|
||||
static napi_module vectorModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = VectorInit,
|
||||
.nm_modname = "Vector",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = {0},
|
||||
};
|
||||
extern "C" __attribute__((constructor)) void RegisterModule()
|
||||
{
|
||||
napi_module_register(&vectorModule);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -7,7 +7,8 @@
|
||||
"phone"
|
||||
],
|
||||
"module_list": [
|
||||
"//base/compileruntime/js_util_module/util:util_packages"
|
||||
"//base/compileruntime/js_util_module/util:util_packages",
|
||||
"//base/compileruntime/js_util_module/container:container_packages"
|
||||
],
|
||||
"inner_kits": [
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user