1 /** 2 * Copyright (c) 2021-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 LIBPANDAFILE_VALUE_H 17 #define LIBPANDAFILE_VALUE_H 18 19 #include <type_traits> 20 21 #include "file.h" 22 #include "helpers.h" 23 24 namespace panda::panda_file { 25 26 class ScalarValue { 27 public: ScalarValue(const File & panda_file,uint32_t value)28 ScalarValue(const File &panda_file, uint32_t value) : panda_file_(panda_file), value_(value) {} 29 30 ~ScalarValue() = default; 31 32 NO_COPY_SEMANTIC(ScalarValue); 33 NO_MOVE_SEMANTIC(ScalarValue); 34 35 template <class T> Get()36 T Get() const 37 { 38 static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, File::EntityId>); 39 40 if constexpr (std::is_same_v<T, float>) { // NOLINT 41 return bit_cast<float>(value_); 42 } 43 44 constexpr size_t T_SIZE = sizeof(T); 45 46 // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon) 47 if constexpr (T_SIZE <= sizeof(uint32_t)) { 48 return static_cast<T>(value_); 49 } 50 51 File::EntityId id(value_); 52 auto sp = panda_file_.GetSpanFromId(id); 53 auto res = helpers::Read<T_SIZE>(&sp); 54 55 if constexpr (std::is_floating_point_v<T>) { // NOLINT 56 return bit_cast<T>(res); 57 } 58 59 return static_cast<T>(res); 60 } 61 GetValue()62 uint32_t GetValue() const 63 { 64 return value_; 65 } 66 67 private: 68 const File &panda_file_; 69 uint32_t value_; 70 }; 71 72 class ArrayValue { 73 public: ArrayValue(const File & panda_file,File::EntityId id)74 ArrayValue(const File &panda_file, File::EntityId id) : panda_file_(panda_file), id_(id) 75 { 76 auto sp = panda_file_.GetSpanFromId(id_); 77 count_ = helpers::ReadULeb128(&sp); 78 data_ = sp; 79 } 80 81 ~ArrayValue() = default; 82 83 NO_COPY_SEMANTIC(ArrayValue); 84 NO_MOVE_SEMANTIC(ArrayValue); 85 86 template <class T> Get(size_t idx)87 T Get(size_t idx) const 88 { 89 static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, File::EntityId>); 90 91 constexpr size_t T_SIZE = sizeof(T); 92 93 auto sp = data_.SubSpan(T_SIZE * idx); 94 auto res = helpers::Read<T_SIZE>(&sp); 95 96 if constexpr (std::is_floating_point_v<T>) { // NOLINT 97 return bit_cast<T>(res); 98 } 99 100 return static_cast<T>(res); 101 } 102 GetCount()103 uint32_t GetCount() const 104 { 105 return count_; 106 } 107 GetId()108 File::EntityId GetId() const 109 { 110 return id_; 111 } 112 113 private: 114 static constexpr size_t COUNT_SIZE = sizeof(uint32_t); 115 116 const File &panda_file_; 117 File::EntityId id_; 118 uint32_t count_; 119 Span<const uint8_t> data_ {nullptr, nullptr}; 120 }; 121 122 } // namespace panda::panda_file 123 124 #endif // LIBPANDAFILE_VALUE_H 125