1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { KPointer, int32 } from './InteropTypes'; 17import { Wrapper } from './mainWrapper'; 18import { CustomTextDecoder, CustomTextEncoder } from './strings'; 19import { throwError } from './utils'; 20 21const encoder = new CustomTextEncoder(); 22const decoder = new CustomTextDecoder(); 23 24export function decodeToString(array: Uint8Array): string { 25 return decoder.decode(array); 26} 27 28export function encodeToData(string: string): Uint8Array { 29 return encoder.encode(string, false); 30} 31 32export function withString<R>(data: string, exec: Exec<string, R>): R { 33 return exec(data); 34} 35 36export function withStringArray(strings: Array<string> | undefined): Uint8Array { 37 if (strings === undefined || strings.length === 0) { 38 throwError('Error in strings array'); 39 } 40 41 let array = encoder.encodeArray(strings); 42 return array; 43} 44 45function withArray<C extends TypedArray, R>(data: C | undefined, exec: ExecWithLength<C | null, R>): R { 46 return exec(data ?? null, data?.length ?? 0); 47} 48 49export function withPtrArray<R>( 50 data: BigUint64Array, 51 access: Access, 52 exec: ExecWithLength<BigUint64Array | null, R> 53): R { 54 return exec(data ?? null, data?.length ?? 0); // TODO rethink 55} 56 57export function toPtrArray<T extends Wrapper>(data: Array<T | undefined> | undefined): BigUint64Array { 58 if (data === undefined || data.length === 0) { 59 return new BigUint64Array(0); 60 } 61 const array = new BigUint64Array(data.length); 62 for (let i = 0; i < data.length; i++) { 63 let item = data[i]; 64 array[i] = item !== undefined ? (item.ptr as bigint) : nullptr; 65 } 66 return array; 67} 68 69export function fromPtrArray<T extends Wrapper>(array: PtrArray, factory: (ptr: KPointer) => T): Array<T | undefined> { 70 if (array.length === 0) { 71 return new Array<T>(0); 72 } 73 const result = new Array<T | undefined>(array.length); 74 for (let i = 0; i < array.length; i++) { 75 let ptr = array[i]; 76 if (ptr === nullptr) { 77 result[i] = undefined; 78 } else { 79 result[i] = factory(ptr); 80 } 81 } 82 return result; 83} 84 85export function withUint8Array<T>( 86 data: Uint8Array | undefined, 87 access: Access, 88 exec: ExecWithLength<Uint8Array | null, T> 89): T { 90 return withArray(data, exec); 91} 92export function withInt8Array<T>( 93 data: Int8Array | undefined, 94 access: Access, 95 exec: ExecWithLength<Int8Array | null, T> 96): T { 97 return withArray(data, exec); 98} 99export function withUint16Array<T>( 100 data: Uint16Array | undefined, 101 access: Access, 102 exec: ExecWithLength<Uint16Array | null, T> 103): T { 104 return withArray(data, exec); 105} 106export function withInt16Array<T>( 107 data: Int16Array | undefined, 108 access: Access, 109 exec: ExecWithLength<Int16Array | null, T> 110): T { 111 return withArray(data, exec); 112} 113export function withUint32Array<T>( 114 data: Uint32Array | undefined, 115 access: Access, 116 exec: ExecWithLength<Uint32Array | null, T> 117): T { 118 return withArray(data, exec); 119} 120export function withInt32Array<T>( 121 data: Int32Array | undefined, 122 access: Access, 123 exec: ExecWithLength<Int32Array | null, T> 124): T { 125 return withArray(data, exec); 126} 127export function withFloat32Array<T>( 128 data: Float32Array | undefined, 129 access: Access, 130 exec: ExecWithLength<Float32Array | null, T> 131): T { 132 return withArray(data, exec); 133} 134export function withFloat64Array<T>( 135 data: Float64Array | undefined, 136 access: Access, 137 exec: ExecWithLength<Float64Array | null, T> 138): T { 139 return withArray(data, exec); 140} 141export function wasmHeap(): ArrayBuffer { 142 throw new Error('Unused'); 143} 144 145export enum Access { 146 READ = 1, // 1 << 0, 147 WRITE = 2, // 1 << 1, 148 READWRITE = 3 // READ | WRITE 149} 150export function isRead(access: Access): boolean { 151 return !!(access & Access.READ); 152} 153export function isWrite(access: Access): boolean { 154 return !!(access & Access.WRITE); 155} 156 157export type Exec<P, R> = (pointer: P) => R; 158export type ExecWithLength<P, R> = (pointer: P, length: int32) => R; 159 160export type TypedArray = 161 | Uint8Array 162 | Int8Array 163 | Uint16Array 164 | Int16Array 165 | Uint32Array 166 | Int32Array 167 | Float32Array 168 | Float64Array; 169 170export const nullptr: bigint = BigInt(0); 171export type PtrArray = Uint32Array | BigUint64Array; 172