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 FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_ITYPES_UTIL_H
17 #define FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_ITYPES_UTIL_H
18
19 #include <climits>
20 #include <map>
21 #include <memory>
22
23 #include "global.h"
24 #include "input_method_property.h"
25 #include "message_parcel.h"
26
27 namespace OHOS {
28 namespace MiscServices {
29 class ITypesUtil final {
30 public:
31 static bool Marshal(MessageParcel &data);
32 static bool Unmarshal(MessageParcel &data);
33
34 static bool Marshalling(bool input, MessageParcel &data);
35 static bool Unmarshalling(bool &output, MessageParcel &data);
36
37 static bool Marshalling(uint32_t input, MessageParcel &data);
38 static bool Unmarshalling(uint32_t &output, MessageParcel &data);
39
40 static bool Marshalling(int32_t input, MessageParcel &data);
41 static bool Unmarshalling(int32_t &output, MessageParcel &data);
42
43 static bool Marshalling(uint64_t input, MessageParcel &data);
44 static bool Unmarshalling(uint64_t &output, MessageParcel &data);
45
46 static bool Marshalling(const std::u16string &input, MessageParcel &data);
47 static bool Unmarshalling(std::u16string &output, MessageParcel &data);
48
49 static bool Marshalling(const std::string &input, MessageParcel &data);
50 static bool Unmarshalling(std::string &output, MessageParcel &data);
51
52 static bool Marshalling(const std::vector<uint8_t> &input, MessageParcel &data);
53 static bool Unmarshalling(std::vector<uint8_t> &output, MessageParcel &data);
54
55 static bool Marshalling(const sptr<IRemoteObject> &input, MessageParcel &data);
56 static bool Unmarshalling(sptr<IRemoteObject> &output, MessageParcel &data);
57
58 static bool Marshalling(const Property &input, MessageParcel &data);
59 static bool Unmarshalling(Property &output, MessageParcel &data);
60
61 static bool Marshalling(const SubProperty &input, MessageParcel &data);
62 static bool Unmarshalling(SubProperty &output, MessageParcel &data);
63
64 template<class T>
65 static bool Marshalling(const std::vector<T> &val, MessageParcel &parcel);
66 template<class T>
67 static bool Unmarshalling(std::vector<T> &val, MessageParcel &parcel);
68
69 template<class K, class V>
70 static bool Marshalling(const std::map<K, V> &val, MessageParcel &parcel);
71 template<class K, class V>
72 static bool Unmarshalling(std::map<K, V> &val, MessageParcel &parcel);
73
74 template<typename T, typename... Types>
75 static bool Marshal(MessageParcel &parcel, const T &first, const Types &...others);
76 template<typename T, typename... Types>
77 static bool Unmarshal(MessageParcel &parcel, T &first, Types &...others);
78
79 template<typename T>
80 static int32_t MarshalToBuffer(const T &input, int size, MessageParcel &data);
81
82 template<typename T>
83 static int32_t MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data);
84
85 template<typename T>
86 static int32_t UnmarshalFromBuffer(MessageParcel &data, int size, T &output);
87 template<typename T>
88 static int32_t UnmarshalFromBuffer(MessageParcel &data, int size, std::vector<T> &output);
89 };
90
91 template<class T>
Marshalling(const std::vector<T> & val,MessageParcel & parcel)92 bool ITypesUtil::Marshalling(const std::vector<T> &val, MessageParcel &parcel)
93 {
94 if (val.size() > INT_MAX) {
95 return false;
96 }
97
98 if (!parcel.WriteInt32(static_cast<int32_t>(val.size()))) {
99 return false;
100 }
101
102 for (auto &v : val) {
103 if (!Marshalling(v, parcel)) {
104 return false;
105 }
106 }
107 return true;
108 }
109
110 template<class T>
Unmarshalling(std::vector<T> & val,MessageParcel & parcel)111 bool ITypesUtil::Unmarshalling(std::vector<T> &val, MessageParcel &parcel)
112 {
113 int32_t len = parcel.ReadInt32();
114 if (len < 0) {
115 return false;
116 }
117
118 size_t readAbleSize = parcel.GetReadableBytes();
119 size_t size = static_cast<size_t>(len);
120 if ((size > readAbleSize) || (size > val.max_size())) {
121 return false;
122 }
123
124 val.resize(size);
125 if (val.size() < size) {
126 return false;
127 }
128
129 for (auto &v : val) {
130 if (!Unmarshalling(v, parcel)) {
131 return false;
132 }
133 }
134
135 return true;
136 }
137
138 template<typename T>
MarshalToBuffer(const T & input,int size,MessageParcel & data)139 int32_t ITypesUtil::MarshalToBuffer(const T &input, int size, MessageParcel &data)
140 {
141 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
142 if (!data.WriteBool(buffer != nullptr)) {
143 return ErrorCode::ERROR_EX_PARCELABLE;
144 }
145 if (buffer == nullptr) {
146 return ErrorCode::ERROR_EX_NULL_POINTER;
147 }
148
149 int leftSize = size;
150 uint8_t *cursor = buffer.get();
151 if (!input.WriteToBuffer(cursor, leftSize)) {
152 return ErrorCode::ERROR_EX_PARCELABLE;
153 }
154 return data.WriteRawData(buffer.get(), size) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
155 }
156
157 template<typename T>
MarshalToBuffer(const std::vector<T> & input,int size,MessageParcel & data)158 int32_t ITypesUtil::MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data)
159 {
160 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
161 if (!data.WriteBool(buffer != nullptr)) {
162 return ErrorCode::ERROR_EX_PARCELABLE;
163 }
164 if (buffer == nullptr) {
165 return ErrorCode::ERROR_EX_ILLEGAL_STATE;
166 }
167 uint8_t *cursor = buffer.get();
168 for (const auto &entry : input) {
169 if (!entry.WriteToBuffer(cursor, size)) {
170 return ErrorCode::ERROR_EX_PARCELABLE;
171 }
172 }
173 if (!data.WriteInt32(input.size())) {
174 return ErrorCode::ERROR_EX_PARCELABLE;
175 }
176 return data.WriteRawData(buffer.get(), size) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
177 }
178
179 template<typename T>
UnmarshalFromBuffer(MessageParcel & data,int size,T & output)180 int32_t ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, int size, T &output)
181 {
182 if (size < 0) {
183 return ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT;
184 }
185 if (!data.ReadBool()) {
186 return ErrorCode::ERROR_EX_ILLEGAL_STATE;
187 }
188 const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
189 if (buffer == nullptr) {
190 return ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT;
191 }
192 return output.ReadFromBuffer(buffer, size) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
193 }
194
195 template<typename T>
UnmarshalFromBuffer(MessageParcel & data,int size,std::vector<T> & output)196 int32_t ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, int size, std::vector<T> &output)
197 {
198 if (size < 0) {
199 return ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT;
200 }
201 if (!data.ReadBool()) {
202 return ErrorCode::ERROR_EX_ILLEGAL_STATE;
203 }
204 int count = data.ReadInt32();
205 const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
206 if (count < 0 || buffer == nullptr) {
207 return ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT;
208 }
209
210 output.resize(count);
211 for (auto &entry : output) {
212 if (!entry.ReadFromBuffer(buffer, size)) {
213 output.clear();
214 return ErrorCode::ERROR_EX_PARCELABLE;
215 }
216 }
217 return ErrorCode::NO_ERROR;
218 }
219
220 template<typename T, typename... Types>
Marshal(MessageParcel & parcel,const T & first,const Types &...others)221 bool ITypesUtil::Marshal(MessageParcel &parcel, const T &first, const Types &...others)
222 {
223 if (!Marshalling(first, parcel)) {
224 return false;
225 }
226 return Marshal(parcel, others...);
227 }
228
229 template<typename T, typename... Types>
Unmarshal(MessageParcel & parcel,T & first,Types &...others)230 bool ITypesUtil::Unmarshal(MessageParcel &parcel, T &first, Types &...others)
231 {
232 if (!Unmarshalling(first, parcel)) {
233 return false;
234 }
235 return Unmarshal(parcel, others...);
236 }
237
238 template<class K, class V>
Marshalling(const std::map<K,V> & result,MessageParcel & parcel)239 bool ITypesUtil::Marshalling(const std::map<K, V> &result, MessageParcel &parcel)
240 {
241 if (!parcel.WriteInt32(static_cast<int32_t>(result.size()))) {
242 return false;
243 }
244 for (const auto &entry : result) {
245 if (!Marshalling(entry.first, parcel)) {
246 return false;
247 }
248 if (!Marshalling(entry.second, parcel)) {
249 return false;
250 }
251 }
252 return true;
253 }
254
255 template<class K, class V>
Unmarshalling(std::map<K,V> & val,MessageParcel & parcel)256 bool ITypesUtil::Unmarshalling(std::map<K, V> &val, MessageParcel &parcel)
257 {
258 int32_t size = 0;
259 if (!parcel.ReadInt32(size)) {
260 return false;
261 }
262 if (size < 0) {
263 return false;
264 }
265
266 size_t readAbleSize = parcel.GetReadableBytes();
267 size_t len = static_cast<size_t>(size);
268 if ((len > readAbleSize) || len > val.max_size()) {
269 return false;
270 }
271
272 for (int32_t i = 0; i < size; i++) {
273 K key;
274 if (!Unmarshalling(key, parcel)) {
275 return false;
276 }
277 V value;
278 if (!Unmarshalling(value, parcel)) {
279 return false;
280 }
281 val.insert({ key, value });
282 }
283 return true;
284 }
285 } // namespace MiscServices
286 } // namespace OHOS
287 #endif
288