1a1db01bdSopenharmony_ci/*
2a1db01bdSopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd.
3a1db01bdSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a1db01bdSopenharmony_ci * you may not use this file except in compliance with the License.
5a1db01bdSopenharmony_ci * You may obtain a copy of the License at
6a1db01bdSopenharmony_ci *
7a1db01bdSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a1db01bdSopenharmony_ci *
9a1db01bdSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a1db01bdSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a1db01bdSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a1db01bdSopenharmony_ci * See the License for the specific language governing permissions and
13a1db01bdSopenharmony_ci * limitations under the License.
14a1db01bdSopenharmony_ci */
15a1db01bdSopenharmony_ci
16a1db01bdSopenharmony_ci#include "want_utils.h"
17a1db01bdSopenharmony_ci#include "element_name_utils.h"
18a1db01bdSopenharmony_ci
19a1db01bdSopenharmony_ci#include <securec.h>
20a1db01bdSopenharmony_ci#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
21a1db01bdSopenharmony_ci#include <string>
22a1db01bdSopenharmony_ci#include "ipc_skeleton.h"
23a1db01bdSopenharmony_ci#endif
24a1db01bdSopenharmony_ci
25a1db01bdSopenharmony_ci#include "log.h"
26a1db01bdSopenharmony_ci#include "utils.h"
27a1db01bdSopenharmony_ci
28a1db01bdSopenharmony_ci#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
29a1db01bdSopenharmony_ciusing UriKeyType = enum {
30a1db01bdSopenharmony_ci    BEGIN,
31a1db01bdSopenharmony_ci    DEVICE,
32a1db01bdSopenharmony_ci    BUNDLE,
33a1db01bdSopenharmony_ci    ABILITY,
34a1db01bdSopenharmony_ci    END,
35a1db01bdSopenharmony_ci};
36a1db01bdSopenharmony_ci
37a1db01bdSopenharmony_ciusing UriProperties = struct {
38a1db01bdSopenharmony_ci    const char *key;    /* key of uri property */
39a1db01bdSopenharmony_ci    uint8_t keyLen;     /* key length of uri property */
40a1db01bdSopenharmony_ci    UriKeyType type;    /* key type of uri property */
41a1db01bdSopenharmony_ci};
42a1db01bdSopenharmony_ci
43a1db01bdSopenharmony_ciconst static UriProperties URI_PROPERTIES[] = {
44a1db01bdSopenharmony_ci    { "#Want",    5, BEGIN   },
45a1db01bdSopenharmony_ci    { "device=",  7, DEVICE  },
46a1db01bdSopenharmony_ci    { "bundle=",  7, BUNDLE  },
47a1db01bdSopenharmony_ci    { "ability=", 8, ABILITY },
48a1db01bdSopenharmony_ci    { "end",      3, END     },
49a1db01bdSopenharmony_ci};
50a1db01bdSopenharmony_ci
51a1db01bdSopenharmony_ciconstexpr static char URI_SEPARATOR = ';';
52a1db01bdSopenharmony_ciconstexpr static int VALUE_NULL = 0;
53a1db01bdSopenharmony_ciconstexpr static int VALUE_OBJECT = 1;
54a1db01bdSopenharmony_ciconstexpr static int DATA_LENGTH = 2048;
55a1db01bdSopenharmony_ci#endif
56a1db01bdSopenharmony_ci
57a1db01bdSopenharmony_ciconstexpr uint8_t INT_VALUE_TYPE = 6;
58a1db01bdSopenharmony_ciconstexpr uint8_t STRING_VALUE_TYPE = 13;
59a1db01bdSopenharmony_ciconstexpr uint8_t KEY_VALUE_PAIR_TYPE = 97;
60a1db01bdSopenharmony_ci
61a1db01bdSopenharmony_civoid ClearWant(Want *want)
62a1db01bdSopenharmony_ci{
63a1db01bdSopenharmony_ci    if (want == nullptr) {
64a1db01bdSopenharmony_ci        return;
65a1db01bdSopenharmony_ci    }
66a1db01bdSopenharmony_ci
67a1db01bdSopenharmony_ci    ClearElement(want->element);
68a1db01bdSopenharmony_ci    AdapterFree(want->element);
69a1db01bdSopenharmony_ci#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
70a1db01bdSopenharmony_ci    AdapterFree(want->sid);
71a1db01bdSopenharmony_ci#endif
72a1db01bdSopenharmony_ci    AdapterFree(want->appPath);
73a1db01bdSopenharmony_ci    AdapterFree(want->data);
74a1db01bdSopenharmony_ci#ifndef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
75a1db01bdSopenharmony_ci    AdapterFree(want->actions);
76a1db01bdSopenharmony_ci    AdapterFree(want->entities);
77a1db01bdSopenharmony_ci#endif
78a1db01bdSopenharmony_ci}
79a1db01bdSopenharmony_ci
80a1db01bdSopenharmony_cibool SetWantElement(Want *want, ElementName element)
81a1db01bdSopenharmony_ci{
82a1db01bdSopenharmony_ci    if (want == nullptr) {
83a1db01bdSopenharmony_ci        return false;
84a1db01bdSopenharmony_ci    }
85a1db01bdSopenharmony_ci
86a1db01bdSopenharmony_ci    ClearElement(want->element);
87a1db01bdSopenharmony_ci    AdapterFree(want->element);
88a1db01bdSopenharmony_ci    want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
89a1db01bdSopenharmony_ci    if (want->element == nullptr) {
90a1db01bdSopenharmony_ci        return false;
91a1db01bdSopenharmony_ci    }
92a1db01bdSopenharmony_ci    want->element->deviceId = OHOS::Utils::Strdup(element.deviceId);
93a1db01bdSopenharmony_ci    want->element->bundleName = OHOS::Utils::Strdup(element.bundleName);
94a1db01bdSopenharmony_ci    want->element->abilityName = OHOS::Utils::Strdup(element.abilityName);
95a1db01bdSopenharmony_ci    return true;
96a1db01bdSopenharmony_ci}
97a1db01bdSopenharmony_ci
98a1db01bdSopenharmony_ciTlv *EncapTlv(uint8_t type, uint8_t length, const void *value, uint8_t valueLen)
99a1db01bdSopenharmony_ci{
100a1db01bdSopenharmony_ci    void *entity = nullptr;
101a1db01bdSopenharmony_ci
102a1db01bdSopenharmony_ci    // Tlv header can only has 2 bytes.
103a1db01bdSopenharmony_ci    uint8_t totalLen = valueLen + 2;
104a1db01bdSopenharmony_ci    entity = AdapterMalloc(totalLen);
105a1db01bdSopenharmony_ci    if (entity == nullptr) {
106a1db01bdSopenharmony_ci        return nullptr;
107a1db01bdSopenharmony_ci    }
108a1db01bdSopenharmony_ci
109a1db01bdSopenharmony_ci    if (memcpy_s((unsigned char *)entity, totalLen, &type, 1) != 0 ||
110a1db01bdSopenharmony_ci        memcpy_s((unsigned char *)entity + 1, totalLen - 1, &length, 1) != 0 ||
111a1db01bdSopenharmony_ci        memcpy_s((unsigned char *)entity + 2, valueLen, value, valueLen) != 0) {
112a1db01bdSopenharmony_ci        AdapterFree(entity);
113a1db01bdSopenharmony_ci        return nullptr;
114a1db01bdSopenharmony_ci    }
115a1db01bdSopenharmony_ci
116a1db01bdSopenharmony_ci    Tlv *newTlv = reinterpret_cast<Tlv *>(AdapterMalloc(sizeof(Tlv)));
117a1db01bdSopenharmony_ci    if (newTlv == nullptr) {
118a1db01bdSopenharmony_ci        AdapterFree(entity);
119a1db01bdSopenharmony_ci        return nullptr;
120a1db01bdSopenharmony_ci    }
121a1db01bdSopenharmony_ci
122a1db01bdSopenharmony_ci    newTlv->type = type;
123a1db01bdSopenharmony_ci    newTlv->entity = entity;
124a1db01bdSopenharmony_ci    newTlv->totalLen = totalLen;
125a1db01bdSopenharmony_ci    return newTlv;
126a1db01bdSopenharmony_ci}
127a1db01bdSopenharmony_ci
128a1db01bdSopenharmony_civoid FreeTlvStruct(Tlv *tlv)
129a1db01bdSopenharmony_ci{
130a1db01bdSopenharmony_ci    AdapterFree(tlv->entity);
131a1db01bdSopenharmony_ci    AdapterFree(tlv);
132a1db01bdSopenharmony_ci}
133a1db01bdSopenharmony_ci
134a1db01bdSopenharmony_ciTlv *CombineKeyValueTlv(Tlv *keyTlv, Tlv *valueTlv)
135a1db01bdSopenharmony_ci{
136a1db01bdSopenharmony_ci    uint8_t newTlvValueLen = keyTlv->totalLen + valueTlv->totalLen;
137a1db01bdSopenharmony_ci    void *newTlvValue = AdapterMalloc(newTlvValueLen);
138a1db01bdSopenharmony_ci    if (newTlvValue == nullptr) {
139a1db01bdSopenharmony_ci        return nullptr;
140a1db01bdSopenharmony_ci    }
141a1db01bdSopenharmony_ci    if (memcpy_s((unsigned char *)newTlvValue, keyTlv->totalLen, keyTlv->entity, keyTlv->totalLen) != 0 ||
142a1db01bdSopenharmony_ci        memcpy_s((unsigned char *)newTlvValue + keyTlv->totalLen, valueTlv->totalLen,
143a1db01bdSopenharmony_ci        valueTlv->entity, valueTlv->totalLen) != 0) {
144a1db01bdSopenharmony_ci        AdapterFree(newTlvValue);
145a1db01bdSopenharmony_ci        return nullptr;
146a1db01bdSopenharmony_ci    }
147a1db01bdSopenharmony_ci
148a1db01bdSopenharmony_ci    Tlv *newTlv = EncapTlv(KEY_VALUE_PAIR_TYPE, newTlvValueLen, newTlvValue, newTlvValueLen);
149a1db01bdSopenharmony_ci    AdapterFree(newTlvValue);
150a1db01bdSopenharmony_ci    return newTlv;
151a1db01bdSopenharmony_ci}
152a1db01bdSopenharmony_ci
153a1db01bdSopenharmony_cibool UpdateWantData(Want *want, Tlv *tlv)
154a1db01bdSopenharmony_ci{
155a1db01bdSopenharmony_ci    bool result = false;
156a1db01bdSopenharmony_ci    if (want->data != nullptr) {
157a1db01bdSopenharmony_ci        void *newWantData = AdapterMalloc(tlv->totalLen + want->dataLength);
158a1db01bdSopenharmony_ci        if (newWantData == nullptr) {
159a1db01bdSopenharmony_ci            return result;
160a1db01bdSopenharmony_ci        }
161a1db01bdSopenharmony_ci        if (memcpy_s(newWantData, want->dataLength, want->data, want->dataLength) != 0 ||
162a1db01bdSopenharmony_ci            memcpy_s((unsigned char*)newWantData + want->dataLength, tlv->totalLen, tlv->entity, tlv->totalLen) != 0) {
163a1db01bdSopenharmony_ci            AdapterFree(newWantData);
164a1db01bdSopenharmony_ci            return result;
165a1db01bdSopenharmony_ci        }
166a1db01bdSopenharmony_ci        SetWantData(want, newWantData, tlv->totalLen + want->dataLength);
167a1db01bdSopenharmony_ci        AdapterFree(newWantData);
168a1db01bdSopenharmony_ci        result = true;
169a1db01bdSopenharmony_ci    } else {
170a1db01bdSopenharmony_ci        SetWantData(want, tlv->entity, tlv->totalLen);
171a1db01bdSopenharmony_ci        result = true;
172a1db01bdSopenharmony_ci    }
173a1db01bdSopenharmony_ci    return result;
174a1db01bdSopenharmony_ci}
175a1db01bdSopenharmony_ci
176a1db01bdSopenharmony_cibool SetIntParam(Want *want, const char *key, uint8_t keyLen, int32_t value)
177a1db01bdSopenharmony_ci{
178a1db01bdSopenharmony_ci    bool result = false;
179a1db01bdSopenharmony_ci    if (keyLen <= 0) {
180a1db01bdSopenharmony_ci        return result;
181a1db01bdSopenharmony_ci    }
182a1db01bdSopenharmony_ci
183a1db01bdSopenharmony_ci    Tlv *keyTlv = EncapTlv(STRING_VALUE_TYPE, keyLen, (void *)key, keyLen);
184a1db01bdSopenharmony_ci    if (keyTlv == nullptr) {
185a1db01bdSopenharmony_ci        return result;
186a1db01bdSopenharmony_ci    }
187a1db01bdSopenharmony_ci    if (value < 0) {
188a1db01bdSopenharmony_ci        HILOG_ERROR(HILOG_MODULE_APP, "SetIntParam value should be positive");
189a1db01bdSopenharmony_ci        FreeTlvStruct(keyTlv);
190a1db01bdSopenharmony_ci        return result;
191a1db01bdSopenharmony_ci    }
192a1db01bdSopenharmony_ci    int intBufferNumber = 4;
193a1db01bdSopenharmony_ci    unsigned char intBuffer[4] = {0};
194a1db01bdSopenharmony_ci    for (int i = 0; i < intBufferNumber; i++) {
195a1db01bdSopenharmony_ci        intBuffer[i] = value >> (8 * (3- i));
196a1db01bdSopenharmony_ci    }
197a1db01bdSopenharmony_ci    Tlv *valueTlv = EncapTlv(INT_VALUE_TYPE, sizeof(int), (void *)intBuffer, sizeof(int));
198a1db01bdSopenharmony_ci    if (valueTlv == nullptr) {
199a1db01bdSopenharmony_ci        FreeTlvStruct(keyTlv);
200a1db01bdSopenharmony_ci        return result;
201a1db01bdSopenharmony_ci    }
202a1db01bdSopenharmony_ci    Tlv *newTlv = CombineKeyValueTlv(keyTlv, valueTlv);
203a1db01bdSopenharmony_ci    FreeTlvStruct(keyTlv);
204a1db01bdSopenharmony_ci    FreeTlvStruct(valueTlv);
205a1db01bdSopenharmony_ci    if (newTlv == nullptr) {
206a1db01bdSopenharmony_ci        return result;
207a1db01bdSopenharmony_ci    }
208a1db01bdSopenharmony_ci    if (UpdateWantData(want, newTlv)) {
209a1db01bdSopenharmony_ci        result = true;
210a1db01bdSopenharmony_ci    }
211a1db01bdSopenharmony_ci    AdapterFree(newTlv);
212a1db01bdSopenharmony_ci    return result;
213a1db01bdSopenharmony_ci}
214a1db01bdSopenharmony_ci
215a1db01bdSopenharmony_cibool SetStrParam(Want *want, const char *key, uint8_t keyLen, const char *value, uint8_t valueLen)
216a1db01bdSopenharmony_ci{
217a1db01bdSopenharmony_ci    bool result = false;
218a1db01bdSopenharmony_ci    if (keyLen <= 0 || valueLen <= 0) {
219a1db01bdSopenharmony_ci        return result;
220a1db01bdSopenharmony_ci    }
221a1db01bdSopenharmony_ci
222a1db01bdSopenharmony_ci    Tlv *keyTlv = EncapTlv(STRING_VALUE_TYPE, keyLen, (void *)key, keyLen);
223a1db01bdSopenharmony_ci    if (keyTlv == nullptr) {
224a1db01bdSopenharmony_ci        return result;
225a1db01bdSopenharmony_ci    }
226a1db01bdSopenharmony_ci
227a1db01bdSopenharmony_ci    Tlv *valueTlv = EncapTlv(STRING_VALUE_TYPE, valueLen, (void *)value, valueLen);
228a1db01bdSopenharmony_ci    if (valueTlv == nullptr) {
229a1db01bdSopenharmony_ci        FreeTlvStruct(keyTlv);
230a1db01bdSopenharmony_ci        return result;
231a1db01bdSopenharmony_ci    }
232a1db01bdSopenharmony_ci    Tlv *newTlv = CombineKeyValueTlv(keyTlv, valueTlv);
233a1db01bdSopenharmony_ci    FreeTlvStruct(keyTlv);
234a1db01bdSopenharmony_ci    FreeTlvStruct(valueTlv);
235a1db01bdSopenharmony_ci    if (newTlv == nullptr) {
236a1db01bdSopenharmony_ci        return result;
237a1db01bdSopenharmony_ci    }
238a1db01bdSopenharmony_ci    if (UpdateWantData(want, newTlv)) {
239a1db01bdSopenharmony_ci        result = true;
240a1db01bdSopenharmony_ci    }
241a1db01bdSopenharmony_ci    AdapterFree(newTlv);
242a1db01bdSopenharmony_ci    return result;
243a1db01bdSopenharmony_ci}
244a1db01bdSopenharmony_ci
245a1db01bdSopenharmony_ci#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
246a1db01bdSopenharmony_cibool SetWantSvcIdentity(Want *want, SvcIdentity sid)
247a1db01bdSopenharmony_ci{
248a1db01bdSopenharmony_ci    if (want == nullptr) {
249a1db01bdSopenharmony_ci        return false;
250a1db01bdSopenharmony_ci    }
251a1db01bdSopenharmony_ci
252a1db01bdSopenharmony_ci    AdapterFree(want->sid);
253a1db01bdSopenharmony_ci    want->sid = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
254a1db01bdSopenharmony_ci    if (want->sid == nullptr) {
255a1db01bdSopenharmony_ci        return false;
256a1db01bdSopenharmony_ci    }
257a1db01bdSopenharmony_ci    if (memcpy_s(want->sid, sizeof(SvcIdentity), &sid, sizeof(SvcIdentity)) != EOK) {
258a1db01bdSopenharmony_ci        AdapterFree(want->sid);
259a1db01bdSopenharmony_ci        return false;
260a1db01bdSopenharmony_ci    }
261a1db01bdSopenharmony_ci
262a1db01bdSopenharmony_ci    return true;
263a1db01bdSopenharmony_ci}
264a1db01bdSopenharmony_ci#endif
265a1db01bdSopenharmony_ci
266a1db01bdSopenharmony_cibool SetWantData(Want *want, const void *data, uint16_t dataLength)
267a1db01bdSopenharmony_ci{
268a1db01bdSopenharmony_ci    if (want == nullptr) {
269a1db01bdSopenharmony_ci        return false;
270a1db01bdSopenharmony_ci    }
271a1db01bdSopenharmony_ci
272a1db01bdSopenharmony_ci    AdapterFree(want->data);
273a1db01bdSopenharmony_ci    want->data = OHOS::Utils::Memdup(data, dataLength);
274a1db01bdSopenharmony_ci    if (want->data == nullptr) {
275a1db01bdSopenharmony_ci        want->dataLength = 0;
276a1db01bdSopenharmony_ci        return false;
277a1db01bdSopenharmony_ci    }
278a1db01bdSopenharmony_ci
279a1db01bdSopenharmony_ci    want->dataLength = dataLength;
280a1db01bdSopenharmony_ci    return true;
281a1db01bdSopenharmony_ci}
282a1db01bdSopenharmony_ci
283a1db01bdSopenharmony_ci#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
284a1db01bdSopenharmony_cibool SerializeWant(IpcIo *io, const Want *want)
285a1db01bdSopenharmony_ci{
286a1db01bdSopenharmony_ci    if ((io == nullptr) || (want == nullptr) || (want->dataLength > DATA_LENGTH)) {
287a1db01bdSopenharmony_ci        return false;
288a1db01bdSopenharmony_ci    }
289a1db01bdSopenharmony_ci
290a1db01bdSopenharmony_ci    if (want->element == nullptr) {
291a1db01bdSopenharmony_ci        WriteInt32(io, VALUE_NULL);
292a1db01bdSopenharmony_ci    } else {
293a1db01bdSopenharmony_ci        WriteInt32(io, VALUE_OBJECT);
294a1db01bdSopenharmony_ci        if (!SerializeElement(io, want->element)) {
295a1db01bdSopenharmony_ci            return false;
296a1db01bdSopenharmony_ci        }
297a1db01bdSopenharmony_ci    }
298a1db01bdSopenharmony_ci    WriteInt32(io, want->dataLength);
299a1db01bdSopenharmony_ci    if (want->dataLength > 0) {
300a1db01bdSopenharmony_ci        WriteBuffer(io, want->data, want->dataLength);
301a1db01bdSopenharmony_ci    }
302a1db01bdSopenharmony_ci    if (want->sid == nullptr) {
303a1db01bdSopenharmony_ci        WriteInt32(io, VALUE_NULL);
304a1db01bdSopenharmony_ci    } else {
305a1db01bdSopenharmony_ci        WriteInt32(io, VALUE_OBJECT);
306a1db01bdSopenharmony_ci        bool ret = WriteRemoteObject(io, want->sid);
307a1db01bdSopenharmony_ci        if (!ret) {
308a1db01bdSopenharmony_ci            return false;
309a1db01bdSopenharmony_ci        }
310a1db01bdSopenharmony_ci    }
311a1db01bdSopenharmony_ci
312a1db01bdSopenharmony_ci    return true;
313a1db01bdSopenharmony_ci}
314a1db01bdSopenharmony_ci
315a1db01bdSopenharmony_cibool DeserializeWant(Want *want, IpcIo *io)
316a1db01bdSopenharmony_ci{
317a1db01bdSopenharmony_ci    if ((want == nullptr) || (io == nullptr)) {
318a1db01bdSopenharmony_ci        return false;
319a1db01bdSopenharmony_ci    }
320a1db01bdSopenharmony_ci
321a1db01bdSopenharmony_ci    int ret = 0;
322a1db01bdSopenharmony_ci    ReadInt32(io, &ret);
323a1db01bdSopenharmony_ci    if (ret == VALUE_OBJECT) {
324a1db01bdSopenharmony_ci        want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
325a1db01bdSopenharmony_ci        if (want->element == nullptr ||
326a1db01bdSopenharmony_ci            memset_s(want->element, sizeof(ElementName), 0, sizeof(ElementName)) != EOK ||
327a1db01bdSopenharmony_ci            !DeserializeElement(want->element, io)) {
328a1db01bdSopenharmony_ci            AdapterFree(want->element);
329a1db01bdSopenharmony_ci            return false;
330a1db01bdSopenharmony_ci        }
331a1db01bdSopenharmony_ci    }
332a1db01bdSopenharmony_ci    uint32_t size = 0;
333a1db01bdSopenharmony_ci    ReadUint32(io, &size);
334a1db01bdSopenharmony_ci    if (size > 0) {
335a1db01bdSopenharmony_ci        void *data = (void*)ReadBuffer(io, (size_t)size);
336a1db01bdSopenharmony_ci        if (!SetWantData(want, data, size)) {
337a1db01bdSopenharmony_ci            ClearWant(want);
338a1db01bdSopenharmony_ci            return false;
339a1db01bdSopenharmony_ci        }
340a1db01bdSopenharmony_ci    }
341a1db01bdSopenharmony_ci    ReadInt32(io, &ret);
342a1db01bdSopenharmony_ci    if (ret == VALUE_OBJECT) {
343a1db01bdSopenharmony_ci        SvcIdentity svc;
344a1db01bdSopenharmony_ci        bool ret = ReadRemoteObject(io, &svc);
345a1db01bdSopenharmony_ci        if (!ret || !SetWantSvcIdentity(want, svc)) {
346a1db01bdSopenharmony_ci            ClearWant(want);
347a1db01bdSopenharmony_ci            return false;
348a1db01bdSopenharmony_ci        }
349a1db01bdSopenharmony_ci    }
350a1db01bdSopenharmony_ci
351a1db01bdSopenharmony_ci    return true;
352a1db01bdSopenharmony_ci}
353a1db01bdSopenharmony_ci
354a1db01bdSopenharmony_ciWant *WantParseUri(const char *uri)
355a1db01bdSopenharmony_ci{
356a1db01bdSopenharmony_ci    if (uri == nullptr) {
357a1db01bdSopenharmony_ci        return nullptr;
358a1db01bdSopenharmony_ci    }
359a1db01bdSopenharmony_ci    char *parseUri = OHOS::Utils::Strdup(uri);
360a1db01bdSopenharmony_ci    if (parseUri == nullptr) {
361a1db01bdSopenharmony_ci        return nullptr;
362a1db01bdSopenharmony_ci    }
363a1db01bdSopenharmony_ci    ElementName element = { nullptr, nullptr, nullptr };
364a1db01bdSopenharmony_ci    char *beginIndex = parseUri;
365a1db01bdSopenharmony_ci    for (auto property : URI_PROPERTIES) {
366a1db01bdSopenharmony_ci        if (strstr(beginIndex, property.key) != beginIndex) {
367a1db01bdSopenharmony_ci            AdapterFree(parseUri);
368a1db01bdSopenharmony_ci            return nullptr;
369a1db01bdSopenharmony_ci        }
370a1db01bdSopenharmony_ci        if (property.type == END) {
371a1db01bdSopenharmony_ci            break;
372a1db01bdSopenharmony_ci        }
373a1db01bdSopenharmony_ci        char *endIndex = strchr(beginIndex, URI_SEPARATOR);
374a1db01bdSopenharmony_ci        if ((endIndex == nullptr) || (endIndex <= beginIndex)) {
375a1db01bdSopenharmony_ci            AdapterFree(parseUri);
376a1db01bdSopenharmony_ci            return nullptr;
377a1db01bdSopenharmony_ci        }
378a1db01bdSopenharmony_ci        *endIndex = '\0';
379a1db01bdSopenharmony_ci        beginIndex += property.keyLen;
380a1db01bdSopenharmony_ci        switch (property.type) {
381a1db01bdSopenharmony_ci            case DEVICE: {
382a1db01bdSopenharmony_ci                SetElementDeviceID(&element, beginIndex);
383a1db01bdSopenharmony_ci                break;
384a1db01bdSopenharmony_ci            }
385a1db01bdSopenharmony_ci            case BUNDLE: {
386a1db01bdSopenharmony_ci                SetElementBundleName(&element, beginIndex);
387a1db01bdSopenharmony_ci                break;
388a1db01bdSopenharmony_ci            }
389a1db01bdSopenharmony_ci            case ABILITY: {
390a1db01bdSopenharmony_ci                SetElementAbilityName(&element, beginIndex);
391a1db01bdSopenharmony_ci                break;
392a1db01bdSopenharmony_ci            }
393a1db01bdSopenharmony_ci            default: {
394a1db01bdSopenharmony_ci                break;
395a1db01bdSopenharmony_ci            }
396a1db01bdSopenharmony_ci        }
397a1db01bdSopenharmony_ci        beginIndex = endIndex + 1;
398a1db01bdSopenharmony_ci    }
399a1db01bdSopenharmony_ci    AdapterFree(parseUri);
400a1db01bdSopenharmony_ci    Want *want = new Want();
401a1db01bdSopenharmony_ci    if ((memset_s(want, sizeof(Want), 0, sizeof(Want)) != EOK) || !SetWantElement(want, element)) {
402a1db01bdSopenharmony_ci        ClearElement(&element);
403a1db01bdSopenharmony_ci        delete want;
404a1db01bdSopenharmony_ci        return nullptr;
405a1db01bdSopenharmony_ci    }
406a1db01bdSopenharmony_ci    ClearElement(&element);
407a1db01bdSopenharmony_ci    return want;
408a1db01bdSopenharmony_ci}
409a1db01bdSopenharmony_ci
410a1db01bdSopenharmony_ciconst char *WantToUri(Want want)
411a1db01bdSopenharmony_ci{
412a1db01bdSopenharmony_ci    std::string uriString;
413a1db01bdSopenharmony_ci
414a1db01bdSopenharmony_ci    for (auto property : URI_PROPERTIES) {
415a1db01bdSopenharmony_ci        uriString += property.key;
416a1db01bdSopenharmony_ci        switch (property.type) {
417a1db01bdSopenharmony_ci            case BEGIN: {
418a1db01bdSopenharmony_ci                uriString += URI_SEPARATOR;
419a1db01bdSopenharmony_ci                break;
420a1db01bdSopenharmony_ci            }
421a1db01bdSopenharmony_ci            case DEVICE: {
422a1db01bdSopenharmony_ci                if ((want.element != nullptr) && (want.element->deviceId != nullptr)) {
423a1db01bdSopenharmony_ci                    uriString += want.element->deviceId;
424a1db01bdSopenharmony_ci                }
425a1db01bdSopenharmony_ci                uriString += URI_SEPARATOR;
426a1db01bdSopenharmony_ci                break;
427a1db01bdSopenharmony_ci            }
428a1db01bdSopenharmony_ci            case BUNDLE: {
429a1db01bdSopenharmony_ci                if ((want.element != nullptr) && (want.element->bundleName != nullptr)) {
430a1db01bdSopenharmony_ci                    uriString += want.element->bundleName;
431a1db01bdSopenharmony_ci                }
432a1db01bdSopenharmony_ci                uriString += URI_SEPARATOR;
433a1db01bdSopenharmony_ci                break;
434a1db01bdSopenharmony_ci            }
435a1db01bdSopenharmony_ci            case ABILITY: {
436a1db01bdSopenharmony_ci                if ((want.element != nullptr) && (want.element->abilityName != nullptr)) {
437a1db01bdSopenharmony_ci                    uriString += want.element->abilityName;
438a1db01bdSopenharmony_ci                }
439a1db01bdSopenharmony_ci                uriString += URI_SEPARATOR;
440a1db01bdSopenharmony_ci                break;
441a1db01bdSopenharmony_ci            }
442a1db01bdSopenharmony_ci            default: {
443a1db01bdSopenharmony_ci                break;
444a1db01bdSopenharmony_ci            }
445a1db01bdSopenharmony_ci        }
446a1db01bdSopenharmony_ci    }
447a1db01bdSopenharmony_ci
448a1db01bdSopenharmony_ci    uint16_t len = uriString.size();
449a1db01bdSopenharmony_ci    char *uri = reinterpret_cast<char *>(AdapterMalloc(len + 1));
450a1db01bdSopenharmony_ci    if (uri == nullptr) {
451a1db01bdSopenharmony_ci        return nullptr;
452a1db01bdSopenharmony_ci    }
453a1db01bdSopenharmony_ci    if (strncpy_s(uri, len + 1, uriString.c_str(), len) < 0) {
454a1db01bdSopenharmony_ci        AdapterFree(uri);
455a1db01bdSopenharmony_ci        return nullptr;
456a1db01bdSopenharmony_ci    }
457a1db01bdSopenharmony_ci
458a1db01bdSopenharmony_ci    return uri;
459a1db01bdSopenharmony_ci}
460a1db01bdSopenharmony_ci#endif
461