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