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  #define LOG_TAG "ITypesUtil::KvTypesUtil"
16  #include "kv_types_util.h"
17  #include "log_print.h"
18  namespace OHOS::ITypesUtil {
19  using namespace DistributedKv;
20  template<>
Marshalling(const Blob & blob,MessageParcel & data)21  bool Marshalling(const Blob &blob, MessageParcel &data)
22  {
23      return data.WriteUInt8Vector(blob.Data());
24  }
25  
26  template<>
Unmarshalling(Blob & output,MessageParcel & data)27  bool Unmarshalling(Blob &output, MessageParcel &data)
28  {
29      std::vector<uint8_t> blob;
30      bool result = data.ReadUInt8Vector(&blob);
31      output = blob;
32      return result;
33  }
34  
35  template<>
Marshalling(const AppId & input,MessageParcel & data)36  bool Marshalling(const AppId &input, MessageParcel &data)
37  {
38      return ITypesUtil::Marshalling(input.appId, data);
39  }
40  
41  template<>
Unmarshalling(AppId & output,MessageParcel & data)42  bool Unmarshalling(AppId &output, MessageParcel &data)
43  {
44      return ITypesUtil::Unmarshalling(output.appId, data);
45  }
46  
47  template<>
Marshalling(const StoreId & input,MessageParcel & data)48  bool Marshalling(const StoreId &input, MessageParcel &data)
49  {
50      return ITypesUtil::Marshalling(input.storeId, data);
51  }
52  
53  template<>
Unmarshalling(StoreId & output,MessageParcel & data)54  bool Unmarshalling(StoreId &output, MessageParcel &data)
55  {
56      return ITypesUtil::Unmarshalling(output.storeId, data);
57  }
58  
59  template<>
Marshalling(const Entry & entry,MessageParcel & data)60  bool Marshalling(const Entry &entry, MessageParcel &data)
61  {
62      return ITypesUtil::Marshal(data, entry.key, entry.value);
63  }
64  
65  template<>
Unmarshalling(Entry & output,MessageParcel & data)66  bool Unmarshalling(Entry &output, MessageParcel &data)
67  {
68      return ITypesUtil::Unmarshal(data, output.key, output.value);
69  }
70  
71  template<>
Marshalling(const DeviceInfo & entry,MessageParcel & data)72  bool Marshalling(const DeviceInfo &entry, MessageParcel &data)
73  {
74      return ITypesUtil::Marshal(data, entry.deviceId, entry.deviceName, entry.deviceType);
75  }
76  
77  template<>
Unmarshalling(DeviceInfo & output,MessageParcel & data)78  bool Unmarshalling(DeviceInfo &output, MessageParcel &data)
79  {
80      return ITypesUtil::Unmarshal(data, output.deviceId, output.deviceName, output.deviceType);
81  }
82  
83  template<>
Marshalling(const ChangeNotification & notification,MessageParcel & parcel)84  bool Marshalling(const ChangeNotification &notification, MessageParcel &parcel)
85  {
86      return ITypesUtil::Marshal(parcel, notification.GetInsertEntries(), notification.GetUpdateEntries(),
87          notification.GetDeleteEntries(), notification.GetDeviceId(), notification.IsClear());
88  }
89  
90  template<>
Unmarshalling(ChangeNotification & output,MessageParcel & parcel)91  bool Unmarshalling(ChangeNotification &output, MessageParcel &parcel)
92  {
93      std::vector<Entry> inserts;
94      std::vector<Entry> updates;
95      std::vector<Entry> deletes;
96      std::string deviceId;
97      bool isClear = false;
98      if (!ITypesUtil::Unmarshal(parcel, inserts, updates, deletes, deviceId, isClear)) {
99          return false;
100      }
101      output = ChangeNotification(std::move(inserts), std::move(updates), std::move(deletes), deviceId, isClear);
102      return true;
103  }
104  
105  template<>
Marshalling(const Options & input,MessageParcel & data)106  bool Marshalling(const Options &input, MessageParcel &data)
107  {
108      if (!ITypesUtil::Marshal(data, input.schema, input.hapName, input.policies, input.cloudConfig.enableCloud,
109                               input.cloudConfig.autoSync, input.authType)) {
110          ZLOGE("write policies failed");
111          return false;
112      }
113  
114      std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(sizeof(input));
115      Options *target = reinterpret_cast<Options *>(buffer.get());
116      target->createIfMissing = input.createIfMissing;
117      target->encrypt = input.encrypt;
118      target->persistent = input.persistent;
119      target->backup = input.backup;
120      target->autoSync = input.autoSync;
121      target->syncable = input.syncable;
122      target->securityLevel = input.securityLevel;
123      target->area = input.area;
124      target->kvStoreType = input.kvStoreType;
125      target->isNeedCompress = input.isNeedCompress;
126      target->dataType = input.dataType;
127      target->isPublic = input.isPublic;
128      target->subUser = input.subUser;
129      return data.WriteRawData(buffer.get(), sizeof(input));
130  }
131  
132  template<>
Unmarshalling(Options & output,MessageParcel & data)133  bool Unmarshalling(Options &output, MessageParcel &data)
134  {
135      if (!ITypesUtil::Unmarshal(data, output.schema, output.hapName, output.policies, output.cloudConfig.enableCloud,
136                                 output.cloudConfig.autoSync, output.authType)) {
137          ZLOGE("read policies failed");
138          return false;
139      }
140  
141      const Options *source = reinterpret_cast<const Options *>(data.ReadRawData(sizeof(output)));
142      if (source == nullptr) {
143          return false;
144      }
145      output.createIfMissing = source->createIfMissing;
146      output.encrypt = source->encrypt;
147      output.persistent = source->persistent;
148      output.backup = source->backup;
149      output.autoSync = source->autoSync;
150      output.securityLevel = source->securityLevel;
151      output.area = source->area;
152      output.kvStoreType = source->kvStoreType;
153      output.syncable = source->syncable;
154      output.isNeedCompress = source->isNeedCompress;
155      output.dataType = source->dataType;
156      output.isPublic = source->isPublic;
157      output.subUser = source->subUser;
158      return true;
159  }
160  
161  template<>
Marshalling(const AuthType & input,MessageParcel & data)162  bool Marshalling(const AuthType &input, MessageParcel &data)
163  {
164      return ITypesUtil::Marshal(data, static_cast<int32_t>(input));
165  }
166  
167  template<>
Unmarshalling(AuthType & output,MessageParcel & data)168  bool Unmarshalling(AuthType &output, MessageParcel &data)
169  {
170      int32_t authType;
171      if (!ITypesUtil::Unmarshal(data, authType)) {
172          return false;
173      }
174      output = static_cast<AuthType>(authType);
175      return true;
176  }
177  
178  template<>
Marshalling(const SyncPolicy & input,MessageParcel & data)179  bool Marshalling(const SyncPolicy &input, MessageParcel &data)
180  {
181      return ITypesUtil::Marshal(data, input.type, input.value);
182  }
183  
184  template<>
Unmarshalling(SyncPolicy & output,MessageParcel & data)185  bool Unmarshalling(SyncPolicy &output, MessageParcel &data)
186  {
187      return ITypesUtil::Unmarshal(data, output.type, output.value);
188  }
189  
190  template<>
Marshalling(const SwitchData & input,MessageParcel & data)191  bool Marshalling(const SwitchData &input, MessageParcel &data)
192  {
193      return ITypesUtil::Marshal(data, input.value, input.length);
194  }
195  
196  template<>
Unmarshalling(SwitchData & output,MessageParcel & data)197  bool Unmarshalling(SwitchData &output, MessageParcel &data)
198  {
199      return ITypesUtil::Unmarshal(data, output.value, output.length);
200  }
201  
202  template<>
Marshalling(const Status & input,MessageParcel & data)203  bool Marshalling(const Status &input, MessageParcel &data)
204  {
205      return ITypesUtil::Marshal(data, static_cast<int32_t>(input));
206  }
207  
208  template<>
Unmarshalling(Status & output,MessageParcel & data)209  bool Unmarshalling(Status &output, MessageParcel &data)
210  {
211      int32_t status;
212      if (!ITypesUtil::Unmarshal(data, status)) {
213          return false;
214      }
215      output = static_cast<Status>(status);
216      return true;
217  }
218  
219  template<>
Marshalling(const Notification & input,MessageParcel & data)220  bool Marshalling(const Notification &input, MessageParcel &data)
221  {
222      return ITypesUtil::Marshal(
223          data, input.data.value, input.data.length, input.deviceId, static_cast<int32_t>(input.state));
224  }
225  
226  template<>
Unmarshalling(Notification & output,MessageParcel & data)227  bool Unmarshalling(Notification &output, MessageParcel &data)
228  {
229      int32_t state;
230      if (!ITypesUtil::Unmarshal(data, output.data.value, output.data.length, output.deviceId, state)) {
231          return false;
232      }
233      output.state = static_cast<SwitchState>(state);
234      return true;
235  }
236  
237  template<>
Marshalling(const ProgressDetail & input,MessageParcel & data)238  bool Marshalling(const ProgressDetail &input, MessageParcel &data)
239  {
240      return Marshal(data, input.progress, input.code, input.details);
241  }
242  template<>
Unmarshalling(ProgressDetail & output,MessageParcel & data)243  bool Unmarshalling(ProgressDetail &output, MessageParcel &data)
244  {
245      return Unmarshal(data, output.progress, output.code, output.details);
246  }
247  template<>
Marshalling(const TableDetail & input,MessageParcel & data)248  bool Marshalling(const TableDetail &input, MessageParcel &data)
249  {
250      return Marshal(data, input.upload, input.download);
251  }
252  template<>
Unmarshalling(TableDetail & output,MessageParcel & data)253  bool Unmarshalling(TableDetail &output, MessageParcel &data)
254  {
255      return Unmarshal(data, output.upload, output.download);
256  }
257  template<>
Marshalling(const Statistic & input,MessageParcel & data)258  bool Marshalling(const Statistic &input, MessageParcel &data)
259  {
260      return Marshal(data, input.total, input.success, input.failed, input.untreated);
261  }
262  template<>
Unmarshalling(Statistic & output,MessageParcel & data)263  bool Unmarshalling(Statistic &output, MessageParcel &data)
264  {
265      return Unmarshal(data, output.total, output.success, output.failed, output.untreated);
266  }
267  
268  template<>
Marshalling(const CloudConfig & input,MessageParcel & data)269  bool Marshalling(const CloudConfig &input, MessageParcel &data)
270  {
271      return Marshal(data, input.enableCloud, input.autoSync);
272  }
273  template<>
Unmarshalling(CloudConfig & output,MessageParcel & data)274  bool Unmarshalling(CloudConfig &output, MessageParcel &data)
275  {
276      return Unmarshal(data, output.enableCloud, output.autoSync);
277  }
278  
279  template<>
Marshalling(const StoreConfig & input,MessageParcel & data)280  bool Marshalling(const StoreConfig &input, MessageParcel &data)
281  {
282      return Marshal(data, input.cloudConfig);
283  }
284  template<>
Unmarshalling(StoreConfig & output,MessageParcel & data)285  bool Unmarshalling(StoreConfig &output, MessageParcel &data)
286  {
287      return Unmarshal(data, output.cloudConfig);
288  }
289  
GetTotalSize(const std::vector<Entry> & entries)290  int64_t GetTotalSize(const std::vector<Entry> &entries)
291  {
292      int64_t bufferSize = 1;
293      for (const auto &item : entries) {
294          if (item.key.Size() > Entry::MAX_KEY_LENGTH || item.value.Size() > Entry::MAX_VALUE_LENGTH) {
295              return -bufferSize;
296          }
297          bufferSize += item.key.RawSize() + item.value.RawSize();
298      }
299      return bufferSize - 1;
300  }
301  
GetTotalSize(const std::vector<Key> & entries)302  int64_t GetTotalSize(const std::vector<Key> &entries)
303  {
304      int64_t bufferSize = 1;
305      for (const auto &item : entries) {
306          if (item.Size() > Entry::MAX_KEY_LENGTH) {
307              return -bufferSize;
308          }
309          bufferSize += item.RawSize();
310      }
311      return bufferSize - 1;
312  }
313  }