LLVM  10.0.0svn
BinaryStreamWriter.h
Go to the documentation of this file.
1 //===- BinaryStreamWriter.h - Writes objects to a BinaryStream ---*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_SUPPORT_BINARYSTREAMWRITER_H
10 #define LLVM_SUPPORT_BINARYSTREAMWRITER_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/Error.h"
20 #include <cstdint>
21 #include <type_traits>
22 #include <utility>
23 
24 namespace llvm {
25 
26 /// Provides write only access to a subclass of `WritableBinaryStream`.
27 /// Provides bounds checking and helpers for writing certain common data types
28 /// such as null-terminated strings, integers in various flavors of endianness,
29 /// etc. Can be subclassed to provide reading and writing of custom datatypes,
30 /// although no methods are overridable.
32 public:
33  BinaryStreamWriter() = default;
38 
40  : Stream(Other.Stream), Offset(Other.Offset) {}
41 
43  Stream = Other.Stream;
44  Offset = Other.Offset;
45  return *this;
46  }
47 
48  virtual ~BinaryStreamWriter() {}
49 
50  /// Write the bytes specified in \p Buffer to the underlying stream.
51  /// On success, updates the offset so that subsequent writes will occur
52  /// at the next unwritten position.
53  ///
54  /// \returns a success error code if the data was successfully written,
55  /// otherwise returns an appropriate error code.
57 
58  /// Write the integer \p Value to the underlying stream in the
59  /// specified endianness. On success, updates the offset so that
60  /// subsequent writes occur at the next unwritten position.
61  ///
62  /// \returns a success error code if the data was successfully written,
63  /// otherwise returns an appropriate error code.
64  template <typename T> Error writeInteger(T Value) {
65  static_assert(std::is_integral<T>::value,
66  "Cannot call writeInteger with non-integral value!");
67  uint8_t Buffer[sizeof(T)];
68  llvm::support::endian::write<T, llvm::support::unaligned>(
69  Buffer, Value, Stream.getEndian());
70  return writeBytes(Buffer);
71  }
72 
73  /// Similar to writeInteger
74  template <typename T> Error writeEnum(T Num) {
75  static_assert(std::is_enum<T>::value,
76  "Cannot call writeEnum with non-Enum type");
77 
78  using U = typename std::underlying_type<T>::type;
79  return writeInteger<U>(static_cast<U>(Num));
80  }
81 
82  /// Write the unsigned integer Value to the underlying stream using ULEB128
83  /// encoding.
84  ///
85  /// \returns a success error code if the data was successfully written,
86  /// otherwise returns an appropriate error code.
87  Error writeULEB128(uint64_t Value);
88 
89  /// Write the unsigned integer Value to the underlying stream using ULEB128
90  /// encoding.
91  ///
92  /// \returns a success error code if the data was successfully written,
93  /// otherwise returns an appropriate error code.
94  Error writeSLEB128(int64_t Value);
95 
96  /// Write the string \p Str to the underlying stream followed by a null
97  /// terminator. On success, updates the offset so that subsequent writes
98  /// occur at the next unwritten position. \p Str need not be null terminated
99  /// on input.
100  ///
101  /// \returns a success error code if the data was successfully written,
102  /// otherwise returns an appropriate error code.
104 
105  /// Write the string \p Str to the underlying stream without a null
106  /// terminator. On success, updates the offset so that subsequent writes
107  /// occur at the next unwritten position.
108  ///
109  /// \returns a success error code if the data was successfully written,
110  /// otherwise returns an appropriate error code.
112 
113  /// Efficiently reads all data from \p Ref, and writes it to this stream.
114  /// This operation will not invoke any copies of the source data, regardless
115  /// of the source stream's implementation.
116  ///
117  /// \returns a success error code if the data was successfully written,
118  /// otherwise returns an appropriate error code.
120 
121  /// Efficiently reads \p Size bytes from \p Ref, and writes it to this stream.
122  /// This operation will not invoke any copies of the source data, regardless
123  /// of the source stream's implementation.
124  ///
125  /// \returns a success error code if the data was successfully written,
126  /// otherwise returns an appropriate error code.
128 
129  /// Writes the object \p Obj to the underlying stream, as if by using memcpy.
130  /// It is up to the caller to ensure that type of \p Obj can be safely copied
131  /// in this fashion, as no checks are made to ensure that this is safe.
132  ///
133  /// \returns a success error code if the data was successfully written,
134  /// otherwise returns an appropriate error code.
135  template <typename T> Error writeObject(const T &Obj) {
136  static_assert(!std::is_pointer<T>::value,
137  "writeObject should not be used with pointers, to write "
138  "the pointed-to value dereference the pointer before calling "
139  "writeObject");
140  return writeBytes(
141  ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
142  }
143 
144  /// Writes an array of objects of type T to the underlying stream, as if by
145  /// using memcpy. It is up to the caller to ensure that type of \p Obj can
146  /// be safely copied in this fashion, as no checks are made to ensure that
147  /// this is safe.
148  ///
149  /// \returns a success error code if the data was successfully written,
150  /// otherwise returns an appropriate error code.
151  template <typename T> Error writeArray(ArrayRef<T> Array) {
152  if (Array.empty())
153  return Error::success();
154  if (Array.size() > UINT32_MAX / sizeof(T))
155  return make_error<BinaryStreamError>(
157 
158  return writeBytes(
159  ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
160  Array.size() * sizeof(T)));
161  }
162 
163  /// Writes all data from the array \p Array to the underlying stream.
164  ///
165  /// \returns a success error code if the data was successfully written,
166  /// otherwise returns an appropriate error code.
167  template <typename T, typename U>
169  return writeStreamRef(Array.getUnderlyingStream());
170  }
171 
172  /// Writes all elements from the array \p Array to the underlying stream.
173  ///
174  /// \returns a success error code if the data was successfully written,
175  /// otherwise returns an appropriate error code.
176  template <typename T> Error writeArray(FixedStreamArray<T> Array) {
177  return writeStreamRef(Array.getUnderlyingStream());
178  }
179 
180  /// Splits the Writer into two Writers at a given offset.
181  std::pair<BinaryStreamWriter, BinaryStreamWriter> split(uint32_t Off) const;
182 
183  void setOffset(uint32_t Off) { Offset = Off; }
184  uint32_t getOffset() const { return Offset; }
185  uint32_t getLength() const { return Stream.getLength(); }
186  uint32_t bytesRemaining() const { return getLength() - getOffset(); }
188 
189 protected:
192 };
193 
194 } // end namespace llvm
195 
196 #endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
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:23
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.
Error writeSLEB128(int64_t Value)
Write the unsigned integer Value to the underlying stream using ULEB128 encoding. ...
virtual uint32_t getLength()=0
Return the number of bytes of data in this stream.
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:148
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:145
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:40
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:326
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 writeULEB128(uint64_t Value)
Write the unsigned integer Value to the underlying stream using ULEB128 encoding. ...
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:46
LLVM Value Representation.
Definition: Value.h:73
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:143
A BinaryStream which can be read from as well as written to.
Definition: BinaryStream.h:73