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_PARAM_ANNOTATIONS_DATA_ACCESSOR_H 17 #define LIBPANDAFILE_PARAM_ANNOTATIONS_DATA_ACCESSOR_H 18 19 #include "file.h" 20 #include "file_items.h" 21 #include "helpers.h" 22 23 namespace panda::panda_file { 24 class ParamAnnotationsDataAccessor { 25 public: 26 class AnnotationArray { 27 public: AnnotationArray(uint32_t count,Span<const uint8_t> offsets)28 AnnotationArray(uint32_t count, Span<const uint8_t> offsets) : count_(count), offsets_(offsets) {} 29 30 ~AnnotationArray() = default; 31 32 NO_COPY_SEMANTIC(AnnotationArray); 33 NO_MOVE_SEMANTIC(AnnotationArray); GetCount()34 uint32_t GetCount() const 35 { 36 return count_; 37 } 38 GetSize()39 uint32_t GetSize() const 40 { 41 return sizeof(uint32_t) + count_ * ID_SIZE; 42 } 43 44 template <class Callback> EnumerateAnnotations(const Callback & cb)45 void EnumerateAnnotations(const Callback &cb) 46 { 47 auto sp = offsets_; 48 for (size_t i = 0; i < count_; i++) { 49 File::EntityId id(helpers::Read<ID_SIZE>(&sp)); 50 cb(id); 51 } 52 } 53 54 private: 55 uint32_t count_; 56 Span<const uint8_t> offsets_; 57 }; 58 ParamAnnotationsDataAccessor(const File & panda_file,File::EntityId id)59 ParamAnnotationsDataAccessor(const File &panda_file, File::EntityId id) : panda_file_(panda_file), id_(id) 60 { 61 auto sp = panda_file_.GetSpanFromId(id); 62 count_ = helpers::Read<COUNT_SIZE>(&sp); 63 annotations_array_ = sp; 64 } 65 66 ~ParamAnnotationsDataAccessor() = default; 67 68 NO_COPY_SEMANTIC(ParamAnnotationsDataAccessor); 69 NO_MOVE_SEMANTIC(ParamAnnotationsDataAccessor); 70 71 template <class Callback> EnumerateAnnotationArrays(const Callback & cb)72 void EnumerateAnnotationArrays(const Callback &cb) 73 { 74 auto sp = annotations_array_; 75 size_t size = COUNT_SIZE; 76 77 for (size_t i = 0; i < count_; i++) { 78 auto count = helpers::Read<COUNT_SIZE>(&sp); 79 AnnotationArray array(count, sp); 80 sp = sp.SubSpan(count * ID_SIZE); 81 cb(array); 82 size += array.GetSize(); 83 } 84 85 size_ = size; 86 } 87 GetAnnotationArray(uint32_t index)88 AnnotationArray GetAnnotationArray(uint32_t index) 89 { 90 ASSERT(index < count_); 91 92 auto sp = annotations_array_; 93 for (uint32_t i = 0; i < count_; i++) { 94 auto count = helpers::Read<COUNT_SIZE>(&sp); 95 if (i == index) { 96 return AnnotationArray {count, sp}; 97 } 98 sp = sp.SubSpan(count * ID_SIZE); 99 } 100 UNREACHABLE(); 101 } 102 GetCount()103 uint32_t GetCount() const 104 { 105 return count_; 106 } 107 GetSize()108 size_t GetSize() 109 { 110 if (size_ == 0) { 111 SkipAnnotationArrays(); 112 } 113 114 return size_; 115 } 116 GetParamAnnotationsId()117 File::EntityId GetParamAnnotationsId() const 118 { 119 return id_; 120 } 121 122 private: 123 static constexpr size_t COUNT_SIZE = sizeof(uint32_t); 124 SkipAnnotationArrays()125 void SkipAnnotationArrays() 126 { 127 EnumerateAnnotationArrays([](const AnnotationArray & /* unused */) {}); 128 } 129 130 const File &panda_file_; 131 File::EntityId id_; 132 133 uint32_t count_; 134 Span<const uint8_t> annotations_array_ {nullptr, nullptr}; 135 136 size_t size_ {0}; 137 }; 138 139 } // namespace panda::panda_file 140 141 #endif // LIBPANDAFILE_PARAM_ANNOTATIONS_DATA_ACCESSOR_H 142