• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #include "ark_interop_internal.h"
17 #include "ark_interop_napi.h"
18 #include "ark_interop_log.h"
19 
20 #include <cstdint>
21 #include <cassert>
22 #include <cstdlib>
23 #include <vector>
24 
25 using namespace panda;
26 using namespace panda::ecmascript;
27 
28 static constexpr int32_t STRING_TABLE_THRESHOLD = 128;
29 
ARKTS_CreateUtf8(ARKTS_Env env,const char * value,int32_t size)30 ARKTS_Value ARKTS_CreateUtf8(ARKTS_Env env, const char* value, int32_t size)
31 {
32     ARKTS_ASSERT_P(env, "env is null");
33     ARKTS_ASSERT_P(value, "value is null");
34 
35     auto vm = P_CAST(env, EcmaVM*);
36     Local<JSValueRef> result;
37     if (size < STRING_TABLE_THRESHOLD) {
38         result = StringRef::NewFromUtf8(vm, value, size);
39     } else {
40         result = StringRef::NewFromUtf8WithoutStringTable(vm, value, size);
41     }
42     return ARKTS_FromHandle(result);
43 }
44 
ARKTS_IsString(ARKTS_Env env,ARKTS_Value value)45 bool ARKTS_IsString(ARKTS_Env env, ARKTS_Value value)
46 {
47     auto v = BIT_CAST(value, JSValueRef);
48     if (v.IsHole() || !v.IsHeapObject()) {
49         return false;
50     }
51     v = *P_CAST(value, JSValueRef*);
52     auto vm = P_CAST(env, EcmaVM*);
53     return v.IsString(vm);
54 }
55 
ARKTS_GetValueUtf8Size(ARKTS_Env env,ARKTS_Value value)56 int32_t ARKTS_GetValueUtf8Size(ARKTS_Env env, ARKTS_Value value)
57 {
58     ARKTS_ASSERT_I(env, "env is null");
59     ARKTS_ASSERT_I(ARKTS_IsString(env, value), "not a string");
60     auto vm = P_CAST(env, EcmaVM*);
61     auto v = BIT_CAST(value, Local<StringRef>);
62     return v->Utf8Length(vm, true);
63 }
64 
ARKTS_GetValueUtf8(ARKTS_Env env,ARKTS_Value value,int32_t capacity,char * buffer)65 int32_t ARKTS_GetValueUtf8(ARKTS_Env env, ARKTS_Value value, int32_t capacity, char* buffer)
66 {
67     ARKTS_ASSERT_I(ARKTS_IsString(env, value), "not a string");
68     auto vm = P_CAST(env, EcmaVM*);
69     auto v = BIT_CAST(value, Local<StringRef>);
70     return v->WriteUtf8(vm, buffer, capacity, true);
71 }
72 
ARKTS_GetValueCString(ARKTS_Env env,ARKTS_Value value)73 const char* ARKTS_GetValueCString(ARKTS_Env env, ARKTS_Value value)
74 {
75     ARKTS_ASSERT_I(env, "env is null");
76     ARKTS_ASSERT_I(ARKTS_IsString(env, value), "not a string");
77     auto vm = P_CAST(env, EcmaVM*);
78     auto v = BIT_CAST(value, Local<StringRef>);
79     auto size = v->Utf8Length(vm, true);
80     if (size <= 0) {
81         return nullptr;
82     }
83     auto result = (char*) malloc(sizeof(char) * size);
84     if (!result) {
85         LOGE("ARKTS_GetValueCString fail, out of memory");
86         return nullptr;
87     }
88     v->WriteUtf8(vm, result, size, true);
89     return result;
90 }
91 
ARKTS_FreeCString(const char * src)92 void ARKTS_FreeCString(const char* src)
93 {
94     free(reinterpret_cast<void*>(const_cast<char*>(src)));
95 }
96 
ARKTS_GetStringInfo(ARKTS_Env env,ARKTS_Value value)97 ARKTS_StringInfo ARKTS_GetStringInfo(ARKTS_Env env, ARKTS_Value value)
98 {
99     ARKTS_ASSERT(env, "env is null", {});
100     ARKTS_ASSERT(ARKTS_IsString(env, value), "not a string", {});
101 
102     auto vm = P_CAST(env, EcmaVM*);
103     auto string = BIT_CAST(value, Local<StringRef>);
104 
105     auto isCompressed = string->IsCompressed(vm);
106     auto length = string->Length(vm);
107 
108     return { isCompressed, length };
109 }
110 
ARKTS_StringCopy(ARKTS_Env env,ARKTS_Value value,void * dst,uint32_t length)111 void ARKTS_StringCopy(ARKTS_Env env, ARKTS_Value value, void* dst, uint32_t length)
112 {
113     ARKTS_ASSERT_V(env, "env is null");
114     ARKTS_ASSERT_V(ARKTS_IsString(env, value), "not a string");
115     ARKTS_ASSERT_V(dst, "dst is null");
116 
117     auto vm = P_CAST(env, EcmaVM*);
118     auto string = BIT_CAST(value, Local<StringRef>);
119     if (string->IsCompressed(vm)) {
120         string->WriteLatin1(vm, reinterpret_cast<char*>(dst), length);
121     } else {
122         string->WriteUtf16(vm, reinterpret_cast<char16_t*>(dst), length);
123     }
124 }
125 
ARKTS_CreateString(ARKTS_Env env,bool isCompressed,uint32_t length,const void * data)126 ARKTS_Value ARKTS_CreateString(ARKTS_Env env, bool isCompressed, uint32_t length, const void* data)
127 {
128     ARKTS_ASSERT_P(env, "env is null");
129     ARKTS_ASSERT_P(data, "data is null");
130 
131     auto vm = P_CAST(env, EcmaVM*);
132 
133     Local<StringRef> result;
134     if (length < STRING_TABLE_THRESHOLD) {
135         if (isCompressed) {
136             result = StringRef::NewFromUtf8(vm, reinterpret_cast<const char *>(data), length);
137         } else {
138             result = StringRef::NewFromUtf16(vm, reinterpret_cast<const char16_t *>(data), length);
139         }
140     } else {
141         if (isCompressed) {
142             result = StringRef::NewFromUtf8WithoutStringTable(vm, reinterpret_cast<const char *>(data), length);
143         } else {
144             result = StringRef::NewFromUtf16WithoutStringTable(vm, reinterpret_cast<const char16_t *>(data), length);
145         }
146     }
147     return ARKTS_FromHandle(result);
148 }
149