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 ¬ification, 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