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 #include <climits> 19 #include <list> 20 #include <map> 21 #include <memory> 22 #include <type_traits> 23 #include <variant> 24 #include <vector> 25 26 #include "iremote_object.h" 27 #include "message_parcel.h" 28 namespace OHOS { 29 template<class T> 30 struct is_container : std::false_type { 31 }; 32 template<class T> 33 struct is_container<std::vector<T>> : std::true_type { 34 }; 35 template<class T> 36 struct is_container<std::list<T>> : std::true_type { 37 }; 38 namespace ITypesUtil { 39 inline constexpr size_t MAX_COUNT = 100000; 40 inline constexpr size_t MAX_SIZE = 1 * 1024 * 1024 * 1024; //1G 41 static inline bool Marshal(MessageParcel &data) 42 { 43 return true; 44 } 45 46 static inline bool Unmarshal(MessageParcel &data) 47 { 48 return true; 49 } 50 51 static inline bool Marshalling(int16_t input, MessageParcel &data) 52 { 53 return data.WriteInt16(input); 54 } 55 56 static inline bool Unmarshalling(int16_t &output, MessageParcel &data) 57 { 58 return data.ReadInt16(output); 59 } 60 61 static inline bool Marshalling(uint32_t input, MessageParcel &data) 62 { 63 return data.WriteUint32(input); 64 } 65 66 static inline bool Unmarshalling(uint32_t &output, MessageParcel &data) 67 { 68 return data.ReadUint32(output); 69 } 70 71 static inline bool Marshalling(int32_t input, MessageParcel &data) 72 { 73 return data.WriteInt32(input); 74 } 75 76 static inline bool Unmarshalling(int32_t &output, MessageParcel &data) 77 { 78 return data.ReadInt32(output); 79 } 80 81 static inline bool Marshalling(uint64_t input, MessageParcel &data) 82 { 83 return data.WriteUint64(input); 84 } 85 86 static inline bool Unmarshalling(uint64_t &output, MessageParcel &data) 87 { 88 return data.ReadUint64(output); 89 } 90 91 static inline bool Marshalling(int64_t input, MessageParcel &data) 92 { 93 return data.WriteInt64(input); 94 } 95 96 static inline bool Unmarshalling(int64_t &output, MessageParcel &data) 97 { 98 return data.ReadInt64(output); 99 } 100 101 static inline bool Marshalling(double input, MessageParcel &data) 102 { 103 return data.WriteDouble(input); 104 } 105 106 static inline bool Unmarshalling(double &output, MessageParcel &data) 107 { 108 return data.ReadDouble(output); 109 } 110 111 static inline bool Marshalling(bool input, MessageParcel &data) 112 { 113 return data.WriteBool(input); 114 } 115 116 static inline bool Unmarshalling(bool &output, MessageParcel &data) 117 { 118 return data.ReadBool(output); 119 } 120 121 static inline bool Marshalling(const std::monostate &input, MessageParcel &data) 122 { 123 return true; 124 } 125 126 static inline bool Unmarshalling(std::monostate &output, MessageParcel &data) 127 { 128 return true; 129 } 130 131 static inline bool Marshalling(const std::string &input, MessageParcel &data) 132 { 133 return data.WriteString(input); 134 } 135 136 static inline bool Unmarshalling(std::string &output, MessageParcel &data) 137 { 138 return data.ReadString(output); 139 } 140 141 static inline bool Marshalling(const std::vector<uint8_t> &input, MessageParcel &data) 142 { 143 return data.WriteUInt8Vector(input); 144 } 145 146 static inline bool Unmarshalling(std::vector<uint8_t> &output, MessageParcel &data) 147 { 148 return data.ReadUInt8Vector(&output); 149 } 150 151 static inline bool Marshalling(const sptr<IRemoteObject> &input, MessageParcel &data) 152 { 153 return data.WriteRemoteObject(input); 154 } 155 156 static inline bool Unmarshalling(sptr<IRemoteObject> &output, MessageParcel &data) 157 { 158 output = data.ReadRemoteObject(); 159 return true; 160 } 161 162 static inline bool Marshalling(IRemoteObject *input, MessageParcel &data) 163 { 164 return data.WriteRemoteObject(input); 165 } 166 167 template<typename _OutTp> 168 bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data); 169 template<typename _OutTp, typename _First, typename... _Rest> 170 bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data); 171 172 template<typename _InTp> 173 bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data); 174 template<typename _InTp, typename _First, typename... _Rest> 175 bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data); 176 177 template<typename... _Types> 178 bool Marshalling(const std::variant<_Types...> &input, MessageParcel &data); 179 template<typename... _Types> 180 bool Unmarshalling(std::variant<_Types...> &output, MessageParcel &data); 181 182 template<class K, class V> 183 bool Marshalling(const std::map<K, V> &result, MessageParcel &parcel); 184 template<class K, class V> 185 bool Unmarshalling(std::map<K, V> &val, MessageParcel &parcel); 186 187 template<class T> 188 bool Marshalling(const std::vector<T> &val, MessageParcel &parcel); 189 template<class T> 190 bool Unmarshalling(std::vector<T> &val, MessageParcel &parcel); 191 192 template<class T> 193 bool Marshalling(const std::list<T> &val, MessageParcel &parcel); 194 template<class T> 195 bool Unmarshalling(std::list<T> &val, MessageParcel &parcel); 196 197 template<typename T, typename std::enable_if<std::is_pointer<T>{}, int>::type = 0> 198 bool Marshalling(const T &input, MessageParcel &data) = delete; 199 template<typename T, typename std::enable_if<std::is_pointer<T>{}, int>::type = 0> 200 bool Unmarshalling(T &output, MessageParcel &data) = delete; 201 202 template<typename T> 203 bool Marshalling(const T &input, MessageParcel &data); 204 template<typename T> 205 bool Unmarshalling(T &output, MessageParcel &data); 206 207 template<class T, typename std::enable_if<is_container<T>{}, int>::type = 0> 208 bool MarshalToContainer(const T &val, MessageParcel &parcel); 209 template<class T, typename std::enable_if<is_container<T>{}, int>::type = 0> 210 bool UnmarshalFromContainer(T &val, MessageParcel &parcel); 211 212 template<typename T> 213 bool MarshalToBuffer(const T &input, int size, MessageParcel &data); 214 template<typename T> 215 bool MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data); 216 217 template<typename T> 218 bool UnmarshalFromBuffer(MessageParcel &data, T &output); 219 template<typename T> 220 bool UnmarshalFromBuffer(MessageParcel &data, std::vector<T> &output); 221 222 template<typename T, typename... Types> 223 bool Marshal(MessageParcel &parcel, const T &first, const Types &...others); 224 225 template<typename T, typename... Types> 226 bool Unmarshal(MessageParcel &parcel, T &first, Types &...others); 227 } // namespace ITypesUtil 228 229 template<typename _OutTp> 230 bool ITypesUtil::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data) 231 { 232 return false; 233 } 234 235 template<typename _OutTp, typename _First, typename... _Rest> 236 bool ITypesUtil::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data) 237 { 238 if (step == index) { 239 _First value{}; 240 auto success = ITypesUtil::Unmarshalling(value, data); 241 output = value; 242 return success; 243 } 244 return ITypesUtil::ReadVariant<_OutTp, _Rest...>(step + 1, index, output, data); 245 } 246 247 template<typename _InTp> 248 bool ITypesUtil::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data) 249 { 250 return false; 251 } 252 253 template<typename _InTp, typename _First, typename... _Rest> 254 bool ITypesUtil::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data) 255 { 256 if (step == input.index()) { 257 return ITypesUtil::Marshalling(std::get<_First>(input), data); 258 } 259 return ITypesUtil::WriteVariant<_InTp, _Rest...>(step + 1, input, data); 260 } 261 262 template<typename... _Types> 263 bool ITypesUtil::Marshalling(const std::variant<_Types...> &input, MessageParcel &data) 264 { 265 uint32_t index = static_cast<uint32_t>(input.index()); 266 if (!data.WriteUint32(index)) { 267 return false; 268 } 269 270 return ITypesUtil::WriteVariant<decltype(input), _Types...>(0, input, data); 271 } 272 273 template<typename... _Types> 274 bool ITypesUtil::Unmarshalling(std::variant<_Types...> &output, MessageParcel &data) 275 { 276 uint32_t index = data.ReadUint32(); 277 if (index >= sizeof...(_Types)) { 278 return false; 279 } 280 281 return ITypesUtil::ReadVariant<decltype(output), _Types...>(0, index, output, data); 282 } 283 284 template<class K, class V> 285 bool ITypesUtil::Marshalling(const std::map<K, V> &result, MessageParcel &parcel) 286 { 287 if (!parcel.WriteInt32(static_cast<int32_t>(result.size()))) { 288 return false; 289 } 290 for (const auto &entry : result) { 291 if (!ITypesUtil::Marshalling(entry.first, parcel)) { 292 return false; 293 } 294 if (!ITypesUtil::Marshalling(entry.second, parcel)) { 295 return false; 296 } 297 } 298 return true; 299 } 300 301 template<class K, class V> 302 bool ITypesUtil::Unmarshalling(std::map<K, V> &val, MessageParcel &parcel) 303 { 304 int32_t size = 0; 305 if (!parcel.ReadInt32(size)) { 306 return false; 307 } 308 if (size < 0) { 309 return false; 310 } 311 312 size_t readAbleSize = parcel.GetReadableBytes(); 313 if ((static_cast<size_t>(size) > readAbleSize) || static_cast<size_t>(size) > val.max_size()) { 314 return false; 315 } 316 317 for (int32_t i = 0; i < size; i++) { 318 K key; 319 if (!ITypesUtil::Unmarshalling(key, parcel)) { 320 return false; 321 } 322 if (!ITypesUtil::Unmarshalling(val[key], parcel)) { 323 return false; 324 } 325 } 326 return true; 327 } 328 329 template<class T> 330 bool ITypesUtil::Marshalling(const std::vector<T> &val, MessageParcel &parcel) 331 { 332 return ITypesUtil::MarshalToContainer(val, parcel); 333 } 334 335 template<class T> 336 bool ITypesUtil::Unmarshalling(std::vector<T> &val, MessageParcel &parcel) 337 { 338 return ITypesUtil::UnmarshalFromContainer(val, parcel); 339 } 340 341 template<class T> 342 bool ITypesUtil::Marshalling(const std::list<T> &val, MessageParcel &parcel) 343 { 344 return ITypesUtil::MarshalToContainer(val, parcel); 345 } 346 347 template<class T> 348 bool ITypesUtil::Unmarshalling(std::list<T> &val, MessageParcel &parcel) 349 { 350 return ITypesUtil::UnmarshalFromContainer(val, parcel); 351 } 352 353 template<class T, typename std::enable_if<is_container<T>{}, int>::type> 354 bool ITypesUtil::MarshalToContainer(const T &val, MessageParcel &parcel) 355 { 356 if (val.size() > INT_MAX) { 357 return false; 358 } 359 360 if (!parcel.WriteInt32(static_cast<int32_t>(val.size()))) { 361 return false; 362 } 363 364 for (auto &v : val) { 365 if (!ITypesUtil::Marshalling(v, parcel)) { 366 return false; 367 } 368 } 369 return true; 370 } 371 372 template<class T, typename std::enable_if<is_container<T>{}, int>::type> 373 bool ITypesUtil::UnmarshalFromContainer(T &val, MessageParcel &parcel) 374 { 375 int32_t len = parcel.ReadInt32(); 376 if (len < 0) { 377 return false; 378 } 379 380 size_t readAbleSize = parcel.GetReadableBytes(); 381 size_t size = static_cast<size_t>(len); 382 if ((size > readAbleSize) || (size > val.max_size())) { 383 return false; 384 } 385 386 val.clear(); 387 for (size_t i = 0; i < size; i++) { 388 typename T::value_type value; 389 if (!ITypesUtil::Unmarshalling(value, parcel)) { 390 return false; 391 } 392 val.emplace_back(std::move(value)); 393 } 394 return true; 395 } 396 397 template<typename T> 398 bool ITypesUtil::MarshalToBuffer(const T &input, int size, MessageParcel &data) 399 { 400 if (size < 0 || static_cast<size_t>(size) > MAX_SIZE || !data.WriteInt32(size)) { 401 return false; 402 } 403 if (size == 0) { 404 return true; 405 } 406 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size); 407 if (buffer == nullptr) { 408 return false; 409 } 410 411 int leftSize = size; 412 uint8_t *cursor = buffer.get(); 413 if (!input.WriteToBuffer(cursor, leftSize)) { 414 return false; 415 } 416 return data.WriteRawData(buffer.get(), size); 417 } 418 419 template<typename T> 420 bool ITypesUtil::MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data) 421 { 422 if (size < 0 || static_cast<size_t>(size) > MAX_SIZE || input.size() > MAX_COUNT || !data.WriteInt32(size)) { 423 return false; 424 } 425 if (size == 0) { 426 return true; 427 } 428 if (!data.WriteInt32(input.size())) { 429 return false; 430 } 431 432 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size); 433 if (buffer == nullptr) { 434 return false; 435 } 436 437 uint8_t *cursor = buffer.get(); 438 int32_t left = size; 439 for (const auto &entry : input) { 440 if (!entry.WriteToBuffer(cursor, left)) { 441 return false; 442 } 443 } 444 return data.WriteRawData(buffer.get(), size); 445 } 446 447 template<typename T> 448 bool ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, T &output) 449 { 450 int32_t size = data.ReadInt32(); 451 if (size == 0) { 452 return true; 453 } 454 if (size < 0 || static_cast<size_t>(size) > MAX_SIZE) { 455 return false; 456 } 457 const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size)); 458 if (buffer == nullptr) { 459 return false; 460 } 461 return output.ReadFromBuffer(buffer, size); 462 } 463 464 template<typename T> 465 bool ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, std::vector<T> &output) 466 { 467 int size = data.ReadInt32(); 468 if (size == 0) { 469 return true; 470 } 471 if (size < 0 || static_cast<size_t>(size) > MAX_SIZE) { 472 return false; 473 } 474 int count = data.ReadInt32(); 475 const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size)); 476 if (count < 0 || static_cast<size_t>(count) > MAX_COUNT || buffer == nullptr) { 477 return false; 478 } 479 480 output.resize(count); 481 for (auto &entry : output) { 482 if (!entry.ReadFromBuffer(buffer, size)) { 483 output.clear(); 484 return false; 485 } 486 } 487 return true; 488 } 489 490 template<typename T, typename... Types> 491 bool ITypesUtil::Marshal(MessageParcel &parcel, const T &first, const Types &...others) 492 { 493 if (!ITypesUtil::Marshalling(first, parcel)) { 494 return false; 495 } 496 return ITypesUtil::Marshal(parcel, others...); 497 } 498 499 template<typename T, typename... Types> 500 bool ITypesUtil::Unmarshal(MessageParcel &parcel, T &first, Types &...others) 501 { 502 if (!ITypesUtil::Unmarshalling(first, parcel)) { 503 return false; 504 } 505 return ITypesUtil::Unmarshal(parcel, others...); 506 } 507 } // namespace OHOS 508 #endif