//===--- ExponentialGrowthAppendingBinaryByteStream.h -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // /// Defines an \c llvm::WritableBinaryStream whose internal buffer grows /// exponentially in size as data is written to it. It is thus more efficient /// than llvm::AppendingBinaryByteStream if a lot of small data gets appended to /// it. /// //===----------------------------------------------------------------------===// #ifndef SWIFT_BASIC_EXPONENTIALGROWTHAPPENDINGBINARYBYTESTREAM_H #define SWIFT_BASIC_EXPONENTIALGROWTHAPPENDINGBINARYBYTESTREAM_H #include "swift/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/BinaryByteStream.h" namespace swift { /// An implementation of WritableBinaryStream which can write at its end /// causing the underlying data to grow. This class owns the underlying data. class ExponentialGrowthAppendingBinaryByteStream : public llvm::WritableBinaryStream { /// The buffer holding the data. SmallVector Data; /// Data in the stream is always encoded in little-endian byte order. const llvm::support::endianness Endian = llvm::support::endianness::little; public: ExponentialGrowthAppendingBinaryByteStream() = default; void reserve(size_t Size); llvm::support::endianness getEndian() const override { return Endian; } llvm::Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) override; llvm::Error readLongestContiguousChunk(uint32_t Offset, ArrayRef &Buffer) override; MutableArrayRef data() { return Data; } uint32_t getLength() override { return Data.size(); } llvm::Error writeBytes(uint32_t Offset, ArrayRef Buffer) override; /// This is an optimized version of \c writeBytes specifically for integers. /// Integers are written in little-endian byte order. template llvm::Error writeInteger(uint32_t Offset, T Value) { static_assert(std::is_integral::value, "Integer required."); if (auto Error = checkOffsetForWrite(Offset, sizeof(T))) { return Error; } // Resize the internal buffer if needed. uint32_t RequiredSize = Offset + sizeof(T); if (RequiredSize > Data.size()) { Data.resize(RequiredSize); } llvm::support::endian::write( Data.data() + Offset, Value, Endian); return llvm::Error::success(); } llvm::Error commit() override { return llvm::Error::success(); } virtual llvm::BinaryStreamFlags getFlags() const override { return llvm::BSF_Write | llvm::BSF_Append; } }; } // end namespace swift #endif // SWIFT_BASIC_EXPONENTIALGROWTHAPPENDINGBINARYBYTESTREAM_H