• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 & pandaFile,uint32_t value)28      ScalarValue(const File &pandaFile, uint32_t value) : pandaFile_(pandaFile), 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 = pandaFile_.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 &pandaFile_;
69      uint32_t value_;
70  };
71  
72  class ArrayValue {
73  public:
ArrayValue(const File & pandaFile,File::EntityId id)74      ArrayValue(const File &pandaFile, File::EntityId id) : pandaFile_(pandaFile), id_(id)
75      {
76          auto sp = pandaFile_.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 &pandaFile_;
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