annotate include/llvm/Support/BinaryStreamWriter.h @ 125:56c5119fbcd2

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