Line data Source code
1 : //===- StreamReader.h - Reads bytes and objects from a stream ---*- 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_STREAMREADER_H
11 : #define LLVM_DEBUGINFO_MSF_STREAMREADER_H
12 :
13 : #include "llvm/ADT/ArrayRef.h"
14 : #include "llvm/DebugInfo/Msf/MsfError.h"
15 : #include "llvm/DebugInfo/Msf/StreamArray.h"
16 : #include "llvm/DebugInfo/Msf/StreamInterface.h"
17 : #include "llvm/DebugInfo/Msf/StreamRef.h"
18 : #include "llvm/Support/Endian.h"
19 : #include "llvm/Support/Error.h"
20 :
21 : #include <string>
22 :
23 : namespace llvm {
24 : namespace msf {
25 :
26 : class StreamReader {
27 : public:
28 : StreamReader(ReadableStreamRef Stream);
29 :
30 : Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
31 : Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
32 : Error readInteger(uint16_t &Dest);
33 : Error readInteger(uint32_t &Dest);
34 : Error readZeroString(StringRef &Dest);
35 : Error readFixedString(StringRef &Dest, uint32_t Length);
36 : Error readStreamRef(ReadableStreamRef &Ref);
37 : Error readStreamRef(ReadableStreamRef &Ref, uint32_t Length);
38 :
39 3 : template <typename T> Error readEnum(T &Dest) {
40 : typename std::underlying_type<T>::type N;
41 9 : if (auto EC = readInteger(N))
42 0 : return EC;
43 3 : Dest = static_cast<T>(N);
44 : return Error::success();
45 : }
46 :
47 30417 : template <typename T> Error readObject(const T *&Dest) {
48 30417 : ArrayRef<uint8_t> Buffer;
49 91248 : if (auto EC = readBytes(Buffer, sizeof(T)))
50 6 : return EC;
51 30414 : Dest = reinterpret_cast<const T *>(Buffer.data());
52 : return Error::success();
53 : }
54 :
55 : template <typename T>
56 199 : Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
57 199 : ArrayRef<uint8_t> Bytes;
58 199 : if (NumElements == 0) {
59 16 : Array = ArrayRef<T>();
60 : return Error::success();
61 : }
62 :
63 183 : if (NumElements > UINT32_MAX / sizeof(T))
64 0 : return make_error<MsfError>(msf_error_code::insufficient_buffer);
65 :
66 549 : if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
67 0 : return EC;
68 183 : Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
69 : return Error::success();
70 : }
71 :
72 : template <typename T, typename U>
73 366 : Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
74 366 : ReadableStreamRef S;
75 1098 : if (auto EC = readStreamRef(S, Size))
76 0 : return EC;
77 366 : Array = VarStreamArray<T, U>(S, Array.getExtractor());
78 : return Error::success();
79 : }
80 :
81 : template <typename T>
82 55 : Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {
83 55 : if (NumItems == 0) {
84 4 : Array = FixedStreamArray<T>();
85 : return Error::success();
86 : }
87 51 : uint32_t Length = NumItems * sizeof(T);
88 51 : if (Length / sizeof(T) != NumItems)
89 0 : return make_error<MsfError>(msf_error_code::invalid_format);
90 51 : if (Offset + Length > Stream.getLength())
91 0 : return make_error<MsfError>(msf_error_code::insufficient_buffer);
92 51 : ReadableStreamRef View = Stream.slice(Offset, Length);
93 51 : Array = FixedStreamArray<T>(View);
94 51 : Offset += Length;
95 : return Error::success();
96 : }
97 :
98 4819 : void setOffset(uint32_t Off) { Offset = Off; }
99 : uint32_t getOffset() const { return Offset; }
100 802 : uint32_t getLength() const { return Stream.getLength(); }
101 457 : uint32_t bytesRemaining() const { return getLength() - getOffset(); }
102 :
103 : private:
104 : ReadableStreamRef Stream;
105 : uint32_t Offset;
106 : };
107 : } // namespace msf
108 : } // namespace llvm
109 :
110 : #endif // LLVM_DEBUGINFO_MSF_STREAMREADER_H
|