1 /*
2 * Copyright (C) 2022 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 "napi_parser_utils.h"
17
18 #include <string>
19 #include <vector>
20
21 namespace OHOS {
22 namespace Bluetooth {
23
24 // shall check object type is napi_object before, if it's other type, return false
25 // If the 'name' field is not exist, or napi function call error, return false
NapiIsObjectPropertyExist(napi_env env,napi_value object,const char * name)26 static bool NapiIsObjectPropertyExist(napi_env env, napi_value object, const char *name)
27 {
28 auto status = NapiIsObject(env, object);
29 if (status != napi_ok) {
30 HILOGE("expect object");
31 return false;
32 }
33 bool exist = false;
34 status = napi_has_named_property(env, object, name, &exist);
35 if (status != napi_ok) {
36 HILOGE("Get object property failed, name: %{public}s", name);
37 return false;
38 }
39 return exist;
40 }
41
NapiParseGattService(napi_env env,napi_value object,NapiGattService & outService)42 napi_status NapiParseGattService(napi_env env, napi_value object, NapiGattService &outService)
43 {
44 NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "isPrimary", "characteristics",
45 "includeServices"}));
46
47 std::string uuid {};
48 bool isPrimary = true;
49 std::vector<NapiBleCharacteristic> characteristics {};
50 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
51 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", uuid));
52 NAPI_BT_CALL_RETURN(NapiParseObjectBoolean(env, object, "isPrimary", isPrimary));
53 NAPI_BT_CALL_RETURN(NapiParseObjectArray(env, object, "characteristics", characteristics));
54 if (NapiIsObjectPropertyExist(env, object, "includeServices")) {
55 std::vector<NapiGattService> includeServices {};
56 NAPI_BT_CALL_RETURN(NapiParseObjectArray(env, object, "includeServices", includeServices));
57 outService.includeServices = std::move(includeServices);
58 }
59 outService.serviceUuid = UUID::FromString(uuid);
60 outService.isPrimary = isPrimary;
61 outService.characteristics = std::move(characteristics);
62 return napi_ok;
63 }
64
NapiParseGattCharacteristic(napi_env env,napi_value object,NapiBleCharacteristic & outCharacteristic)65 napi_status NapiParseGattCharacteristic(napi_env env, napi_value object, NapiBleCharacteristic &outCharacteristic)
66 {
67 NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "characteristicUuid",
68 "characteristicValue", "descriptors"}));
69
70 std::string serviceUuid {};
71 std::string characterUuid {};
72 std::vector<uint8_t> characterValue {};
73 std::vector<NapiBleDescriptor> descriptors {};
74 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
75 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", serviceUuid));
76 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "characteristicUuid", characterUuid));
77 NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "characteristicValue", characterValue));
78 NAPI_BT_CALL_RETURN(NapiParseObjectArray(env, object, "descriptors", descriptors));
79
80 outCharacteristic.serviceUuid = UUID::FromString(serviceUuid);
81 outCharacteristic.characteristicUuid = UUID::FromString(characterUuid);
82 outCharacteristic.characteristicValue = std::move(characterValue);
83 outCharacteristic.descriptors = std::move(descriptors);
84 return napi_ok;
85 }
86
NapiParseGattDescriptor(napi_env env,napi_value object,NapiBleDescriptor & outDescriptor)87 napi_status NapiParseGattDescriptor(napi_env env, napi_value object, NapiBleDescriptor &outDescriptor)
88 {
89 NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "characteristicUuid",
90 "descriptorUuid", "descriptorValue"}));
91
92 std::string serviceUuid {};
93 std::string characterUuid {};
94 std::string descriptorUuid {};
95 std::vector<uint8_t> descriptorValue {};
96 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
97 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", serviceUuid));
98 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "characteristicUuid", characterUuid));
99 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "descriptorUuid", descriptorUuid));
100 NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "descriptorValue", descriptorValue));
101
102 outDescriptor.serviceUuid = UUID::FromString(serviceUuid);
103 outDescriptor.characteristicUuid = UUID::FromString(characterUuid);
104 outDescriptor.descriptorUuid = UUID::FromString(descriptorUuid);
105 outDescriptor.descriptorValue = std::move(descriptorValue);
106 return napi_ok;
107 }
108
NapiParseNotifyCharacteristic(napi_env env,napi_value object,NapiNotifyCharacteristic & outCharacter)109 napi_status NapiParseNotifyCharacteristic(napi_env env, napi_value object, NapiNotifyCharacteristic &outCharacter)
110 {
111 NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "characteristicUuid",
112 "characteristicValue", "confirm"}));
113
114 std::string serviceUuid {};
115 std::string characterUuid {};
116 std::vector<uint8_t> characterValue {};
117 bool confirm = false;
118 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
119 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", serviceUuid));
120 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "characteristicUuid", characterUuid));
121 NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "characteristicValue", characterValue));
122 NAPI_BT_CALL_RETURN(NapiParseObjectBoolean(env, object, "confirm", confirm));
123
124 outCharacter.serviceUuid = UUID::FromString(serviceUuid);
125 outCharacter.characterUuid = UUID::FromString(characterUuid);
126 outCharacter.characterValue = std::move(characterValue);
127 outCharacter.confirm = confirm;
128 return napi_ok;
129 }
130
NapiParseGattsServerResponse(napi_env env,napi_value object,NapiGattsServerResponse & rsp)131 napi_status NapiParseGattsServerResponse(napi_env env, napi_value object, NapiGattsServerResponse &rsp)
132 {
133 NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"deviceId", "transId", "status", "offset",
134 "value"}));
135
136 std::string deviceId {};
137 int transId = 0;
138 int status = 0;
139 int offset = 0;
140 std::vector<uint8_t> value {};
141 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
142 NAPI_BT_CALL_RETURN(NapiParseObjectBdAddr(env, object, "deviceId", deviceId));
143 NAPI_BT_CALL_RETURN(NapiParseObjectInt32(env, object, "transId", transId));
144 NAPI_BT_CALL_RETURN(NapiParseObjectInt32(env, object, "status", status));
145 NAPI_BT_CALL_RETURN(NapiParseObjectInt32(env, object, "offset", offset));
146 NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "value", value));
147
148 rsp.deviceId = deviceId;
149 rsp.transId = transId;
150 rsp.status = status;
151 rsp.offset = offset;
152 rsp.value = std::move(value);
153 return napi_ok;
154 }
155
NapiParseBoolean(napi_env env,napi_value value,bool & outBoolean)156 napi_status NapiParseBoolean(napi_env env, napi_value value, bool &outBoolean)
157 {
158 bool boolean = false;
159 NAPI_BT_CALL_RETURN(NapiIsBoolean(env, value));
160 NAPI_BT_CALL_RETURN(napi_get_value_bool(env, value, &boolean));
161 outBoolean = boolean;
162 return napi_ok;
163 }
164
NapiParseInt32(napi_env env,napi_value value,int32_t & outNum)165 napi_status NapiParseInt32(napi_env env, napi_value value, int32_t &outNum)
166 {
167 int32_t num = 0;
168 NAPI_BT_CALL_RETURN(NapiIsNumber(env, value));
169 NAPI_BT_CALL_RETURN(napi_get_value_int32(env, value, &num));
170 outNum = num;
171 return napi_ok;
172 }
173
NapiParseUint32(napi_env env,napi_value value,uint32_t & outNum)174 napi_status NapiParseUint32(napi_env env, napi_value value, uint32_t &outNum)
175 {
176 uint32_t num = 0;
177 NAPI_BT_CALL_RETURN(NapiIsNumber(env, value));
178 NAPI_BT_CALL_RETURN(napi_get_value_uint32(env, value, &num));
179 outNum = num;
180 return napi_ok;
181 }
182
NapiParseString(napi_env env,napi_value value,std::string & outStr)183 napi_status NapiParseString(napi_env env, napi_value value, std::string &outStr)
184 {
185 std::string str {};
186 NAPI_BT_CALL_RETURN(NapiIsString(env, value));
187 NAPI_BT_RETURN_IF(!ParseString(env, str, value), "parse string failed", napi_invalid_arg);
188 outStr = std::move(str);
189 return napi_ok;
190 }
191
NapiParseBdAddr(napi_env env,napi_value value,std::string & outAddr)192 napi_status NapiParseBdAddr(napi_env env, napi_value value, std::string &outAddr)
193 {
194 std::string bdaddr {};
195 NAPI_BT_CALL_RETURN(NapiParseString(env, value, bdaddr));
196 NAPI_BT_RETURN_IF(!IsValidAddress(bdaddr), "Invalid bdaddr", napi_invalid_arg);
197 outAddr = std::move(bdaddr);
198 return napi_ok;
199 }
200
NapiParseUuid(napi_env env,napi_value value,std::string & outUuid)201 napi_status NapiParseUuid(napi_env env, napi_value value, std::string &outUuid)
202 {
203 std::string uuid {};
204 NAPI_BT_CALL_RETURN(NapiParseString(env, value, uuid));
205 NAPI_BT_RETURN_IF(!IsValidUuid(uuid), "Invalid uuid", napi_invalid_arg);
206 outUuid = std::move(uuid);
207 return napi_ok;
208 }
209
NapiParseArrayBuffer(napi_env env,napi_value value,std::vector<uint8_t> & outVec)210 napi_status NapiParseArrayBuffer(napi_env env, napi_value value, std::vector<uint8_t> &outVec)
211 {
212 uint8_t *data = nullptr;
213 size_t size = 0;
214 NAPI_BT_CALL_RETURN(NapiIsArrayBuffer(env, value));
215 bool isSuccess = ParseArrayBuffer(env, &data, size, value);
216 if (!isSuccess) {
217 HILOGE("Parse arraybuffer failed");
218 return napi_invalid_arg;
219 }
220 std::vector<uint8_t> vec(data, data + size);
221 outVec = std::move(vec);
222 return napi_ok;
223 }
224
NapiGetObjectProperty(napi_env env,napi_value object,const char * name,napi_value & outProperty,bool & outExist)225 static napi_status NapiGetObjectProperty(napi_env env, napi_value object, const char *name, napi_value &outProperty,
226 bool &outExist)
227 {
228 bool exist = false;
229 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
230 NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &exist));
231 if (exist) {
232 napi_value property;
233 NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
234 outProperty = property;
235 }
236 outExist = exist;
237 return napi_ok;
238 }
NapiGetObjectProperty(napi_env env,napi_value object,const char * name,napi_value & outProperty)239 napi_status NapiGetObjectProperty(napi_env env, napi_value object, const char *name, napi_value &outProperty)
240 {
241 bool exist = false;
242 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, outProperty, exist));
243 NAPI_BT_RETURN_IF(!exist, "no needed property", napi_invalid_arg);
244 return napi_ok;
245 }
NapiGetObjectPropertyOptional(napi_env env,napi_value object,const char * name,napi_value & outProperty,bool & outExist)246 napi_status NapiGetObjectPropertyOptional(napi_env env, napi_value object, const char *name, napi_value &outProperty,
247 bool &outExist)
248 {
249 return NapiGetObjectProperty(env, object, name, outProperty, outExist);
250 }
251
NapiParseObjectBoolean(napi_env env,napi_value object,const char * name,bool & outBoolean)252 napi_status NapiParseObjectBoolean(napi_env env, napi_value object, const char *name, bool &outBoolean)
253 {
254 napi_value property;
255 bool boolean = true;
256 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
257 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
258 NAPI_BT_CALL_RETURN(NapiParseBoolean(env, property, boolean));
259 outBoolean = boolean;
260 return napi_ok;
261 }
262
NapiParseObjectUuid(napi_env env,napi_value object,const char * name,std::string & outUuid)263 napi_status NapiParseObjectUuid(napi_env env, napi_value object, const char *name, std::string &outUuid)
264 {
265 napi_value property;
266 std::string uuid {};
267 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
268 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
269 NAPI_BT_CALL_RETURN(NapiParseUuid(env, property, uuid));
270 outUuid = std::move(uuid);
271 return napi_ok;
272 }
273
NapiParseObjectArrayBuffer(napi_env env,napi_value object,const char * name,std::vector<uint8_t> & outVec)274 napi_status NapiParseObjectArrayBuffer(napi_env env, napi_value object, const char *name, std::vector<uint8_t> &outVec)
275 {
276 napi_value property;
277 std::vector<uint8_t> vec {};
278 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
279 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
280 NAPI_BT_CALL_RETURN(NapiParseArrayBuffer(env, property, vec));
281 outVec = std::move(vec);
282 return napi_ok;
283 }
284
NapiParseObjectBdAddr(napi_env env,napi_value object,const char * name,std::string & outAddr)285 napi_status NapiParseObjectBdAddr(napi_env env, napi_value object, const char *name, std::string &outAddr)
286 {
287 napi_value property;
288 std::string bdaddr {};
289 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
290 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
291 NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, property, bdaddr));
292 outAddr = std::move(bdaddr);
293 return napi_ok;
294 }
295
NapiParseObjectInt32(napi_env env,napi_value object,const char * name,int32_t & outNum)296 napi_status NapiParseObjectInt32(napi_env env, napi_value object, const char *name, int32_t &outNum)
297 {
298 napi_value property;
299 int32_t num = 0;
300 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
301 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
302 NAPI_BT_CALL_RETURN(NapiParseInt32(env, property, num));
303 outNum = num;
304 return napi_ok;
305 }
306
NapiParseObjectUint32(napi_env env,napi_value object,const char * name,uint32_t & outNum)307 napi_status NapiParseObjectUint32(napi_env env, napi_value object, const char *name, uint32_t &outNum)
308 {
309 napi_value property;
310 uint32_t num = 0;
311 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
312 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
313 NAPI_BT_CALL_RETURN(NapiParseUint32(env, property, num));
314 outNum = num;
315 return napi_ok;
316 }
317
NapiParseObjectBooleanOptional(napi_env env,napi_value object,const char * name,bool & outBoolean,bool & outExist)318 napi_status NapiParseObjectBooleanOptional(napi_env env, napi_value object, const char *name, bool &outBoolean,
319 bool &outExist)
320 {
321 napi_value property;
322 bool boolean = true;
323 bool exist = false;
324 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
325 NAPI_BT_CALL_RETURN(NapiGetObjectPropertyOptional(env, object, name, property, exist));
326 if (exist) {
327 NAPI_BT_CALL_RETURN(NapiParseBoolean(env, property, boolean));
328 outBoolean = boolean;
329 }
330 outExist = exist;
331 return napi_ok;
332 }
NapiParseObjectInt32Optional(napi_env env,napi_value object,const char * name,int32_t & outNum,bool & outExist)333 napi_status NapiParseObjectInt32Optional(napi_env env, napi_value object, const char *name, int32_t &outNum,
334 bool &outExist)
335 {
336 napi_value property;
337 int32_t num = 0;
338 bool exist = false;
339 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
340 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property, exist));
341 if (exist) {
342 NAPI_BT_CALL_RETURN(NapiParseInt32(env, property, num));
343 outNum = num;
344 }
345 outExist = exist;
346 return napi_ok;
347 }
NapiParseObjectUint32Optional(napi_env env,napi_value object,const char * name,uint32_t & outNum,bool & outExist)348 napi_status NapiParseObjectUint32Optional(napi_env env, napi_value object, const char *name, uint32_t &outNum,
349 bool &outExist)
350 {
351 napi_value property;
352 uint32_t num = 0;
353 bool exist = false;
354 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
355 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property, exist));
356 if (exist) {
357 NAPI_BT_CALL_RETURN(NapiParseUint32(env, property, num));
358 outNum = num;
359 }
360 outExist = exist;
361 return napi_ok;
362 }
363
364 // Parse params template, used for NapiParseArray
365 template <typename T>
NapiParseObject(napi_env env,napi_value object,T & outObj)366 napi_status NapiParseObject(napi_env env, napi_value object, T &outObj)
367 {
368 HILOGE("Unimpleted type");
369 return napi_invalid_arg;
370 }
371
372 template <>
NapiParseObject(napi_env env,napi_value object,std::string & outObj)373 napi_status NapiParseObject<std::string>(napi_env env, napi_value object, std::string &outObj)
374 {
375 return NapiParseString(env, object, outObj);
376 }
377
378 template <>
NapiParseObject(napi_env env,napi_value object,UUID & outObj)379 napi_status NapiParseObject<UUID>(napi_env env, napi_value object, UUID &outObj)
380 {
381 std::string uuid {};
382 NAPI_BT_CALL_RETURN(NapiParseUuid(env, object, uuid));
383 outObj = UUID::FromString(uuid);
384 return napi_ok;
385 }
386
387 template <>
NapiParseObject(napi_env env,napi_value object,NapiAdvManufactureData & outObj)388 napi_status NapiParseObject<NapiAdvManufactureData>(napi_env env, napi_value object, NapiAdvManufactureData &outObj)
389 {
390 NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"manufactureId", "manufactureValue"}));
391 uint32_t num = 0;
392 std::vector<uint8_t> vec {};
393 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
394 NAPI_BT_CALL_RETURN(NapiParseObjectUint32(env, object, "manufactureId", num));
395 NAPI_BT_RETURN_IF(num > 0xFFFF, "Invalid manufactureId", napi_invalid_arg);
396 NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "manufactureValue", vec));
397
398 outObj.id = static_cast<uint16_t>(num);
399 outObj.value = std::string(vec.begin(), vec.end());
400 return napi_ok;
401 }
402
403 template <>
NapiParseObject(napi_env env,napi_value object,NapiAdvServiceData & outObj)404 napi_status NapiParseObject<NapiAdvServiceData>(napi_env env, napi_value object, NapiAdvServiceData &outObj)
405 {
406 NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "serviceValue"}));
407 std::string uuid {};
408 std::vector<uint8_t> vec {};
409 NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
410 NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", uuid));
411 NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "serviceValue", vec));
412
413 outObj.uuid = std::move(uuid);
414 outObj.value = std::move(vec);
415 return napi_ok;
416 }
417
418 template <>
NapiParseObject(napi_env env,napi_value object,NapiGattService & outObj)419 napi_status NapiParseObject<NapiGattService>(napi_env env, napi_value object, NapiGattService &outObj)
420 {
421 return NapiParseGattService(env, object, outObj);
422 }
423
424 template <>
NapiParseObject(napi_env env,napi_value object,NapiBleCharacteristic & outObj)425 napi_status NapiParseObject<NapiBleCharacteristic>(napi_env env, napi_value object, NapiBleCharacteristic &outObj)
426 {
427 return NapiParseGattCharacteristic(env, object, outObj);
428 }
429
430 template <>
NapiParseObject(napi_env env,napi_value object,NapiBleDescriptor & outObj)431 napi_status NapiParseObject<NapiBleDescriptor>(napi_env env, napi_value object, NapiBleDescriptor &outObj)
432 {
433 return NapiParseGattDescriptor(env, object, outObj);
434 }
435
436 template <typename T>
NapiParseArray(napi_env env,napi_value array,std::vector<T> & outVec)437 napi_status NapiParseArray(napi_env env, napi_value array, std::vector<T> &outVec)
438 {
439 std::vector<T> vec {};
440
441 NAPI_BT_CALL_RETURN(NapiIsArray(env, array));
442 uint32_t length = 0;
443 NAPI_BT_CALL_RETURN(napi_get_array_length(env, array, &length));
444 for (uint32_t i = 0; i < length; ++i) {
445 napi_value element;
446 NAPI_BT_CALL_RETURN(napi_get_element(env, array, i, &element));
447 T object;
448 NAPI_BT_CALL_RETURN(NapiParseObject(env, element, object));
449 vec.push_back(std::move(object));
450 }
451 outVec = std::move(vec);
452 return napi_ok;
453 }
454 // // Declaration, ohters will undefined synbol
455 template napi_status NapiParseArray<NapiBleDescriptor>(napi_env env, napi_value array,
456 std::vector<NapiBleDescriptor> &outVec);
457 template napi_status NapiParseArray<NapiBleCharacteristic>(napi_env env, napi_value array,
458 std::vector<NapiBleCharacteristic> &outVec);
459 template napi_status NapiParseArray<NapiGattService>(napi_env env, napi_value array,
460 std::vector<NapiGattService> &outVec);
461 template napi_status NapiParseArray<NapiAdvServiceData>(napi_env env, napi_value array,
462 std::vector<NapiAdvServiceData> &outVec);
463 template napi_status NapiParseArray<NapiAdvManufactureData>(napi_env env, napi_value array,
464 std::vector<NapiAdvManufactureData> &outVec);
465 template napi_status NapiParseArray<UUID>(napi_env env, napi_value array,
466 std::vector<UUID> &outVec);
467 template napi_status NapiParseArray<std::string>(napi_env env, napi_value array,
468 std::vector<std::string> &outVec);
469
470
471 template <typename T>
NapiParseObjectArray(napi_env env,napi_value object,const char * name,std::vector<T> & outVec)472 napi_status NapiParseObjectArray(napi_env env, napi_value object, const char *name, std::vector<T> &outVec)
473 {
474 napi_value property;
475 std::vector<T> vec {};
476 NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
477 NAPI_BT_CALL_RETURN(NapiParseArray(env, property, vec));
478 outVec = std::move(vec);
479 return napi_ok;
480 }
481 // Declaration, ohters will undefined synbol
482 template napi_status NapiParseObjectArray<NapiBleDescriptor>(napi_env env, napi_value object, const char *name,
483 std::vector<NapiBleDescriptor> &outVec);
484 template napi_status NapiParseObjectArray<NapiBleCharacteristic>(napi_env env, napi_value object, const char *name,
485 std::vector<NapiBleCharacteristic> &outVec);
486 template napi_status NapiParseObjectArray<NapiGattService>(napi_env env, napi_value object, const char *name,
487 std::vector<NapiGattService> &outVec);
488 template napi_status NapiParseObjectArray<NapiAdvServiceData>(napi_env env, napi_value object, const char *name,
489 std::vector<NapiAdvServiceData> &outVec);
490 template napi_status NapiParseObjectArray<NapiAdvManufactureData>(napi_env env, napi_value object, const char *name,
491 std::vector<NapiAdvManufactureData> &outVec);
492 template napi_status NapiParseObjectArray<UUID>(napi_env env, napi_value object, const char *name,
493 std::vector<UUID> &outVec);
494 template napi_status NapiParseObjectArray<std::string>(napi_env env, napi_value object, const char *name,
495 std::vector<std::string> &outVec);
496 } // namespace Bluetooth
497 } // namespace OHOS
498