LLVM  8.0.1
BinaryStreamWriter.h
Go to the documentation of this file.
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"
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 /// 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.
33 public:
34  BinaryStreamWriter() = default;
39 
41  : Stream(Other.Stream), Offset(Other.Offset) {}
42 
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.
58 
59  /// Write 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 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.
91 
92  /// Write 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.
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.
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.
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>(
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>
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(); }
175 
176 protected:
179 };
180 
181 } // end namespace llvm
182 
183 #endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Error writeBytes(ArrayRef< uint8_t > Buffer)
Write the bytes specified in Buffer to the underlying stream.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
BinaryStreamWriter(const BinaryStreamWriter &Other)
BinaryStreamWriter & operator=(const BinaryStreamWriter &Other)
BinaryStreamRef getUnderlyingStream() const
FixedStreamArray is similar to VarStreamArray, except with each record having a fixed-length.
The access may reference the value stored in memory.
Error writeArray(VarStreamArray< T, U > Array)
Writes all data from the array Array to the underlying stream.
Error writeFixedString(StringRef Str)
Write the string Str to the underlying stream without a null terminator.
virtual uint32_t getLength()=0
Return the number of bytes of data in this stream.
#define T
Error writeArray(ArrayRef< T > Array)
Writes an array of objects of type T to the underlying stream, as if by using memcpy.
virtual llvm::support::endianness getEndian() const =0
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
Error writeArray(FixedStreamArray< T > Array)
Writes all elements from the array Array to the underlying stream.
Error writeStreamRef(BinaryStreamRef Ref)
Efficiently reads all data from Ref, and writes it to this stream.
WritableBinaryStreamRef Stream
Provides write only access to a subclass of WritableBinaryStream.
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
const T * data() const
Definition: ArrayRef.h:146
uint32_t bytesRemaining() const
Error writeCString(StringRef Str)
Write the string Str to the underlying stream followed by a null terminator.
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
std::pair< BinaryStreamWriter, BinaryStreamWriter > split(uint32_t Off) const
Splits the Writer into two Writers at a given offset.
Error writeEnum(T Num)
Similar to writeInteger.
void setOffset(uint32_t Off)
BinaryStreamRef getUnderlyingStream() const
Error padToAlignment(uint32_t Align)
uint32_t Size
Definition: Profile.cpp:47
LLVM Value Representation.
Definition: Value.h:73
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144
A BinaryStream which can be read from as well as written to.
Definition: BinaryStream.h:74