Mercurial > hg > CbC > CbC_llvm
comparison include/llvm/Support/BinaryStreamWriter.h @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | |
children | 3a76565eade5 |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
1 //===- BinaryStreamWriter.h - Writes objects to a BinaryStream ---*- 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_SUPPORT_BINARYSTREAMWRITER_H | |
11 #define LLVM_SUPPORT_BINARYSTREAMWRITER_H | |
12 | |
13 #include "llvm/ADT/ArrayRef.h" | |
14 #include "llvm/ADT/STLExtras.h" | |
15 #include "llvm/ADT/StringRef.h" | |
16 #include "llvm/Support/BinaryStreamArray.h" | |
17 #include "llvm/Support/BinaryStreamError.h" | |
18 #include "llvm/Support/BinaryStreamRef.h" | |
19 #include "llvm/Support/Endian.h" | |
20 #include "llvm/Support/Error.h" | |
21 #include <cstdint> | |
22 #include <type_traits> | |
23 #include <utility> | |
24 | |
25 namespace llvm { | |
26 | |
27 /// \brief Provides write only access to a subclass of `WritableBinaryStream`. | |
28 /// Provides bounds checking and helpers for writing certain common data types | |
29 /// such as null-terminated strings, integers in various flavors of endianness, | |
30 /// etc. Can be subclassed to provide reading and writing of custom datatypes, | |
31 /// although no methods are overridable. | |
32 class BinaryStreamWriter { | |
33 public: | |
34 BinaryStreamWriter() = default; | |
35 explicit BinaryStreamWriter(WritableBinaryStreamRef Ref); | |
36 explicit BinaryStreamWriter(WritableBinaryStream &Stream); | |
37 explicit BinaryStreamWriter(MutableArrayRef<uint8_t> Data, | |
38 llvm::support::endianness Endian); | |
39 | |
40 BinaryStreamWriter(const BinaryStreamWriter &Other) | |
41 : Stream(Other.Stream), Offset(Other.Offset) {} | |
42 | |
43 BinaryStreamWriter &operator=(const BinaryStreamWriter &Other) { | |
44 Stream = Other.Stream; | |
45 Offset = Other.Offset; | |
46 return *this; | |
47 } | |
48 | |
49 virtual ~BinaryStreamWriter() {} | |
50 | |
51 /// Write the bytes specified in \p Buffer to the underlying stream. | |
52 /// On success, updates the offset so that subsequent writes will occur | |
53 /// at the next unwritten position. | |
54 /// | |
55 /// \returns a success error code if the data was successfully written, | |
56 /// otherwise returns an appropriate error code. | |
57 Error writeBytes(ArrayRef<uint8_t> Buffer); | |
58 | |
59 /// Write the the integer \p Value to the underlying stream in the | |
60 /// specified endianness. On success, updates the offset so that | |
61 /// subsequent writes occur at the next unwritten position. | |
62 /// | |
63 /// \returns a success error code if the data was successfully written, | |
64 /// otherwise returns an appropriate error code. | |
65 template <typename T> Error writeInteger(T Value) { | |
66 static_assert(std::is_integral<T>::value, | |
67 "Cannot call writeInteger with non-integral value!"); | |
68 uint8_t Buffer[sizeof(T)]; | |
69 llvm::support::endian::write<T, llvm::support::unaligned>( | |
70 Buffer, Value, Stream.getEndian()); | |
71 return writeBytes(Buffer); | |
72 } | |
73 | |
74 /// Similar to writeInteger | |
75 template <typename T> Error writeEnum(T Num) { | |
76 static_assert(std::is_enum<T>::value, | |
77 "Cannot call writeEnum with non-Enum type"); | |
78 | |
79 using U = typename std::underlying_type<T>::type; | |
80 return writeInteger<U>(static_cast<U>(Num)); | |
81 } | |
82 | |
83 /// Write the the string \p Str to the underlying stream followed by a null | |
84 /// terminator. On success, updates the offset so that subsequent writes | |
85 /// occur at the next unwritten position. \p Str need not be null terminated | |
86 /// on input. | |
87 /// | |
88 /// \returns a success error code if the data was successfully written, | |
89 /// otherwise returns an appropriate error code. | |
90 Error writeCString(StringRef Str); | |
91 | |
92 /// Write the the string \p Str to the underlying stream without a null | |
93 /// terminator. On success, updates the offset so that subsequent writes | |
94 /// occur at the next unwritten position. | |
95 /// | |
96 /// \returns a success error code if the data was successfully written, | |
97 /// otherwise returns an appropriate error code. | |
98 Error writeFixedString(StringRef Str); | |
99 | |
100 /// Efficiently reads all data from \p Ref, and writes it to this stream. | |
101 /// This operation will not invoke any copies of the source data, regardless | |
102 /// of the source stream's implementation. | |
103 /// | |
104 /// \returns a success error code if the data was successfully written, | |
105 /// otherwise returns an appropriate error code. | |
106 Error writeStreamRef(BinaryStreamRef Ref); | |
107 | |
108 /// Efficiently reads \p Size bytes from \p Ref, and writes it to this stream. | |
109 /// This operation will not invoke any copies of the source data, regardless | |
110 /// of the source stream's implementation. | |
111 /// | |
112 /// \returns a success error code if the data was successfully written, | |
113 /// otherwise returns an appropriate error code. | |
114 Error writeStreamRef(BinaryStreamRef Ref, uint32_t Size); | |
115 | |
116 /// Writes the object \p Obj to the underlying stream, as if by using memcpy. | |
117 /// It is up to the caller to ensure that type of \p Obj can be safely copied | |
118 /// in this fashion, as no checks are made to ensure that this is safe. | |
119 /// | |
120 /// \returns a success error code if the data was successfully written, | |
121 /// otherwise returns an appropriate error code. | |
122 template <typename T> Error writeObject(const T &Obj) { | |
123 static_assert(!std::is_pointer<T>::value, | |
124 "writeObject should not be used with pointers, to write " | |
125 "the pointed-to value dereference the pointer before calling " | |
126 "writeObject"); | |
127 return writeBytes( | |
128 ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T))); | |
129 } | |
130 | |
131 /// Writes an array of objects of type T to the underlying stream, as if by | |
132 /// using memcpy. It is up to the caller to ensure that type of \p Obj can | |
133 /// be safely copied in this fashion, as no checks are made to ensure that | |
134 /// this is safe. | |
135 /// | |
136 /// \returns a success error code if the data was successfully written, | |
137 /// otherwise returns an appropriate error code. | |
138 template <typename T> Error writeArray(ArrayRef<T> Array) { | |
139 if (Array.empty()) | |
140 return Error::success(); | |
141 if (Array.size() > UINT32_MAX / sizeof(T)) | |
142 return make_error<BinaryStreamError>( | |
143 stream_error_code::invalid_array_size); | |
144 | |
145 return writeBytes( | |
146 ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()), | |
147 Array.size() * sizeof(T))); | |
148 } | |
149 | |
150 /// Writes all data from the array \p Array to the underlying stream. | |
151 /// | |
152 /// \returns a success error code if the data was successfully written, | |
153 /// otherwise returns an appropriate error code. | |
154 template <typename T, typename U> | |
155 Error writeArray(VarStreamArray<T, U> Array) { | |
156 return writeStreamRef(Array.getUnderlyingStream()); | |
157 } | |
158 | |
159 /// Writes all elements from the array \p Array to the underlying stream. | |
160 /// | |
161 /// \returns a success error code if the data was successfully written, | |
162 /// otherwise returns an appropriate error code. | |
163 template <typename T> Error writeArray(FixedStreamArray<T> Array) { | |
164 return writeStreamRef(Array.getUnderlyingStream()); | |
165 } | |
166 | |
167 /// Splits the Writer into two Writers at a given offset. | |
168 std::pair<BinaryStreamWriter, BinaryStreamWriter> split(uint32_t Off) const; | |
169 | |
170 void setOffset(uint32_t Off) { Offset = Off; } | |
171 uint32_t getOffset() const { return Offset; } | |
172 uint32_t getLength() const { return Stream.getLength(); } | |
173 uint32_t bytesRemaining() const { return getLength() - getOffset(); } | |
174 Error padToAlignment(uint32_t Align); | |
175 | |
176 protected: | |
177 WritableBinaryStreamRef Stream; | |
178 uint32_t Offset = 0; | |
179 }; | |
180 | |
181 } // end namespace llvm | |
182 | |
183 #endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H |