1 //===- BinaryStream.h - Base interface for a stream of data -----*- 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_BINARYSTREAM_H 11 #define LLVM_SUPPORT_BINARYSTREAM_H 12 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/Support/BinaryStreamError.h" 15 #include "llvm/Support/Endian.h" 16 #include "llvm/Support/Error.h" 17 #include <cstdint> 18 19 namespace llvm { 20 21 /// \brief An interface for accessing data in a stream-like format, but which 22 /// discourages copying. Instead of specifying a buffer in which to copy 23 /// data on a read, the API returns an ArrayRef to data owned by the stream's 24 /// implementation. Since implementations may not necessarily store data in a 25 /// single contiguous buffer (or even in memory at all), in such cases a it may 26 /// be necessary for an implementation to cache such a buffer so that it can 27 /// return it. 28 class BinaryStream { 29 public: 30 virtual ~BinaryStream() = default; 31 32 virtual llvm::support::endianness getEndian() const = 0; 33 34 /// \brief Given an offset into the stream and a number of bytes, attempt to 35 /// read the bytes and set the output ArrayRef to point to data owned by the 36 /// stream. 37 virtual Error readBytes(uint32_t Offset, uint32_t Size, 38 ArrayRef<uint8_t> &Buffer) = 0; 39 40 /// \brief Given an offset into the stream, read as much as possible without 41 /// copying any data. 42 virtual Error readLongestContiguousChunk(uint32_t Offset, 43 ArrayRef<uint8_t> &Buffer) = 0; 44 45 /// \brief Return the number of bytes of data in this stream. 46 virtual uint32_t getLength() = 0; 47 48 protected: 49 Error checkOffset(uint32_t Offset, uint32_t DataSize) { 50 if (Offset > getLength()) 51 return make_error<BinaryStreamError>(stream_error_code::invalid_offset); 52 if (getLength() < DataSize + Offset) 53 return make_error<BinaryStreamError>(stream_error_code::stream_too_short); 54 return Error::success(); 55 } 56 }; 57 58 /// \brief A BinaryStream which can be read from as well as written to. Note 59 /// that writing to a BinaryStream always necessitates copying from the input 60 /// buffer to the stream's backing store. Streams are assumed to be buffered 61 /// so that to be portable it is necessary to call commit() on the stream when 62 /// all data has been written. 63 class WritableBinaryStream : public BinaryStream { 64 public: 65 ~WritableBinaryStream() override = default; 66 67 /// \brief Attempt to write the given bytes into the stream at the desired 68 /// offset. This will always necessitate a copy. Cannot shrink or grow the 69 /// stream, only writes into existing allocated space. 70 virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) = 0; 71 72 /// \brief For buffered streams, commits changes to the backing store. 73 virtual Error commit() = 0; 74 }; 75 76 } // end namespace llvm 77 78 #endif // LLVM_SUPPORT_BINARYSTREAM_H 79