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::u16string &input, MessageParcel &data) 142 { 143 return data.WriteString16(input); 144 } 145 146 static inline bool Unmarshalling(std::u16string &output, MessageParcel &data) 147 { 148 return data.ReadString16(output); 149 } 150 151 static inline bool Marshalling(const std::vector<uint8_t> &input, MessageParcel &data) 152 { 153 return data.WriteUInt8Vector(input); 154 } 155 156 static inline bool Unmarshalling(std::vector<uint8_t> &output, MessageParcel &data) 157 { 158 return data.ReadUInt8Vector(&output); 159 } 160 161 static inline bool Marshalling(const sptr<IRemoteObject> &input, MessageParcel &data) 162 { 163 return data.WriteRemoteObject(input); 164 } 165 166 static inline bool Unmarshalling(sptr<IRemoteObject> &output, MessageParcel &data) 167 { 168 output = data.ReadRemoteObject(); 169 return true; 170 } 171 172 static inline bool Marshalling(IRemoteObject *input, MessageParcel &data) 173 { 174 return data.WriteRemoteObject(input); 175 } 176 177 template<typename _OutTp> 178 bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data); 179 template<typename _OutTp, typename _First, typename... _Rest> 180 bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data); 181 182 template<typename _InTp> 183 bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data); 184 template<typename _InTp, typename _First, typename... _Rest> 185 bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data); 186 187 template<typename... _Types> 188 bool Marshalling(const std::variant<_Types...> &input, MessageParcel &data); 189 template<typename... _Types> 190 bool Unmarshalling(std::variant<_Types...> &output, MessageParcel &data); 191 192 template<class K, class V> 193 bool Marshalling(const std::map<K, V> &result, MessageParcel &parcel); 194 template<class K, class V> 195 bool Unmarshalling(std::map<K, V> &val, MessageParcel &parcel); 196 197 template<class F, class S, class T> 198 bool Marshalling(const std::tuple<F, S, T> &result, MessageParcel &parcel); 199 template<class F, class S, class T> 200 bool Unmarshalling(std::tuple<F, S, T> &val, MessageParcel &parcel); 201 202 template<class F, class S> 203 bool Marshalling(const std::pair<F, S> &result, MessageParcel &parcel); 204 template<class F, class S> 205 bool Unmarshalling(std::pair<F, S> &val, MessageParcel &parcel); 206 207 template<class T> 208 bool Marshalling(const std::vector<T> &val, MessageParcel &parcel); 209 template<class T> 210 bool Unmarshalling(std::vector<T> &val, MessageParcel &parcel); 211 212 template<class T> 213 bool Marshalling(const std::list<T> &val, MessageParcel &parcel); 214 template<class T> 215 bool Unmarshalling(std::list<T> &val, MessageParcel &parcel); 216 217 template<typename T, typename std::enable_if<std::is_pointer<T>{}, int>::type = 0> 218 bool Marshalling(const T &input, MessageParcel &data) = delete; 219 template<typename T, typename std::enable_if<std::is_pointer<T>{}, int>::type = 0> 220 bool Unmarshalling(T &output, MessageParcel &data) = delete; 221 222 template<typename T> 223 bool Marshalling(const T &input, MessageParcel &data); 224 template<typename T> 225 bool Unmarshalling(T &output, MessageParcel &data); 226 227 template<class T, typename std::enable_if<is_container<T>{}, int>::type = 0> 228 bool MarshalToContainer(const T &val, MessageParcel &parcel); 229 template<class T, typename std::enable_if<is_container<T>{}, int>::type = 0> 230 bool UnmarshalFromContainer(T &val, MessageParcel &parcel); 231 232 template<typename T> 233 bool MarshalToBuffer(const T &input, int size, MessageParcel &data); 234 template<typename T> 235 bool MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data); 236 237 template<typename T> 238 bool UnmarshalFromBuffer(MessageParcel &data, T &output); 239 template<typename T> 240 bool UnmarshalFromBuffer(MessageParcel &data, std::vector<T> &output); 241 242 template<typename T, typename... Types> 243 bool Marshal(MessageParcel &parcel, const T &first, const Types &...others); 244 245 template<typename T, typename... Types> 246 bool Unmarshal(MessageParcel &parcel, T &first, Types &...others); 247 } // namespace ITypesUtil 248 249 template<typename _OutTp> 250 bool ITypesUtil::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data) 251 { 252 return false; 253 } 254 255 template<typename _OutTp, typename _First, typename... _Rest> 256 bool ITypesUtil::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data) 257 { 258 if (step == index) { 259 _First value{}; 260 auto success = ITypesUtil::Unmarshalling(value, data); 261 output = value; 262 return success; 263 } 264 return ITypesUtil::ReadVariant<_OutTp, _Rest...>(step + 1, index, output, data); 265 } 266 267 template<typename _InTp> 268 bool ITypesUtil::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data) 269 { 270 return false; 271 } 272 273 template<typename _InTp, typename _First, typename... _Rest> 274 bool ITypesUtil::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data) 275 { 276 if (step == input.index()) { 277 return ITypesUtil::Marshalling(std::get<_First>(input), data); 278 } 279 return ITypesUtil::WriteVariant<_InTp, _Rest...>(step + 1, input, data); 280 } 281 282 template<typename... _Types> 283 bool ITypesUtil::Marshalling(const std::variant<_Types...> &input, MessageParcel &data) 284 { 285 uint32_t index = static_cast<uint32_t>(input.index()); 286 if (!data.WriteUint32(index)) { 287 return false; 288 } 289 290 return ITypesUtil::WriteVariant<decltype(input), _Types...>(0, input, data); 291 } 292 293 template<typename... _Types> 294 bool ITypesUtil::Unmarshalling(std::variant<_Types...> &output, MessageParcel &data) 295 { 296 uint32_t index = data.ReadUint32(); 297 if (index >= sizeof...(_Types)) { 298 return false; 299 } 300 301 return ITypesUtil::ReadVariant<decltype(output), _Types...>(0, index, output, data); 302 } 303 304 template<class K, class V> 305 bool ITypesUtil::Marshalling(const std::map<K, V> &result, MessageParcel &parcel) 306 { 307 if (!parcel.WriteInt32(static_cast<int32_t>(result.size()))) { 308 return false; 309 } 310 for (const auto &entry : result) { 311 if (!ITypesUtil::Marshalling(entry.first, parcel)) { 312 return false; 313 } 314 if (!ITypesUtil::Marshalling(entry.second, parcel)) { 315 return false; 316 } 317 } 318 return true; 319 } 320 321 template<class K, class V> 322 bool ITypesUtil::Unmarshalling(std::map<K, V> &val, MessageParcel &parcel) 323 { 324 int32_t size = 0; 325 if (!parcel.ReadInt32(size)) { 326 return false; 327 } 328 if (size < 0) { 329 return false; 330 } 331 332 size_t readAbleSize = parcel.GetReadableBytes(); 333 if ((static_cast<size_t>(size) > readAbleSize) || static_cast<size_t>(size) > val.max_size()) { 334 return false; 335 } 336 337 for (int32_t i = 0; i < size; i++) { 338 K key; 339 if (!ITypesUtil::Unmarshalling(key, parcel)) { 340 return false; 341 } 342 if (!ITypesUtil::Unmarshalling(val[key], parcel)) { 343 return false; 344 } 345 } 346 return true; 347 } 348 349 template<class F, class S, class T> 350 bool ITypesUtil::Marshalling(const std::tuple<F, S, T> &result, MessageParcel &parcel) 351 { 352 if (!ITypesUtil::Marshalling(std::get<0>(result), parcel)) { 353 return false; 354 } 355 if (!ITypesUtil::Marshalling(std::get<1>(result), parcel)) { 356 return false; 357 } 358 if (!ITypesUtil::Marshalling(std::get<2>(result), parcel)) { // 2 is the last element in tuple 359 return false; 360 } 361 return true; 362 } 363 364 template<class F, class S, class T> 365 bool ITypesUtil::Unmarshalling(std::tuple<F, S, T> &val, MessageParcel &parcel) 366 { 367 F first; 368 if (!ITypesUtil::Unmarshalling(first, parcel)) { 369 return false; 370 } 371 S second; 372 if (!ITypesUtil::Unmarshalling(second, parcel)) { 373 return false; 374 } 375 T third; 376 if (!ITypesUtil::Unmarshalling(third, parcel)) { 377 return false; 378 } 379 val = { first, second, third }; 380 return true; 381 } 382 383 template<class F, class S> 384 bool ITypesUtil::Marshalling(const std::pair<F, S> &result, MessageParcel &parcel) 385 { 386 if (!ITypesUtil::Marshalling(result.first, parcel)) { 387 return false; 388 } 389 if (!ITypesUtil::Marshalling(result.second, parcel)) { 390 return false; 391 } 392 return true; 393 } 394 395 template<class F, class S> 396 bool ITypesUtil::Unmarshalling(std::pair<F, S> &val, MessageParcel &parcel) 397 { 398 F first; 399 if (!ITypesUtil::Unmarshalling(first, parcel)) { 400 return false; 401 } 402 S second; 403 if (!ITypesUtil::Unmarshalling(second, parcel)) { 404 return false; 405 } 406 val = { first, second }; 407 return true; 408 } 409 410 template<class T> 411 bool ITypesUtil::Marshalling(const std::vector<T> &val, MessageParcel &parcel) 412 { 413 return ITypesUtil::MarshalToContainer(val, parcel); 414 } 415 416 template<class T> 417 bool ITypesUtil::Unmarshalling(std::vector<T> &val, MessageParcel &parcel) 418 { 419 return ITypesUtil::UnmarshalFromContainer(val, parcel); 420 } 421 422 template<class T> 423 bool ITypesUtil::Marshalling(const std::list<T> &val, MessageParcel &parcel) 424 { 425 return ITypesUtil::MarshalToContainer(val, parcel); 426 } 427 428 template<class T> 429 bool ITypesUtil::Unmarshalling(std::list<T> &val, MessageParcel &parcel) 430 { 431 return ITypesUtil::UnmarshalFromContainer(val, parcel); 432 } 433 434 template<class T, typename std::enable_if<is_container<T>{}, int>::type> 435 bool ITypesUtil::MarshalToContainer(const T &val, MessageParcel &parcel) 436 { 437 if (val.size() > INT_MAX) { 438 return false; 439 } 440 441 if (!parcel.WriteInt32(static_cast<int32_t>(val.size()))) { 442 return false; 443 } 444 445 for (auto &v : val) { 446 if (!ITypesUtil::Marshalling(v, parcel)) { 447 return false; 448 } 449 } 450 return true; 451 } 452 453 template<class T, typename std::enable_if<is_container<T>{}, int>::type> 454 bool ITypesUtil::UnmarshalFromContainer(T &val, MessageParcel &parcel) 455 { 456 int32_t len = parcel.ReadInt32(); 457 if (len < 0) { 458 return false; 459 } 460 461 size_t readAbleSize = parcel.GetReadableBytes(); 462 size_t size = static_cast<size_t>(len); 463 if ((size > readAbleSize) || (size > val.max_size())) { 464 return false; 465 } 466 467 val.clear(); 468 for (size_t i = 0; i < size; i++) { 469 typename T::value_type value; 470 if (!ITypesUtil::Unmarshalling(value, parcel)) { 471 return false; 472 } 473 val.emplace_back(std::move(value)); 474 } 475 return true; 476 } 477 478 template<typename T> 479 bool ITypesUtil::MarshalToBuffer(const T &input, int size, MessageParcel &data) 480 { 481 if (size < 0 || static_cast<size_t>(size) > MAX_SIZE || !data.WriteInt32(size)) { 482 return false; 483 } 484 if (size == 0) { 485 return true; 486 } 487 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size); 488 if (buffer == nullptr) { 489 return false; 490 } 491 492 int leftSize = size; 493 uint8_t *cursor = buffer.get(); 494 if (!input.WriteToBuffer(cursor, leftSize)) { 495 return false; 496 } 497 return data.WriteRawData(buffer.get(), size); 498 } 499 500 template<typename T> 501 bool ITypesUtil::MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data) 502 { 503 if (size < 0 || static_cast<size_t>(size) > MAX_SIZE || input.size() > MAX_COUNT || !data.WriteInt32(size)) { 504 return false; 505 } 506 if (size == 0) { 507 return true; 508 } 509 if (!data.WriteInt32(input.size())) { 510 return false; 511 } 512 513 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size); 514 if (buffer == nullptr) { 515 return false; 516 } 517 518 uint8_t *cursor = buffer.get(); 519 int32_t left = size; 520 for (const auto &entry : input) { 521 if (!entry.WriteToBuffer(cursor, left)) { 522 return false; 523 } 524 } 525 return data.WriteRawData(buffer.get(), size); 526 } 527 528 template<typename T> 529 bool ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, T &output) 530 { 531 int32_t size = data.ReadInt32(); 532 if (size == 0) { 533 return true; 534 } 535 if (size < 0 || static_cast<size_t>(size) > MAX_SIZE) { 536 return false; 537 } 538 const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size)); 539 if (buffer == nullptr) { 540 return false; 541 } 542 return output.ReadFromBuffer(buffer, size); 543 } 544 545 template<typename T> 546 bool ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, std::vector<T> &output) 547 { 548 int size = data.ReadInt32(); 549 if (size == 0) { 550 return true; 551 } 552 if (size < 0 || static_cast<size_t>(size) > MAX_SIZE) { 553 return false; 554 } 555 int count = data.ReadInt32(); 556 const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size)); 557 if (count < 0 || static_cast<size_t>(count) > MAX_COUNT || buffer == nullptr) { 558 return false; 559 } 560 561 output.resize(count); 562 for (auto &entry : output) { 563 if (!entry.ReadFromBuffer(buffer, size)) { 564 output.clear(); 565 return false; 566 } 567 } 568 return true; 569 } 570 571 template<typename T, typename... Types> 572 bool ITypesUtil::Marshal(MessageParcel &parcel, const T &first, const Types &...others) 573 { 574 if (!ITypesUtil::Marshalling(first, parcel)) { 575 return false; 576 } 577 return ITypesUtil::Marshal(parcel, others...); 578 } 579 580 template<typename T, typename... Types> 581 bool ITypesUtil::Unmarshal(MessageParcel &parcel, T &first, Types &...others) 582 { 583 if (!ITypesUtil::Unmarshalling(first, parcel)) { 584 return false; 585 } 586 return ITypesUtil::Unmarshal(parcel, others...); 587 } 588 } // namespace OHOS 589 #endif