• 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 #ifndef DISTRIBUTED_DATA_FRAMEWORKS_COMMON_ITYPES_UTIL_H
17 #define DISTRIBUTED_DATA_FRAMEWORKS_COMMON_ITYPES_UTIL_H
18 
19 #include <memory>
20 #include "types.h"
21 #include "change_notification.h"
22 #include "message_parcel.h"
23 #include "rdb_types.h"
24 
25 namespace OHOS::DistributedKv {
26 class ITypesUtil final {
27 public:
28     static bool Marshalling(const Blob &blob, MessageParcel &data);
29     static bool Unmarshalling(MessageParcel &data, Blob &output);
30 
31     static bool Marshalling(const std::vector<Blob> &blobs, MessageParcel &data);
32     static bool Unmarshalling(MessageParcel &data, std::vector<Blob> &output);
33 
34     static bool Marshalling(const Entry &entry, MessageParcel &data);
35     static bool Unmarshalling(MessageParcel &data, Entry &output);
36 
37     static bool Marshalling(const std::vector<Entry> &entry, MessageParcel &data);
38     static bool Unmarshalling(MessageParcel &data, std::vector<Entry> &output);
39 
40     static bool Marshalling(const DeviceInfo &entry, MessageParcel &data);
41     static bool Unmarshalling(MessageParcel &data, DeviceInfo &output);
42 
43     static bool Marshalling(const std::vector<DeviceInfo> &input, MessageParcel &data);
44     static bool Unmarshalling(MessageParcel &data, std::vector<DeviceInfo> &output);
45 
46     static bool Marshalling(const ChangeNotification &notification, MessageParcel &parcel);
47     static bool Unmarshalling(MessageParcel &parcel, ChangeNotification &output);
48 
49     static bool Marshalling(const DistributedRdb::RdbSyncerParam& param, MessageParcel& parcel);
50     static bool UnMarshalling(MessageParcel& parcel, DistributedRdb::RdbSyncerParam& param);
51 
52     static bool Marshalling(const DistributedRdb::SyncResult& result, MessageParcel& parcel);
53     static bool UnMarshalling(MessageParcel& parcel, DistributedRdb::SyncResult& result);
54 
55     static bool Marshalling(const DistributedRdb::SyncOption& option, MessageParcel& parcel);
56     static bool UnMarshalling(MessageParcel& parcel, DistributedRdb::SyncOption& option);
57 
58     static bool Marshalling(const DistributedRdb::RdbPredicates& predicates, MessageParcel& parcel);
59     static bool UnMarshalling(MessageParcel& parcel, DistributedRdb::RdbPredicates& predicates);
60 
61     static int64_t GetTotalSize(const std::vector<Entry> &entries);
62     static int64_t GetTotalSize(const std::vector<Key> &entries);
63 
64     template<typename T>
MarshalToBuffer(const T & input,int size,MessageParcel & data)65     static Status MarshalToBuffer(const T &input, int size, MessageParcel &data)
66     {
67         std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
68         if (!data.WriteBool(buffer != nullptr)) {
69             return Status::IPC_ERROR;
70         }
71         if (buffer == nullptr) {
72             return Status::ILLEGAL_STATE;
73         }
74         uint8_t *cursor = buffer.get();
75         if (!input.WriteToBuffer(cursor, size)) {
76             return Status::IPC_ERROR;
77         }
78         return data.WriteRawData(buffer.get(), size) ? Status::SUCCESS :  Status::IPC_ERROR;
79     }
80 
81     template<typename T>
MarshalToBuffer(const std::vector<T> & input,int size,MessageParcel & data)82     static Status MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data)
83     {
84         std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
85         if (!data.WriteBool(buffer != nullptr)) {
86             return Status::IPC_ERROR;
87         }
88         if (buffer == nullptr) {
89             return Status::ILLEGAL_STATE;
90         }
91         uint8_t *cursor = buffer.get();
92         for (const auto &entry : input) {
93             if (!entry.WriteToBuffer(cursor, size)) {
94                 return Status::IPC_ERROR;
95             }
96         }
97         if (!data.WriteInt32(input.size())) {
98             return Status::IPC_ERROR;
99         }
100         return data.WriteRawData(buffer.get(), size) ? Status::SUCCESS :  Status::IPC_ERROR;
101     }
102 
103     template<typename T>
UnmarshalFromBuffer(MessageParcel & data,int size,T & output)104     static Status UnmarshalFromBuffer(MessageParcel &data, int size, T &output)
105     {
106         if (size < 0) {
107             return Status::INVALID_ARGUMENT;
108         }
109         if (!data.ReadBool()) {
110             return Status::ILLEGAL_STATE;
111         }
112         const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
113         if (buffer == nullptr) {
114             return Status::INVALID_ARGUMENT;
115         }
116         return output.ReadFromBuffer(buffer, size) ? Status::SUCCESS :  Status::IPC_ERROR;
117     }
118 
119     template<typename T>
UnmarshalFromBuffer(MessageParcel & data,int size,std::vector<T> & output)120     static Status UnmarshalFromBuffer(MessageParcel &data, int size, std::vector<T> &output)
121     {
122         if (size < 0) {
123             return Status::INVALID_ARGUMENT;
124         }
125         if (!data.ReadBool()) {
126             return Status::ILLEGAL_STATE;
127         }
128         int count = data.ReadInt32();
129         const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
130         if (count < 0 || buffer == nullptr) {
131             return Status::INVALID_ARGUMENT;
132         }
133 
134         output.resize(count);
135         for (auto &entry : output) {
136             if (!entry.ReadFromBuffer(buffer, size)) {
137                 output.clear();
138                 return Status::IPC_ERROR;
139             }
140         }
141         return Status::SUCCESS;
142     }
143 
144 private:
145     template<typename T>
146     class VectorParcel : public MessageParcel {
147     public:
Writer(const T & entry)148         bool Writer(const T &entry) { return ITypesUtil::Marshalling(entry, *this); }
Reader(T & entry)149         bool Reader(T &entry) { return ITypesUtil::Unmarshalling(*this, entry); }
150     };
151 
152     template <typename T>
153     static bool ReadVector(Parcel &parcel, std::vector<T> &val, bool (Parcel::*read)(T &));
154     template <typename T>
155     static bool WriteVector(Parcel &parcel, const std::vector<T> &val, bool (Parcel::*writer)(const T &));
156     template<typename T> using Reader = bool (Parcel::*)(T &);
157     template<typename T> using Writer = bool (Parcel::*)(const T &);
158     template<typename T>
GetParcelWriter()159     static Writer<T> GetParcelWriter()
160     {
161         return static_cast<Writer<T>>(&VectorParcel<T>::Writer);
162     }
163     template<typename T>
GetParcelReader()164     static Reader<T> GetParcelReader()
165     {
166         return static_cast<Reader<T>>(&VectorParcel<T>::Reader);
167     }
168     template<typename T>
169     static std::vector<T> Convert2Vector(const std::list<T> &entries);
170     template<typename T>
171     static std::list<T> Convert2List(std::vector<T> &&entries);
172 };
173 }
174 #endif
175 
176