1/*
2 * Copyright (c) 2023-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 "ipc_utils.h"
17#include "dp_subscribe_info.h"
18#include "macro_utils.h"
19
20namespace OHOS {
21namespace DistributedDeviceProfile {
22namespace {
23    const std::string TAG = "IpcUtils";
24}
25bool IpcUtils::Marshalling(MessageParcel& parcel, const std::vector<TrustDeviceProfile>& trustDeviceProfiles)
26{
27    if (trustDeviceProfiles.empty() || trustDeviceProfiles.size() > MAX_PROFILE_SIZE) {
28        HILOGE("profile size is invalid!size : %{public}zu", trustDeviceProfiles.size());
29        return false;
30    }
31    uint32_t size = trustDeviceProfiles.size();
32    WRITE_HELPER_RET(parcel, Uint32, size, false);
33    for (const auto& profile : trustDeviceProfiles) {
34        if (!profile.Marshalling(parcel)) {
35            HILOGE("profile Marshalling fail!");
36            return false;
37        }
38    }
39    return true;
40}
41
42bool IpcUtils::Marshalling(MessageParcel& parcel, const std::vector<AccessControlProfile>& aclProfiles)
43{
44    if (aclProfiles.empty() || aclProfiles.size() > MAX_PROFILE_SIZE) {
45        HILOGE("profile size is invalid!size : %{public}zu", aclProfiles.size());
46        return false;
47    }
48    uint32_t size = aclProfiles.size();
49    WRITE_HELPER_RET(parcel, Uint32, size, false);
50    for (const auto& profile : aclProfiles) {
51        if (!profile.Marshalling(parcel)) {
52            HILOGE("profile Marshalling fail!");
53            return false;
54        }
55    }
56    return true;
57}
58
59bool IpcUtils::Marshalling(MessageParcel& parcel, const std::vector<ServiceProfile>& serviceProfiles)
60{
61    if (serviceProfiles.empty() || serviceProfiles.size() > MAX_PROFILE_SIZE) {
62        HILOGE("profile size is invalid!size : %{public}zu", serviceProfiles.size());
63        return false;
64    }
65    uint32_t size = serviceProfiles.size();
66    WRITE_HELPER_RET(parcel, Uint32, size, false);
67    for (const auto& profile : serviceProfiles) {
68        if (!profile.Marshalling(parcel)) {
69            HILOGE("profile Marshalling fail!");
70            return false;
71        }
72    }
73    return true;
74}
75
76bool IpcUtils::Marshalling(MessageParcel& parcel, const std::vector<CharacteristicProfile>& charProfiles)
77{
78    if (charProfiles.empty() || charProfiles.size() > MAX_PROFILE_SIZE) {
79        HILOGE("profile size is invalid!size : %{public}zu", charProfiles.size());
80        return false;
81    }
82    uint32_t size = charProfiles.size();
83    WRITE_HELPER_RET(parcel, Uint32, size, false);
84    for (const auto& profile : charProfiles) {
85        profile.Marshalling(parcel);
86    }
87    return true;
88}
89
90bool IpcUtils::Marshalling(MessageParcel& parcel, const std::map<std::string, std::string>& params)
91{
92    if (params.size() == 0 || params.size() > MAX_PARAM_SIZE) {
93        HILOGE("Params size is invalid!size : %{public}zu", params.size());
94        return false;
95    }
96    uint32_t size = params.size();
97    WRITE_HELPER_RET(parcel, Uint32, size, false);
98    for (const auto& item : params) {
99        WRITE_HELPER_RET(parcel, String, item.first + SEPARATOR + item.second, false);
100    }
101    return true;
102}
103
104bool IpcUtils::Marshalling(MessageParcel& parcel, const std::map<std::string,
105    OHOS::DistributedDeviceProfile::SubscribeInfo>& listenerMap)
106{
107    if (listenerMap.size() == 0 || listenerMap.size() > MAX_LISTENER_SIZE) {
108        HILOGE("listenerMap size is invalid!size : %{public}zu", listenerMap.size());
109        return false;
110    }
111    uint32_t size = listenerMap.size();
112    WRITE_HELPER_RET(parcel, Uint32, size, false);
113    for (const auto& item : listenerMap) {
114        OHOS::DistributedDeviceProfile::SubscribeInfo subscribeInfo = item.second;
115        if (!subscribeInfo.Marshalling(parcel)) {
116            HILOGE("subscribeInfo Marshalling fail!");
117            return false;
118        }
119    }
120    return true;
121}
122
123bool IpcUtils::Marshalling(MessageParcel& parcel, const std::unordered_set<ProfileChangeType>& changeTypes)
124{
125    if (changeTypes.size() == 0 || changeTypes.size() > MAX_SUBSCRIBE_CHANGE_SIZE) {
126        HILOGE("listenerMap size is invalid!size : %{public}zu", changeTypes.size());
127        return false;
128    }
129    uint32_t size = changeTypes.size();
130    WRITE_HELPER_RET(parcel, Uint32, size, false);
131    for (ProfileChangeType item : changeTypes) {
132        WRITE_HELPER_RET(parcel, Int32, static_cast<int32_t>(item), false);
133    }
134    return true;
135}
136
137bool IpcUtils::UnMarshalling(MessageParcel& parcel, std::vector<TrustDeviceProfile>& trustDeviceProfiles)
138{
139    uint32_t size = parcel.ReadUint32();
140    if (size == 0 || size > MAX_PROFILE_SIZE) {
141        HILOGE("Profile size is invalid!size : %{public}u", size);
142        return false;
143    }
144    for (uint32_t i = 0; i < size; i++) {
145        TrustDeviceProfile trustDeviceProfile;
146        if (!trustDeviceProfile.UnMarshalling(parcel)) {
147            HILOGE("Profile UnMarshalling fail!");
148            return false;
149        }
150        trustDeviceProfiles.emplace_back(trustDeviceProfile);
151    }
152    return true;
153}
154
155bool IpcUtils::UnMarshalling(MessageParcel& parcel, std::vector<AccessControlProfile>& aclProfiles)
156{
157    uint32_t size = parcel.ReadUint32();
158    if (size == 0 || size > MAX_PROFILE_SIZE) {
159        HILOGE("Profile size is invalid!size : %{public}u", size);
160        return false;
161    }
162    for (uint32_t i = 0; i < size; i++) {
163        AccessControlProfile aclProfile;
164        if (!aclProfile.UnMarshalling(parcel)) {
165            HILOGE("Profile UnMarshalling fail!");
166            return false;
167        }
168        aclProfiles.emplace_back(aclProfile);
169    }
170    return true;
171}
172
173bool IpcUtils::UnMarshalling(MessageParcel& parcel, std::vector<ServiceProfile>& serviceProfiles)
174{
175    uint32_t size = parcel.ReadUint32();
176    if (size == 0 || size > MAX_PROFILE_SIZE) {
177        HILOGE("Profile size is invalid!size : %{public}u", size);
178        return false;
179    }
180    for (uint32_t i = 0; i < size; i++) {
181        ServiceProfile serviceProfile;
182        if (!serviceProfile.UnMarshalling(parcel)) {
183            HILOGE("Profile UnMarshalling fail!");
184            return false;
185        }
186        serviceProfiles.emplace_back(serviceProfile);
187    }
188    return true;
189}
190
191bool IpcUtils::UnMarshalling(MessageParcel& parcel, std::vector<CharacteristicProfile>& charProfiles)
192{
193    uint32_t size = parcel.ReadUint32();
194    if (size == 0 || size > MAX_PROFILE_SIZE) {
195        HILOGE("Profile size is invalid!size : %{public}u", size);
196        return false;
197    }
198    for (uint32_t i = 0; i < size; i++) {
199        CharacteristicProfile charProfile;
200        if (!charProfile.UnMarshalling(parcel)) {
201            HILOGE("Profile UnMarshalling fail!");
202            return false;
203        }
204        charProfiles.emplace_back(charProfile);
205    }
206    return true;
207}
208
209bool IpcUtils::UnMarshalling(MessageParcel& parcel, std::map<std::string, std::string>& params)
210{
211    uint32_t size = parcel.ReadUint32();
212    if (size == 0 || size > MAX_PARAM_SIZE) {
213        HILOGE("Params size is invalid!size : %{public}u", size);
214        return false;
215    }
216    for (uint32_t i = 0; i < size; i++) {
217        std::string item = "";
218        READ_HELPER_RET(parcel, String, item, false);
219        std::string::size_type position = item.find(SEPARATOR);
220        if (position == item.npos) {
221            HILOGE("Not found the separator!");
222            continue;
223        }
224        std::string key = item.substr(0, position);
225        std::string value = item.substr(position + 1);
226        params[key] = value;
227    }
228    return true;
229}
230
231bool IpcUtils::UnMarshalling(MessageParcel& parcel, std::map<std::string,
232    OHOS::DistributedDeviceProfile::SubscribeInfo>& listenerMap)
233{
234    uint32_t size = parcel.ReadUint32();
235    if (size == 0 || size > MAX_LISTENER_SIZE) {
236        HILOGE("Params size is invalid!size : %{public}u", size);
237        return false;
238    }
239    for (uint32_t i = 0; i < size; i++) {
240        OHOS::DistributedDeviceProfile::SubscribeInfo subscribeInfo;
241        if (!subscribeInfo.UnMarshalling(parcel)) {
242            HILOGE("subscribeInfo UnMarshalling fail!");
243            return false;
244        }
245        listenerMap[subscribeInfo.GetSubscribeKey() + SEPARATOR + std::to_string(subscribeInfo.GetSaId())] =
246            subscribeInfo;
247    }
248    return true;
249}
250
251bool IpcUtils::UnMarshalling(MessageParcel& parcel, std::unordered_set<ProfileChangeType>& changeTypes)
252{
253    uint32_t size = parcel.ReadUint32();
254    if (size == 0 || size > MAX_SUBSCRIBE_CHANGE_SIZE) {
255        HILOGE("Params size is invalid!size : %{public}u", size);
256        return false;
257    }
258    for (uint32_t i = 0; i < size; i++) {
259        uint32_t num = parcel.ReadUint32();
260        if (num <= ProfileChangeType::PROFILE_CHANGE_TYPE_MIN || num >= ProfileChangeType::PROFILE_CHANGE_TYPE_MAX) {
261            HILOGE("The value is invalid!");
262            return false;
263        }
264        changeTypes.emplace(static_cast<ProfileChangeType>(num));
265    }
266    return true;
267}
268} // namespace DistributedDeviceProfile
269} // namespace OHOS
270