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 { isNullPtr } from './Wrapper'; 17import { decodeToString } from './arrays'; 18import { Wrapper } from './mainWrapper'; 19import { global } from './global'; 20import { int32, KInt, KPointer, nullptr } from './InteropTypes'; 21 22export abstract class NativeStringBase extends Wrapper { 23 constructor(ptr: KPointer) { 24 super(ptr); 25 } 26 27 protected abstract bytesLength(): int32; 28 protected abstract getData(data: Uint8Array): void; 29 30 toString(): string { 31 let length = this.bytesLength(); 32 let data = new Uint8Array(length); 33 this.getData(data); 34 return decodeToString(data); 35 } 36 37 abstract close(): void; 38} 39 40export abstract class ArrayDecoder<T> { 41 abstract getArraySize(blob: KPointer): int32; 42 abstract disposeArray(blob: KPointer): void; 43 abstract getArrayElement(blob: KPointer, index: int32): T; 44 45 decode(blob: KPointer): Array<T> { 46 const size = this.getArraySize(blob); 47 const result = new Array<T>(size); 48 for (let index = 0; index < size; index++) { 49 result[index] = this.getArrayElement(blob, index); 50 } 51 this.disposeArray(blob); 52 return result; 53 } 54} 55 56// TODO: the semicolons after methods in these interfaces are to 57// workaround ArkTS compiler parser bug 58export interface CallbackRegistry { 59 // CC-OFFNXT(no_explicit_any) project code style 60 registerCallback(callback: any, obj: any): KPointer; 61} 62 63export interface PlatformDefinedData { 64 nativeString(ptr: KPointer): NativeStringBase; 65 nativeStringArrayDecoder(): ArrayDecoder<NativeStringBase>; 66 callbackRegistry(): CallbackRegistry | undefined; 67} 68 69export function withStringResult(ptr: KPointer): string | undefined { 70 if (isNullPtr(ptr)) { 71 return undefined; 72 } 73 let managedString = new NativeString(ptr); 74 let result = managedString?.toString(); 75 managedString?.close(); 76 return result; 77} 78 79export class NativeString extends NativeStringBase { 80 constructor(ptr: KPointer) { 81 super(ptr); 82 } 83 protected bytesLength(): int32 { 84 return global.interop._StringLength(this.ptr); 85 } 86 protected getData(data: Uint8Array): void { 87 global.interop._StringData(this.ptr, data, data.length); 88 } 89 close(): void { 90 global.interop._InvokeFinalizer(this.ptr, global.interop._GetStringFinalizer()); 91 this.ptr = nullptr; 92 } 93} 94 95export class NativePtrDecoder extends ArrayDecoder<KPointer> { 96 getArraySize(blob: KPointer): KInt { 97 return global.interop._GetPtrVectorSize(blob); 98 } 99 disposeArray(blob: KPointer): void { 100 // TODO 101 } 102 getArrayElement(blob: KPointer, index: int32): KPointer { 103 return global.interop._GetPtrVectorElement(blob, index); 104 } 105} 106