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
16 #ifndef TS_TYPES_H
17 #define TS_TYPES_H
18
19 #include <cstdint>
20 #include <cstdlib>
21 #include <cmath>
22 #include <cstring>
23 #include "securec.h"
24
25 // NOLINTBEGIN
26
27 struct KStringPtrImpl {
KStringPtrImplKStringPtrImpl28 KStringPtrImpl(const char *str) : value(nullptr), owned(true)
29 {
30 int len = str ? strlen(str) : 0;
31 assign(str, len);
32 }
KStringPtrImplKStringPtrImpl33 KStringPtrImpl(const char *str, int len, bool isOwned) : value(nullptr), owned(isOwned)
34 {
35 assign(str, len);
36 }
KStringPtrImplKStringPtrImpl37 KStringPtrImpl() : value(nullptr), lengthStr(0), owned(true) {}
38
39 KStringPtrImpl(const KStringPtrImpl &other) = delete;
40 KStringPtrImpl &operator=(const KStringPtrImpl &other) = delete;
41
KStringPtrImplKStringPtrImpl42 KStringPtrImpl(KStringPtrImpl &&other)
43 {
44 this->value = other.release();
45 this->owned = other.owned;
46 other.owned = false;
47 this->lengthStr = other.lengthStr;
48 }
49
~KStringPtrImplKStringPtrImpl50 ~KStringPtrImpl()
51 {
52 if (value && owned)
53 free(value);
54 }
55
isNullKStringPtrImpl56 bool isNull() const
57 {
58 return value == nullptr;
59 }
c_strKStringPtrImpl60 const char *c_str() const
61 {
62 return value;
63 }
dataKStringPtrImpl64 char *data() const
65 {
66 return value;
67 }
lengthKStringPtrImpl68 int length() const
69 {
70 return lengthStr;
71 }
72
resizeKStringPtrImpl73 void resize(unsigned int size)
74 {
75 lengthStr = size;
76 if (!owned)
77 return;
78 // Ignore old content.
79 if (value && owned)
80 free(value);
81 value = reinterpret_cast<char *>(std::malloc(size + 1));
82 if (value == nullptr) {
83 // NOTE(khil): should be refactored to proper malloc
84 return;
85 }
86 value[size] = 0;
87 }
88
assignKStringPtrImpl89 void assign(const char *data)
90 {
91 assign(data, data ? strlen(data) : 0);
92 }
93
assignKStringPtrImpl94 void assign(const char *data, unsigned int len)
95 {
96 if (value && owned)
97 free(value);
98 if (data) {
99 if (owned) {
100 value = reinterpret_cast<char *>(std::malloc(len + 1));
101 if (!value) {
102 return;
103 }
104 memcpy_s(value, len, data, len);
105 value[len] = 0;
106 } else {
107 value = const_cast<char *>(data);
108 }
109 } else {
110 value = nullptr;
111 }
112 lengthStr = len;
113 }
114
115 protected:
releaseKStringPtrImpl116 char *release()
117 {
118 char *result = this->value;
119 this->value = nullptr;
120 return result;
121 }
122
123 private:
124 char *value;
125 int lengthStr;
126 bool owned;
127 };
128
129 struct KInteropNumber {
130 int8_t tag;
131 union {
132 int32_t i32;
133 float f32;
134 };
fromDoubleKInteropNumber135 static inline KInteropNumber fromDouble(double value)
136 {
137 KInteropNumber result = {0, {0}};
138 // NOTE(khil): boundary check
139 if (value == std::floor(value)) {
140 result.tag = 102U; // ARK_TAG_INT32
141 result.i32 = (int)value;
142 } else {
143 result.tag = 103U; // ARK_TAG_FLOAT32
144 result.f32 = (float)value;
145 }
146 return result;
147 }
asDoubleKInteropNumber148 inline double asDouble()
149 {
150 if (tag == 102U) // ARK_TAG_INT32
151 return (double)i32;
152 else
153 return (double)f32;
154 }
155 };
156
157 typedef int8_t KBoolean;
158 typedef uint8_t KByte;
159 typedef int16_t KChar;
160 typedef int16_t KShort;
161 typedef uint16_t KUShort;
162 typedef int32_t KInt;
163 typedef uint32_t KUInt;
164 typedef float KFloat;
165 typedef int64_t KLong;
166 typedef double KDouble;
167 typedef void *KNativePointer;
168 typedef KStringPtrImpl KStringPtr;
169 typedef float *KFloatArray;
170 typedef const uint8_t *KStringArray;
171 typedef void **KNativePointerArray;
172
173 struct KInteropBuffer {
174 KLong length;
175 KNativePointer data;
176
177 KInt resourceId;
178 void (*dispose)(KInt /* resourceId for now */);
179 };
180
181 struct KInteropReturnBuffer {
182 KInt length;
183 KNativePointer data;
184 void (*dispose)(KNativePointer data, KInt length);
185 };
186
187 struct KLength {
188 KByte type;
189 KFloat value;
190 KInt unit;
191 KInt resource;
192 };
193
194 // CC-OFFNXT(G.FUD.06) switch-case, ODR
ParseKLength(const KStringPtrImpl & string,KLength * result)195 inline void ParseKLength(const KStringPtrImpl &string, KLength *result)
196 {
197 char *suffixPtr = nullptr;
198
199 float value = std::strtof(string.c_str(), &suffixPtr);
200
201 if (!suffixPtr || suffixPtr == string.c_str()) {
202 // not a numeric value
203 result->unit = -1;
204 return;
205 }
206 result->value = value;
207 if (suffixPtr[0] == '\0' || (suffixPtr[0] == 'v' && suffixPtr[1] == 'p')) {
208 result->unit = 1;
209 } else if (suffixPtr[0] == '%') {
210 result->unit = 3U;
211 } else if (suffixPtr[0] == 'p' && suffixPtr[1] == 'x') {
212 result->unit = 0;
213 } else if (suffixPtr[0] == 'l' && suffixPtr[1] == 'p' && suffixPtr[2U] == 'x') {
214 result->unit = 4U;
215 } else if (suffixPtr[0] == 'f' && suffixPtr[1] == 'p') {
216 result->unit = 2U;
217 } else {
218 result->unit = -1;
219 }
220 }
221
222 struct KVMContextRaw;
223 typedef KVMContextRaw *KVMContext;
224
225 // BEWARE: this MUST never be used in user code, only in very rare service code.
226 struct KVMObjectRaw;
227 typedef KVMObjectRaw *KVMObjectHandle;
228
229 typedef struct KVMDeferred {
230 void *handler;
231 void *context;
232 void (*resolve)(KVMDeferred *thiz, uint8_t *data, int32_t length);
233 void (*reject)(KVMDeferred *thiz, const char *message);
234 } KVMDeferred;
235
236 template <class T>
ptr(KNativePointer ptr)237 T *ptr(KNativePointer ptr)
238 {
239 return reinterpret_cast<T *>(ptr);
240 }
241
242 template <class T>
ref(KNativePointer ptr)243 T &ref(KNativePointer ptr)
244 {
245 return *reinterpret_cast<T *>(ptr);
246 }
247
NativePtr(void * pointer)248 inline KNativePointer NativePtr(void *pointer)
249 {
250 return reinterpret_cast<KNativePointer>(pointer);
251 }
252
253 template <class T>
fnPtr(void (* pointer)(T *))254 KNativePointer fnPtr(void (*pointer)(T *))
255 {
256 return reinterpret_cast<KNativePointer>(pointer);
257 }
258
259 // NOLINTEND
260
261 #endif /* TS_TYPES_H */
262