File indexing completed on 2026-05-10 08:44:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #ifndef LLVM_SUPPORT_BINARYSTREAMARRAY_H
0023 #define LLVM_SUPPORT_BINARYSTREAMARRAY_H
0024
0025 #include "llvm/ADT/ArrayRef.h"
0026 #include "llvm/ADT/iterator.h"
0027 #include "llvm/Support/Alignment.h"
0028 #include "llvm/Support/BinaryStreamRef.h"
0029 #include "llvm/Support/Error.h"
0030 #include <cassert>
0031 #include <cstdint>
0032
0033 namespace llvm {
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 template <typename T> struct VarStreamArrayExtractor {
0048
0049
0050 Error operator()(BinaryStreamRef Stream, uint32_t &Len,
0051 T &Item) const = delete;
0052 };
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 template <typename ValueType, typename Extractor> class VarStreamArrayIterator;
0089
0090 template <typename ValueType,
0091 typename Extractor = VarStreamArrayExtractor<ValueType>>
0092 class VarStreamArray {
0093 friend class VarStreamArrayIterator<ValueType, Extractor>;
0094
0095 public:
0096 typedef VarStreamArrayIterator<ValueType, Extractor> Iterator;
0097
0098 VarStreamArray() = default;
0099
0100 explicit VarStreamArray(const Extractor &E) : E(E) {}
0101
0102 explicit VarStreamArray(BinaryStreamRef Stream, uint32_t Skew = 0)
0103 : Stream(Stream), Skew(Skew) {}
0104
0105 VarStreamArray(BinaryStreamRef Stream, const Extractor &E, uint32_t Skew = 0)
0106 : Stream(Stream), E(E), Skew(Skew) {}
0107
0108 Iterator begin(bool *HadError = nullptr) const {
0109 return Iterator(*this, E, Skew, nullptr);
0110 }
0111
0112 bool valid() const { return Stream.valid(); }
0113
0114 bool isOffsetValid(uint32_t Offset) const { return at(Offset) != end(); }
0115
0116 uint32_t skew() const { return Skew; }
0117 Iterator end() const { return Iterator(E); }
0118
0119 bool empty() const { return Stream.getLength() == 0; }
0120
0121 VarStreamArray<ValueType, Extractor> substream(uint32_t Begin,
0122 uint32_t End) const {
0123 assert(Begin >= Skew);
0124
0125
0126 BinaryStreamRef NewStream = Stream.slice(0, End);
0127 return {NewStream, E, Begin};
0128 }
0129
0130
0131
0132
0133
0134 Iterator at(uint32_t Offset) const {
0135 return Iterator(*this, E, Offset, nullptr);
0136 }
0137
0138 const Extractor &getExtractor() const { return E; }
0139 Extractor &getExtractor() { return E; }
0140
0141 BinaryStreamRef getUnderlyingStream() const { return Stream; }
0142 void setUnderlyingStream(BinaryStreamRef NewStream, uint32_t NewSkew = 0) {
0143 Stream = NewStream;
0144 Skew = NewSkew;
0145 }
0146
0147 void drop_front() { Skew += begin()->length(); }
0148
0149 private:
0150 BinaryStreamRef Stream;
0151 Extractor E;
0152 uint32_t Skew = 0;
0153 };
0154
0155 template <typename ValueType, typename Extractor>
0156 class VarStreamArrayIterator
0157 : public iterator_facade_base<VarStreamArrayIterator<ValueType, Extractor>,
0158 std::forward_iterator_tag, const ValueType> {
0159 typedef VarStreamArrayIterator<ValueType, Extractor> IterType;
0160 typedef VarStreamArray<ValueType, Extractor> ArrayType;
0161
0162 public:
0163 VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
0164 uint32_t Offset, bool *HadError)
0165 : IterRef(Array.Stream.drop_front(Offset)), Extract(E),
0166 Array(&Array), AbsOffset(Offset), HadError(HadError) {
0167 if (IterRef.getLength() == 0)
0168 moveToEnd();
0169 else {
0170 auto EC = Extract(IterRef, ThisLen, ThisValue);
0171 if (EC) {
0172 consumeError(std::move(EC));
0173 markError();
0174 }
0175 }
0176 }
0177
0178 VarStreamArrayIterator() = default;
0179 explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {}
0180 ~VarStreamArrayIterator() = default;
0181
0182 bool operator==(const IterType &R) const {
0183 if (Array && R.Array) {
0184
0185 assert(Array == R.Array);
0186 return IterRef == R.IterRef;
0187 }
0188
0189
0190 if (!Array && !R.Array)
0191 return true;
0192
0193
0194 return false;
0195 }
0196
0197 const ValueType &operator*() const {
0198 assert(Array && !HasError);
0199 return ThisValue;
0200 }
0201
0202 IterType &operator+=(unsigned N) {
0203 for (unsigned I = 0; I < N; ++I) {
0204
0205
0206 AbsOffset += ThisLen;
0207 IterRef = IterRef.drop_front(ThisLen);
0208 if (IterRef.getLength() == 0) {
0209
0210
0211 moveToEnd();
0212 } else {
0213
0214 auto EC = Extract(IterRef, ThisLen, ThisValue);
0215 if (EC) {
0216 consumeError(std::move(EC));
0217 markError();
0218 } else if (ThisLen == 0) {
0219
0220 moveToEnd();
0221 }
0222 }
0223 }
0224 return *this;
0225 }
0226
0227 uint32_t offset() const { return AbsOffset; }
0228 uint32_t getRecordLength() const { return ThisLen; }
0229
0230 private:
0231 void moveToEnd() {
0232 Array = nullptr;
0233 ThisLen = 0;
0234 }
0235 void markError() {
0236 moveToEnd();
0237 HasError = true;
0238 if (HadError != nullptr)
0239 *HadError = true;
0240 }
0241
0242 ValueType ThisValue;
0243 BinaryStreamRef IterRef;
0244 Extractor Extract;
0245 const ArrayType *Array{nullptr};
0246 uint32_t ThisLen{0};
0247 uint32_t AbsOffset{0};
0248 bool HasError{false};
0249 bool *HadError{nullptr};
0250 };
0251
0252 template <typename T> class FixedStreamArrayIterator;
0253
0254
0255
0256
0257
0258
0259 template <typename T> class FixedStreamArray {
0260 friend class FixedStreamArrayIterator<T>;
0261
0262 public:
0263 typedef FixedStreamArrayIterator<T> Iterator;
0264
0265 FixedStreamArray() = default;
0266 explicit FixedStreamArray(BinaryStreamRef Stream) : Stream(Stream) {
0267 assert(Stream.getLength() % sizeof(T) == 0);
0268 }
0269
0270 bool operator==(const FixedStreamArray<T> &Other) const {
0271 return Stream == Other.Stream;
0272 }
0273
0274 bool operator!=(const FixedStreamArray<T> &Other) const {
0275 return !(*this == Other);
0276 }
0277
0278 FixedStreamArray(const FixedStreamArray &) = default;
0279 FixedStreamArray &operator=(const FixedStreamArray &) = default;
0280
0281 const T &operator[](uint32_t Index) const {
0282 assert(Index < size());
0283 uint32_t Off = Index * sizeof(T);
0284 ArrayRef<uint8_t> Data;
0285 if (auto EC = Stream.readBytes(Off, sizeof(T), Data)) {
0286 assert(false && "Unexpected failure reading from stream");
0287
0288
0289 consumeError(std::move(EC));
0290 }
0291 assert(isAddrAligned(Align::Of<T>(), Data.data()));
0292 return *reinterpret_cast<const T *>(Data.data());
0293 }
0294
0295 uint32_t size() const { return Stream.getLength() / sizeof(T); }
0296
0297 bool empty() const { return size() == 0; }
0298
0299 FixedStreamArrayIterator<T> begin() const {
0300 return FixedStreamArrayIterator<T>(*this, 0);
0301 }
0302
0303 FixedStreamArrayIterator<T> end() const {
0304 return FixedStreamArrayIterator<T>(*this, size());
0305 }
0306
0307 const T &front() const { return *begin(); }
0308 const T &back() const {
0309 FixedStreamArrayIterator<T> I = end();
0310 return *(--I);
0311 }
0312
0313 BinaryStreamRef getUnderlyingStream() const { return Stream; }
0314
0315 private:
0316 BinaryStreamRef Stream;
0317 };
0318
0319 template <typename T>
0320 class FixedStreamArrayIterator
0321 : public iterator_facade_base<FixedStreamArrayIterator<T>,
0322 std::random_access_iterator_tag, const T> {
0323
0324 public:
0325 FixedStreamArrayIterator(const FixedStreamArray<T> &Array, uint32_t Index)
0326 : Array(Array), Index(Index) {}
0327
0328 FixedStreamArrayIterator(const FixedStreamArrayIterator<T> &Other)
0329 : Array(Other.Array), Index(Other.Index) {}
0330 FixedStreamArrayIterator<T> &
0331 operator=(const FixedStreamArrayIterator<T> &Other) {
0332 Array = Other.Array;
0333 Index = Other.Index;
0334 return *this;
0335 }
0336
0337 const T &operator*() const { return Array[Index]; }
0338 const T &operator*() { return Array[Index]; }
0339
0340 bool operator==(const FixedStreamArrayIterator<T> &R) const {
0341 assert(Array == R.Array);
0342 return (Index == R.Index) && (Array == R.Array);
0343 }
0344
0345 FixedStreamArrayIterator<T> &operator+=(std::ptrdiff_t N) {
0346 Index += N;
0347 return *this;
0348 }
0349
0350 FixedStreamArrayIterator<T> &operator-=(std::ptrdiff_t N) {
0351 assert(std::ptrdiff_t(Index) >= N);
0352 Index -= N;
0353 return *this;
0354 }
0355
0356 std::ptrdiff_t operator-(const FixedStreamArrayIterator<T> &R) const {
0357 assert(Array == R.Array);
0358 assert(Index >= R.Index);
0359 return Index - R.Index;
0360 }
0361
0362 bool operator<(const FixedStreamArrayIterator<T> &RHS) const {
0363 assert(Array == RHS.Array);
0364 return Index < RHS.Index;
0365 }
0366
0367 private:
0368 FixedStreamArray<T> Array;
0369 uint32_t Index;
0370 };
0371
0372 }
0373
0374 #endif