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 #define LOG_TAG "ITypesUtil"
17
18 #include "itypes_util.h"
19 #include <climits>
20 #include "autils/constant.h"
21 #include "log_print.h"
22
23 namespace OHOS::DistributedKv {
Marshalling(const Blob & blob,MessageParcel & data)24 bool ITypesUtil::Marshalling(const Blob &blob, MessageParcel &data)
25 {
26 return data.WriteUInt8Vector(blob.Data());
27 }
28
Unmarshalling(MessageParcel & data,Blob & output)29 bool ITypesUtil::Unmarshalling(MessageParcel &data, Blob &output)
30 {
31 std::vector<uint8_t> blob;
32 bool result = data.ReadUInt8Vector(&blob);
33 output = blob;
34 return result;
35 }
36
Marshalling(const std::vector<Blob> & blobs,MessageParcel & data)37 bool ITypesUtil::Marshalling(const std::vector<Blob> &blobs, MessageParcel &data)
38 {
39 return WriteVector(data, blobs, ITypesUtil::GetParcelWriter<Blob>());
40 }
41
Unmarshalling(MessageParcel & data,std::vector<Blob> & output)42 bool ITypesUtil::Unmarshalling(MessageParcel &data, std::vector<Blob> &output)
43 {
44 return ReadVector(data, output, ITypesUtil::GetParcelReader<Blob>());
45 }
46
Marshalling(const std::vector<Entry> & entry,MessageParcel & data)47 bool ITypesUtil::Marshalling(const std::vector<Entry> &entry, MessageParcel &data)
48 {
49 return WriteVector(data, entry, ITypesUtil::GetParcelWriter<Entry>());
50 }
51
Unmarshalling(MessageParcel & data,std::vector<Entry> & output)52 bool ITypesUtil::Unmarshalling(MessageParcel &data, std::vector<Entry> &output)
53 {
54 return ReadVector(data, output, ITypesUtil::GetParcelReader<Entry>());
55 }
56
Marshalling(const Entry & entry,MessageParcel & data)57 bool ITypesUtil::Marshalling(const Entry &entry, MessageParcel &data)
58 {
59 if (!Marshalling(entry.key, data)) {
60 return false;
61 }
62 return Marshalling(entry.value, data);
63 }
64
Unmarshalling(MessageParcel & data,Entry & output)65 bool ITypesUtil::Unmarshalling(MessageParcel &data, Entry &output)
66 {
67 if (!Unmarshalling(data, output.key)) {
68 return false;
69 }
70 return Unmarshalling(data, output.value);
71 }
72
Marshalling(const DeviceInfo & entry,MessageParcel & data)73 bool ITypesUtil::Marshalling(const DeviceInfo &entry, MessageParcel &data)
74 {
75 if (!data.WriteString(entry.deviceId)) {
76 return false;
77 }
78 if (!data.WriteString(entry.deviceName)) {
79 return false;
80 }
81 return data.WriteString(entry.deviceType);
82 }
83
Unmarshalling(MessageParcel & data,DeviceInfo & output)84 bool ITypesUtil::Unmarshalling(MessageParcel &data, DeviceInfo &output)
85 {
86 if (!data.ReadString(output.deviceId)) {
87 return false;
88 }
89 if (!data.ReadString(output.deviceName)) {
90 return false;
91 }
92 return data.ReadString(output.deviceType);
93 }
Marshalling(const std::vector<DeviceInfo> & input,MessageParcel & data)94 bool ITypesUtil::Marshalling(const std::vector<DeviceInfo> &input, MessageParcel &data)
95 {
96 return WriteVector(data, input, ITypesUtil::GetParcelWriter<DeviceInfo>());
97 }
98
Unmarshalling(MessageParcel & data,std::vector<DeviceInfo> & output)99 bool ITypesUtil::Unmarshalling(MessageParcel &data, std::vector<DeviceInfo> &output)
100 {
101 return ReadVector(data, output, ITypesUtil::GetParcelReader<DeviceInfo>());
102 }
103
Marshalling(const ChangeNotification & notification,MessageParcel & parcel)104 bool ITypesUtil::Marshalling(const ChangeNotification ¬ification, MessageParcel &parcel)
105 {
106 if (!Marshalling(notification.GetInsertEntries(), parcel)) {
107 return false;
108 }
109
110 if (!Marshalling(notification.GetUpdateEntries(), parcel)) {
111 return false;
112 }
113
114 if (!Marshalling(notification.GetDeleteEntries(), parcel)) {
115 return false;
116 }
117 if (!parcel.WriteString(notification.GetDeviceId())) {
118 ZLOGE("WriteString deviceId_ failed.");
119 return false;
120 }
121
122 return parcel.WriteBool(notification.IsClear());
123 }
124
Unmarshalling(MessageParcel & parcel,ChangeNotification & output)125 bool ITypesUtil::Unmarshalling(MessageParcel &parcel, ChangeNotification &output)
126 {
127 std::vector<Entry> insertEntries;
128 if (!Unmarshalling(parcel, insertEntries)) {
129 return false;
130 }
131 std::vector<Entry> updateEntries;
132 if (!Unmarshalling(parcel, updateEntries)) {
133 return false;
134 }
135 std::vector<Entry> deleteEntries;
136 if (!Unmarshalling(parcel, deleteEntries)) {
137 return false;
138 }
139 std::string deviceId;
140 if (!parcel.ReadString(deviceId)) {
141 ZLOGE("WriteString deviceId_ failed.");
142 return false;
143 }
144 bool isClear;
145 if (!parcel.ReadBool(isClear)) {
146 ZLOGE("WriteString deviceId_ failed.");
147 return false;
148 }
149 output = ChangeNotification(std::move(insertEntries), std::move(updateEntries), std::move(deleteEntries), deviceId,
150 isClear);
151 return true;
152 }
153
Marshalling(const DistributedRdb::RdbSyncerParam & param,MessageParcel & parcel)154 bool ITypesUtil::Marshalling(const DistributedRdb::RdbSyncerParam& param, MessageParcel& parcel)
155 {
156 if (!parcel.WriteString(param.bundleName_)) {
157 ZLOGE("RdbStoreParam write bundle name failed");
158 return false;
159 }
160 if (!parcel.WriteString(param.relativePath_)) {
161 ZLOGE("RdbStoreParam write directory failed");
162 return false;
163 }
164 if (!parcel.WriteString(param.storeName_)) {
165 ZLOGE("RdbStoreParam write store name failed");
166 return false;
167 }
168 if (!parcel.WriteString(param.encryptLevel_)) {
169 ZLOGE("RdbStoreParam write security level failed");
170 return false;
171 }
172 if (!parcel.WriteInt32(param.type_)) {
173 ZLOGE("RdbStoreParam write type failed");
174 return false;
175 }
176 if (!parcel.WriteBool(param.isAutoSync_)) {
177 ZLOGE("RdbStoreParam write auto sync failed");
178 return false;
179 }
180 return true;
181 }
182
UnMarshalling(MessageParcel & parcel,DistributedRdb::RdbSyncerParam & param)183 bool ITypesUtil::UnMarshalling(MessageParcel& parcel, DistributedRdb::RdbSyncerParam& param)
184 {
185 if (!parcel.ReadString(param.bundleName_)) {
186 ZLOGE("RdbStoreParam read bundle name failed");
187 return false;
188 }
189 if (!parcel.ReadString(param.relativePath_)) {
190 ZLOGE("RdbStoreParam read directory failed");
191 return false;
192 }
193 if (!parcel.ReadString(param.storeName_)) {
194 ZLOGE("RdbStoreParam read store name failed");
195 return false;
196 }
197 if (!parcel.ReadString(param.encryptLevel_)) {
198 ZLOGE("RdbStoreParam read security level failed");
199 return false;
200 }
201 if (!parcel.ReadInt32(param.type_)) {
202 ZLOGE("RdbStoreParam read type failed");
203 return false;
204 }
205 if (!parcel.ReadBool(param.isAutoSync_)) {
206 ZLOGE("RdbStoreParam read auto sync failed");
207 return false;
208 }
209 return true;
210 }
211
Marshalling(const DistributedRdb::SyncResult & result,MessageParcel & parcel)212 bool ITypesUtil::Marshalling(const DistributedRdb::SyncResult &result, MessageParcel &parcel)
213 {
214 if (!parcel.WriteInt32(static_cast<int32_t>(result.size()))) {
215 ZLOGE("SyncResult write size failed");
216 return false;
217 }
218
219 for (const auto& entry : result) {
220 if (!parcel.WriteString(entry.first)) {
221 ZLOGE("SyncResult write device failed");
222 return false;
223 }
224 if (!parcel.WriteInt32(entry.second)) {
225 ZLOGE("SyncResult write int failed");
226 return false;
227 }
228 }
229 return true;
230 }
231
UnMarshalling(MessageParcel & parcel,DistributedRdb::SyncResult & result)232 bool ITypesUtil::UnMarshalling(MessageParcel &parcel, DistributedRdb::SyncResult &result)
233 {
234 int32_t size = 0;
235 if (!parcel.ReadInt32(size)) {
236 ZLOGE("SyncResult read size failed");
237 return false;
238 }
239 if (size <= 0) {
240 ZLOGE("SyncResult size invalid");
241 return false;
242 }
243
244 for (int32_t i = 0; i < size; i++) {
245 std::string device;
246 if (!parcel.ReadString(device)) {
247 ZLOGE("SyncResult read device failed");
248 return false;
249 }
250 int32_t error;
251 if (!parcel.ReadInt32(error)) {
252 ZLOGE("SyncResult read int failed");
253 return false;
254 }
255 result.insert({ device, error });
256 }
257 return true;
258 }
259
Marshalling(const DistributedRdb::SyncOption & option,MessageParcel & parcel)260 bool ITypesUtil::Marshalling(const DistributedRdb::SyncOption &option, MessageParcel &parcel)
261 {
262 if (!parcel.WriteInt32(option.mode)) {
263 ZLOGE("SyncOption write mode failed");
264 return false;
265 }
266 if (!parcel.WriteBool(option.isBlock)) {
267 ZLOGE("SyncOption write isBlock failed");
268 return false;
269 }
270 return true;
271 }
272
UnMarshalling(MessageParcel & parcel,DistributedRdb::SyncOption & option)273 bool ITypesUtil::UnMarshalling(MessageParcel &parcel, DistributedRdb::SyncOption &option)
274 {
275 int32_t mode;
276 if (!parcel.ReadInt32(mode)) {
277 ZLOGE("SyncOption read mode failed");
278 return false;
279 }
280 option.mode = static_cast<DistributedRdb::SyncMode>(mode);
281 if (!parcel.ReadBool(option.isBlock)) {
282 ZLOGE("SyncOption read isBlock failed");
283 return false;
284 }
285 return true;
286 }
287
Marshalling(const DistributedRdb::RdbPredicates & predicates,MessageParcel & parcel)288 bool ITypesUtil::Marshalling(const DistributedRdb::RdbPredicates &predicates, MessageParcel &parcel)
289 {
290 if (!parcel.WriteString(predicates.table_)) {
291 ZLOGE("predicate write table failed");
292 return false;
293 }
294 if (!parcel.WriteStringVector(predicates.devices_)) {
295 ZLOGE("predicate write devices failed");
296 return false;
297 }
298 if (!parcel.WriteUint32(predicates.operations_.size())) {
299 ZLOGE("predicate write operation size failed");
300 return false;
301 }
302 for (const auto& operation : predicates.operations_) {
303 if (!parcel.WriteInt32(operation.operator_)) {
304 ZLOGE("predicate write operator failed");
305 return false;
306 }
307 if (!parcel.WriteString(operation.field_)) {
308 ZLOGE("predicate write field failed");
309 return false;
310 }
311 if (!parcel.WriteStringVector(operation.values_)) {
312 ZLOGE("predicate write values failed");
313 return false;
314 }
315 }
316 return true;
317 }
318
UnMarshalling(MessageParcel & parcel,DistributedRdb::RdbPredicates & predicates)319 bool ITypesUtil::UnMarshalling(MessageParcel &parcel, DistributedRdb::RdbPredicates &predicates)
320 {
321 if (!parcel.ReadString(predicates.table_)) {
322 ZLOGE("predicate read table failed");
323 return false;
324 }
325 if (!parcel.ReadStringVector(&predicates.devices_)) {
326 ZLOGE("predicate read devices failed");
327 return false;
328 }
329 uint32_t size = 0;
330 if (!parcel.ReadUint32(size)) {
331 ZLOGE("predicate read operation size failed");
332 return false;
333 }
334 for (uint32_t i = 0; i < size; i++) {
335 int32_t op;
336 if (!parcel.ReadInt32(op)) {
337 ZLOGE("predicate read operator failed");
338 return false;
339 }
340 DistributedRdb::RdbPredicateOperation operation;
341 operation.operator_ = static_cast<DistributedRdb::RdbPredicateOperator>(op);
342 if (!parcel.ReadString(operation.field_)) {
343 ZLOGE("predicate read field failed");
344 return false;
345 }
346 if (!parcel.ReadStringVector(&operation.values_)) {
347 ZLOGE("predicate read values failed");
348 return false;
349 }
350 predicates.operations_.push_back(std::move(operation));
351 }
352 return true;
353 }
354
355 template<class T>
Convert2Vector(const std::list<T> & entries)356 std::vector<T> ITypesUtil::Convert2Vector(const std::list<T> &entries)
357 {
358 std::vector<T> vector(entries.size());
359 int i = 0;
360 for (const auto &entry : entries) {
361 vector[i++] = entry;
362 }
363 return vector;
364 }
365
366 template<class T>
Convert2List(std::vector<T> && entries)367 std::list<T> ITypesUtil::Convert2List(std::vector<T> &&entries)
368 {
369 std::list<T> result;
370 for (auto &entry : entries) {
371 result.push_back(std::move(entry));
372 }
373 return result;
374 }
GetTotalSize(const std::vector<Entry> & entries)375 int64_t ITypesUtil::GetTotalSize(const std::vector<Entry> &entries)
376 {
377 int64_t bufferSize = 1;
378 for (const auto &item : entries) {
379 if (item.key.Size() > Constant::MAX_KEY_LENGTH || item.value.Size() > Constant::MAX_VALUE_LENGTH) {
380 return -bufferSize;
381 }
382 bufferSize += item.key.RawSize() + item.value.RawSize();
383 }
384 return bufferSize - 1;
385 }
GetTotalSize(const std::vector<Key> & entries)386 int64_t ITypesUtil::GetTotalSize(const std::vector<Key> &entries)
387 {
388 int64_t bufferSize = 1;
389 for (const auto &item : entries) {
390 if (item.Size() > Constant::MAX_KEY_LENGTH) {
391 return -bufferSize;
392 }
393 bufferSize += item.RawSize();
394 }
395 return bufferSize - 1;
396 }
397
398 template<typename T>
ReadVector(Parcel & parcel,std::vector<T> & val,bool (Parcel::* read)(T &))399 bool ITypesUtil::ReadVector(Parcel &parcel, std::vector<T> &val, bool (Parcel::*read)(T &))
400 {
401 int32_t len = parcel.ReadInt32();
402 if (len < 0) {
403 return false;
404 }
405
406 size_t readAbleSize = parcel.GetReadableBytes();
407 size_t size = static_cast<size_t>(len);
408 if ((size > readAbleSize) || (size > val.max_size())) {
409 return false;
410 }
411 val.resize(size);
412 if (val.size() < size) {
413 return false;
414 }
415
416 for (auto &v : val) {
417 if (!(parcel.*read)(v)) {
418 return false;
419 }
420 }
421
422 return true;
423 }
424
425 template<typename T>
WriteVector(Parcel & parcel,const std::vector<T> & val,bool (Parcel::* writer)(const T &))426 bool ITypesUtil::WriteVector(Parcel &parcel, const std::vector<T> &val, bool (Parcel::*writer)(const T &))
427 {
428 if (val.size() > INT_MAX) {
429 return false;
430 }
431
432 if (!parcel.WriteInt32(static_cast<int32_t>(val.size()))) {
433 return false;
434 }
435
436 for (auto &v : val) {
437 if (!(parcel.*writer)(v)) {
438 return false;
439 }
440 }
441 return true;
442 }
443 }
444
445