• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &notification, 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