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 "array_usb_device_id_serializer.h"
17 #include "edm_constants.h"
18 #include "json/json.h"
19 #include "usb_device_id.h"
20 
21 namespace OHOS {
22 namespace EDM {
23 constexpr int32_t ESCAPED_STRING_SUFFIX_LENGTH = 4;
24 
SetUnionPolicyData(std::vector<UsbDeviceId> & data,std::vector<UsbDeviceId> & currentData)25 std::vector<UsbDeviceId> ArrayUsbDeviceIdSerializer::SetUnionPolicyData(std::vector<UsbDeviceId> &data,
26     std::vector<UsbDeviceId> &currentData)
27 {
28     std::vector<UsbDeviceId> mergeData;
29     std::sort(data.begin(), data.end(), Comp());
30     std::sort(currentData.begin(), currentData.end(), Comp());
31     std::set_union(data.begin(), data.end(), currentData.begin(), currentData.end(), back_inserter(mergeData), Comp());
32     return mergeData;
33 }
34 
SetDifferencePolicyData(std::vector<UsbDeviceId> & data,std::vector<UsbDeviceId> & currentData)35 std::vector<UsbDeviceId> ArrayUsbDeviceIdSerializer::SetDifferencePolicyData(std::vector<UsbDeviceId> &data,
36     std::vector<UsbDeviceId> &currentData)
37 {
38     std::vector<UsbDeviceId> mergeData;
39     std::sort(data.begin(), data.end(), Comp());
40     std::sort(currentData.begin(), currentData.end(), Comp());
41     std::set_difference(currentData.begin(), currentData.end(), data.begin(), data.end(), back_inserter(mergeData),
42         Comp());
43     return mergeData;
44 }
45 
Deserialize(const std::string & jsonString,std::vector<UsbDeviceId> & dataObj)46 bool ArrayUsbDeviceIdSerializer::Deserialize(const std::string &jsonString, std::vector<UsbDeviceId> &dataObj)
47 {
48     if (jsonString.empty()) {
49         return true;
50     }
51     Json::Value root;
52     Json::String err;
53     Json::CharReaderBuilder builder;
54     const std::unique_ptr<Json::CharReader> charReader(builder.newCharReader());
55     if (!charReader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &root, &err)) {
56         return false;
57     }
58     if (!root.isArray()) {
59         EDMLOGE("ArrayUsbDeviceIdSerializer Deserialize root is not array");
60         return false;
61     }
62     dataObj = std::vector<UsbDeviceId>(root.size());
63     for (std::uint32_t i = 0; i < root.size(); ++i) {
64         Json::StreamWriterBuilder writerBuilder;
65         std::string valueJsonString = Json::writeString(writerBuilder, root[i]);
66         std::string::size_type pos = 0;
67         while ((pos = valueJsonString.find("\\\"")) != std::string::npos) {
68             valueJsonString.replace(pos, 1, "");
69         }
70         valueJsonString = valueJsonString.substr(1, valueJsonString.length() - ESCAPED_STRING_SUFFIX_LENGTH);
71         UsbDeviceId value;
72         Json::Value item;
73         Json::Reader reader;
74         if (!reader.parse(valueJsonString.data(), valueJsonString.data() + valueJsonString.length(), item)) {
75             EDMLOGE("ArrayUsbDeviceIdSerializer Deserialize reader can not parse, i = %{public}u", i);
76             return false;
77         }
78         if (!item["vendorId"].isConvertibleTo(Json::intValue) || !item["productId"].isConvertibleTo(Json::intValue)) {
79             EDMLOGE("ArrayUsbDeviceIdSerializer Deserialize vendorId or productId can not parse.");
80             return false;
81         }
82         value.SetVendorId(item["vendorId"].asInt());
83         value.SetProductId(item["productId"].asInt());
84         dataObj.at(i) = value;
85     }
86     return true;
87 }
88 
Serialize(const std::vector<UsbDeviceId> & dataObj,std::string & jsonString)89 bool ArrayUsbDeviceIdSerializer::Serialize(const std::vector<UsbDeviceId> &dataObj, std::string &jsonString)
90 {
91     if (dataObj.empty()) {
92         jsonString = "";
93         return true;
94     }
95     Json::Value arrayData(Json::arrayValue);
96     for (std::uint32_t i = 0; i < dataObj.size(); ++i) {
97         std::string itemJson;
98         UsbDeviceId item = dataObj.at(i);
99         Json::Value root;
100         root["vendorId"] = item.GetVendorId();
101         root["productId"] = item.GetProductId();
102         Json::FastWriter writer;
103         itemJson = writer.write(root);
104         arrayData[i] = itemJson;
105     }
106     Json::StreamWriterBuilder builder;
107     builder["indentation"] = "    ";
108     jsonString = Json::writeString(builder, arrayData);
109     return true;
110 }
111 
GetPolicy(MessageParcel & data,std::vector<UsbDeviceId> & result)112 bool ArrayUsbDeviceIdSerializer::GetPolicy(MessageParcel &data, std::vector<UsbDeviceId> &result)
113 {
114     uint32_t size = data.ReadUint32();
115     if (size > EdmConstants::ALLOWED_USB_DEVICES_MAX_SIZE) {
116         EDMLOGE("ArrayUsbDeviceIdSerializer:GetPolicy size=[%{public}u] is too large", size);
117         return false;
118     }
119     for (uint32_t i = 0; i < size; i++) {
120         UsbDeviceId usbDeviceId;
121         if (!UsbDeviceId::Unmarshalling(data, usbDeviceId)) {
122             EDMLOGE("ArrayUsbDeviceIdSerializer::GetPolicy read parcel fail");
123             return false;
124         }
125         result.emplace_back(usbDeviceId);
126     }
127     return true;
128 }
129 
WritePolicy(MessageParcel & reply,std::vector<UsbDeviceId> & result)130 bool ArrayUsbDeviceIdSerializer::WritePolicy(MessageParcel &reply, std::vector<UsbDeviceId> &result)
131 {
132     std::for_each(result.begin(), result.end(), [&](const auto usbDeviceId) {
133         usbDeviceId.Marshalling(reply);
134     });
135     return true;
136 }
137 
MergePolicy(std::vector<std::vector<UsbDeviceId>> & data,std::vector<UsbDeviceId> & result)138 bool ArrayUsbDeviceIdSerializer::MergePolicy(std::vector<std::vector<UsbDeviceId>> &data,
139     std::vector<UsbDeviceId> &result)
140 {
141     std::set<UsbDeviceId> stData;
142     for (const auto &dataItem : data) {
143         for (const auto &item : dataItem) {
144             stData.insert(item);
145         }
146     }
147     result.assign(stData.begin(), stData.end());
148     return true;
149 }
150 } // namespace EDM
151 } // namespace OHOS