LLVM  4.0.0
SequencedItemStream.h
Go to the documentation of this file.
1 //===- SequencedItemStream.h ------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
11 #define LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
12 
13 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/Support/Error.h"
17 #include <cstddef>
18 #include <cstdint>
19 
20 namespace llvm {
21 namespace msf {
22 
23 template <typename T> struct SequencedItemTraits {
24  static size_t length(const T &Item) = delete;
25  static ArrayRef<uint8_t> bytes(const T &Item) = delete;
26 };
27 
28 /// SequencedItemStream represents a sequence of objects stored in a
29 /// standard container but for which it is useful to view as a stream of
30 /// contiguous bytes. An example of this might be if you have a std::vector
31 /// of TPI records, where each record contains a byte sequence that
32 /// represents that one record serialized, but where each consecutive item
33 /// might not be allocated immediately after the previous item. Using a
34 /// SequencedItemStream, we can adapt the VarStreamArray class to trivially
35 /// extract one item at a time, allowing the data to be used anywhere a
36 /// VarStreamArray could be used.
37 template <typename T, typename Traits = SequencedItemTraits<T>>
39 public:
40  SequencedItemStream() = default;
41 
43  ArrayRef<uint8_t> &Buffer) const override {
44  auto ExpectedIndex = translateOffsetIndex(Offset);
45  if (!ExpectedIndex)
46  return ExpectedIndex.takeError();
47  const auto &Item = Items[*ExpectedIndex];
48  if (Size > Traits::length(Item))
49  return make_error<MSFError>(msf_error_code::insufficient_buffer);
50  Buffer = Traits::bytes(Item).take_front(Size);
51  return Error::success();
52  }
53 
55  ArrayRef<uint8_t> &Buffer) const override {
56  auto ExpectedIndex = translateOffsetIndex(Offset);
57  if (!ExpectedIndex)
58  return ExpectedIndex.takeError();
59  Buffer = Traits::bytes(Items[*ExpectedIndex]);
60  return Error::success();
61  }
62 
63  void setItems(ArrayRef<T> ItemArray) { Items = ItemArray; }
64 
65  uint32_t getLength() const override {
66  uint32_t Size = 0;
67  for (const auto &Item : Items)
68  Size += Traits::length(Item);
69  return Size;
70  }
71 
72 private:
73  Expected<uint32_t> translateOffsetIndex(uint32_t Offset) const {
74  uint32_t CurrentOffset = 0;
75  uint32_t CurrentIndex = 0;
76  for (const auto &Item : Items) {
77  if (CurrentOffset >= Offset)
78  break;
79  CurrentOffset += Traits::length(Item);
80  ++CurrentIndex;
81  }
82  if (CurrentOffset != Offset)
83  return make_error<MSFError>(msf_error_code::insufficient_buffer);
84  return CurrentIndex;
85  }
86 
87  ArrayRef<T> Items;
88 };
89 
90 } // end namespace msf
91 } // end namespace llvm
92 
93 #endif // LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H
SequencedItemStream represents a sequence of objects stored in a standard container but for which it ...
Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef< uint8_t > &Buffer) const override
uint32_t getLength() const override
static ArrayRef< uint8_t > bytes(const T &Item)=delete
Tagged union holding either a T or a Error.
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
Definition: ArrayRef.h:204
static size_t length(const T &Item)=delete
Error readLongestContiguousChunk(uint32_t Offset, ArrayRef< uint8_t > &Buffer) const override
uint32_t Offset
static ErrorSuccess success()
Create a success value.
void setItems(ArrayRef< T > ItemArray)
Lightweight error class with error context and mandatory checking.