|
|
|||
File indexing completed on 2026-05-10 08:44:28
0001 //===- BinaryStreamWriter.h - Writes objects to a BinaryStream ---*- C++-*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLVM_SUPPORT_BINARYSTREAMWRITER_H 0010 #define LLVM_SUPPORT_BINARYSTREAMWRITER_H 0011 0012 #include "llvm/ADT/ArrayRef.h" 0013 #include "llvm/ADT/StringRef.h" 0014 #include "llvm/Support/BinaryStreamArray.h" 0015 #include "llvm/Support/BinaryStreamError.h" 0016 #include "llvm/Support/BinaryStreamRef.h" 0017 #include "llvm/Support/Endian.h" 0018 #include "llvm/Support/Error.h" 0019 #include <cstdint> 0020 #include <type_traits> 0021 #include <utility> 0022 0023 namespace llvm { 0024 0025 /// Provides write only access to a subclass of `WritableBinaryStream`. 0026 /// Provides bounds checking and helpers for writing certain common data types 0027 /// such as null-terminated strings, integers in various flavors of endianness, 0028 /// etc. Can be subclassed to provide reading and writing of custom datatypes, 0029 /// although no methods are overridable. 0030 class BinaryStreamWriter { 0031 public: 0032 BinaryStreamWriter() = default; 0033 explicit BinaryStreamWriter(WritableBinaryStreamRef Ref); 0034 explicit BinaryStreamWriter(WritableBinaryStream &Stream); 0035 explicit BinaryStreamWriter(MutableArrayRef<uint8_t> Data, 0036 llvm::endianness Endian); 0037 0038 BinaryStreamWriter(const BinaryStreamWriter &Other) = default; 0039 0040 BinaryStreamWriter &operator=(const BinaryStreamWriter &Other) = default; 0041 0042 virtual ~BinaryStreamWriter() = default; 0043 0044 /// Write the bytes specified in \p Buffer to the underlying stream. 0045 /// On success, updates the offset so that subsequent writes will occur 0046 /// at the next unwritten position. 0047 /// 0048 /// \returns a success error code if the data was successfully written, 0049 /// otherwise returns an appropriate error code. 0050 Error writeBytes(ArrayRef<uint8_t> Buffer); 0051 0052 /// Write the integer \p Value to the underlying stream in the 0053 /// specified endianness. On success, updates the offset so that 0054 /// subsequent writes occur at the next unwritten position. 0055 /// 0056 /// \returns a success error code if the data was successfully written, 0057 /// otherwise returns an appropriate error code. 0058 template <typename T> Error writeInteger(T Value) { 0059 static_assert(std::is_integral_v<T>, 0060 "Cannot call writeInteger with non-integral value!"); 0061 uint8_t Buffer[sizeof(T)]; 0062 llvm::support::endian::write<T>(Buffer, Value, Stream.getEndian()); 0063 return writeBytes(Buffer); 0064 } 0065 0066 /// Similar to writeInteger 0067 template <typename T> Error writeEnum(T Num) { 0068 static_assert(std::is_enum<T>::value, 0069 "Cannot call writeEnum with non-Enum type"); 0070 0071 using U = std::underlying_type_t<T>; 0072 return writeInteger<U>(static_cast<U>(Num)); 0073 } 0074 0075 /// Write the unsigned integer Value to the underlying stream using ULEB128 0076 /// encoding. 0077 /// 0078 /// \returns a success error code if the data was successfully written, 0079 /// otherwise returns an appropriate error code. 0080 Error writeULEB128(uint64_t Value); 0081 0082 /// Write the unsigned integer Value to the underlying stream using ULEB128 0083 /// encoding. 0084 /// 0085 /// \returns a success error code if the data was successfully written, 0086 /// otherwise returns an appropriate error code. 0087 Error writeSLEB128(int64_t Value); 0088 0089 /// Write the string \p Str to the underlying stream followed by a null 0090 /// terminator. On success, updates the offset so that subsequent writes 0091 /// occur at the next unwritten position. \p Str need not be null terminated 0092 /// on input. 0093 /// 0094 /// \returns a success error code if the data was successfully written, 0095 /// otherwise returns an appropriate error code. 0096 Error writeCString(StringRef Str); 0097 0098 /// Write the string \p Str to the underlying stream without a null 0099 /// terminator. On success, updates the offset so that subsequent writes 0100 /// occur at the next unwritten position. 0101 /// 0102 /// \returns a success error code if the data was successfully written, 0103 /// otherwise returns an appropriate error code. 0104 Error writeFixedString(StringRef Str); 0105 0106 /// Efficiently reads all data from \p Ref, and writes it to this stream. 0107 /// This operation will not invoke any copies of the source data, regardless 0108 /// of the source stream's implementation. 0109 /// 0110 /// \returns a success error code if the data was successfully written, 0111 /// otherwise returns an appropriate error code. 0112 Error writeStreamRef(BinaryStreamRef Ref); 0113 0114 /// Efficiently reads \p Size bytes from \p Ref, and writes it to this stream. 0115 /// This operation will not invoke any copies of the source data, regardless 0116 /// of the source stream's implementation. 0117 /// 0118 /// \returns a success error code if the data was successfully written, 0119 /// otherwise returns an appropriate error code. 0120 Error writeStreamRef(BinaryStreamRef Ref, uint64_t Size); 0121 0122 /// Writes the object \p Obj to the underlying stream, as if by using memcpy. 0123 /// It is up to the caller to ensure that type of \p Obj can be safely copied 0124 /// in this fashion, as no checks are made to ensure that this is safe. 0125 /// 0126 /// \returns a success error code if the data was successfully written, 0127 /// otherwise returns an appropriate error code. 0128 template <typename T> Error writeObject(const T &Obj) { 0129 static_assert(!std::is_pointer<T>::value, 0130 "writeObject should not be used with pointers, to write " 0131 "the pointed-to value dereference the pointer before calling " 0132 "writeObject"); 0133 return writeBytes( 0134 ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T))); 0135 } 0136 0137 /// Writes an array of objects of type T to the underlying stream, as if by 0138 /// using memcpy. It is up to the caller to ensure that type of \p Obj can 0139 /// be safely copied in this fashion, as no checks are made to ensure that 0140 /// this is safe. 0141 /// 0142 /// \returns a success error code if the data was successfully written, 0143 /// otherwise returns an appropriate error code. 0144 template <typename T> Error writeArray(ArrayRef<T> Array) { 0145 if (Array.empty()) 0146 return Error::success(); 0147 if (Array.size() > UINT32_MAX / sizeof(T)) 0148 return make_error<BinaryStreamError>( 0149 stream_error_code::invalid_array_size); 0150 0151 return writeBytes( 0152 ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()), 0153 Array.size() * sizeof(T))); 0154 } 0155 0156 /// Writes all data from the array \p Array to the underlying stream. 0157 /// 0158 /// \returns a success error code if the data was successfully written, 0159 /// otherwise returns an appropriate error code. 0160 template <typename T, typename U> 0161 Error writeArray(VarStreamArray<T, U> Array) { 0162 return writeStreamRef(Array.getUnderlyingStream()); 0163 } 0164 0165 /// Writes all elements from the array \p Array to the underlying stream. 0166 /// 0167 /// \returns a success error code if the data was successfully written, 0168 /// otherwise returns an appropriate error code. 0169 template <typename T> Error writeArray(FixedStreamArray<T> Array) { 0170 return writeStreamRef(Array.getUnderlyingStream()); 0171 } 0172 0173 /// Splits the Writer into two Writers at a given offset. 0174 std::pair<BinaryStreamWriter, BinaryStreamWriter> split(uint64_t Off) const; 0175 0176 void setOffset(uint64_t Off) { Offset = Off; } 0177 uint64_t getOffset() const { return Offset; } 0178 uint64_t getLength() const { return Stream.getLength(); } 0179 uint64_t bytesRemaining() const { return getLength() - getOffset(); } 0180 Error padToAlignment(uint32_t Align); 0181 0182 protected: 0183 WritableBinaryStreamRef Stream; 0184 uint64_t Offset = 0; 0185 }; 0186 0187 } // end namespace llvm 0188 0189 #endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|