| //===-- llvm/Support/circular_raw_ostream.h - Buffered streams --*- C++ -*-===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file contains raw_ostream implementations for streams to do circular | 
 | // buffering of their output. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #ifndef LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H | 
 | #define LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H | 
 |  | 
 | #include "llvm/Support/raw_ostream.h" | 
 |  | 
 | namespace llvm { | 
 |   /// circular_raw_ostream - A raw_ostream which *can* save its data | 
 |   /// to a circular buffer, or can pass it through directly to an | 
 |   /// underlying stream if specified with a buffer of zero. | 
 |   /// | 
 |   class circular_raw_ostream : public raw_ostream { | 
 |   public: | 
 |     /// TAKE_OWNERSHIP - Tell this stream that it owns the underlying | 
 |     /// stream and is responsible for cleanup, memory management | 
 |     /// issues, etc. | 
 |     /// | 
 |     static const bool TAKE_OWNERSHIP = true; | 
 |  | 
 |     /// REFERENCE_ONLY - Tell this stream it should not manage the | 
 |     /// held stream. | 
 |     /// | 
 |     static const bool REFERENCE_ONLY = false; | 
 |  | 
 |   private: | 
 |     /// TheStream - The real stream we output to. We set it to be | 
 |     /// unbuffered, since we're already doing our own buffering. | 
 |     /// | 
 |     raw_ostream *TheStream; | 
 |  | 
 |     /// OwnsStream - Are we responsible for managing the underlying | 
 |     /// stream? | 
 |     /// | 
 |     bool OwnsStream; | 
 |  | 
 |     /// BufferSize - The size of the buffer in bytes. | 
 |     /// | 
 |     size_t BufferSize; | 
 |  | 
 |     /// BufferArray - The actual buffer storage. | 
 |     /// | 
 |     char *BufferArray; | 
 |  | 
 |     /// Cur - Pointer to the current output point in BufferArray. | 
 |     /// | 
 |     char *Cur; | 
 |  | 
 |     /// Filled - Indicate whether the buffer has been completely | 
 |     /// filled.  This helps avoid garbage output. | 
 |     /// | 
 |     bool Filled; | 
 |  | 
 |     /// Banner - A pointer to a banner to print before dumping the | 
 |     /// log. | 
 |     /// | 
 |     const char *Banner; | 
 |  | 
 |     /// flushBuffer - Dump the contents of the buffer to Stream. | 
 |     /// | 
 |     void flushBuffer() { | 
 |       if (Filled) | 
 |         // Write the older portion of the buffer. | 
 |         TheStream->write(Cur, BufferArray + BufferSize - Cur); | 
 |       // Write the newer portion of the buffer. | 
 |       TheStream->write(BufferArray, Cur - BufferArray); | 
 |       Cur = BufferArray; | 
 |       Filled = false; | 
 |     } | 
 |  | 
 |     void write_impl(const char *Ptr, size_t Size) override; | 
 |  | 
 |     /// current_pos - Return the current position within the stream, | 
 |     /// not counting the bytes currently in the buffer. | 
 |     /// | 
 |     uint64_t current_pos() const override { | 
 |       // This has the same effect as calling TheStream.current_pos(), | 
 |       // but that interface is private. | 
 |       return TheStream->tell() - TheStream->GetNumBytesInBuffer(); | 
 |     } | 
 |  | 
 |   public: | 
 |     /// circular_raw_ostream - Construct an optionally | 
 |     /// circular-buffered stream, handing it an underlying stream to | 
 |     /// do the "real" output. | 
 |     /// | 
 |     /// As a side effect, if BuffSize is nonzero, the given Stream is | 
 |     /// set to be Unbuffered.  This is because circular_raw_ostream | 
 |     /// does its own buffering, so it doesn't want another layer of | 
 |     /// buffering to be happening underneath it. | 
 |     /// | 
 |     /// "Owns" tells the circular_raw_ostream whether it is | 
 |     /// responsible for managing the held stream, doing memory | 
 |     /// management of it, etc. | 
 |     /// | 
 |     circular_raw_ostream(raw_ostream &Stream, const char *Header, | 
 |                          size_t BuffSize = 0, bool Owns = REFERENCE_ONLY) | 
 |         : raw_ostream(/*unbuffered*/ true), TheStream(nullptr), | 
 |           OwnsStream(Owns), BufferSize(BuffSize), BufferArray(nullptr), | 
 |           Filled(false), Banner(Header) { | 
 |       if (BufferSize != 0) | 
 |         BufferArray = new char[BufferSize]; | 
 |       Cur = BufferArray; | 
 |       setStream(Stream, Owns); | 
 |     } | 
 |  | 
 |     ~circular_raw_ostream() override { | 
 |       flush(); | 
 |       flushBufferWithBanner(); | 
 |       releaseStream(); | 
 |       delete[] BufferArray; | 
 |     } | 
 |  | 
 |     /// setStream - Tell the circular_raw_ostream to output a | 
 |     /// different stream.  "Owns" tells circular_raw_ostream whether | 
 |     /// it should take responsibility for managing the underlying | 
 |     /// stream. | 
 |     /// | 
 |     void setStream(raw_ostream &Stream, bool Owns = REFERENCE_ONLY) { | 
 |       releaseStream(); | 
 |       TheStream = &Stream; | 
 |       OwnsStream = Owns; | 
 |     } | 
 |  | 
 |     /// flushBufferWithBanner - Force output of the buffer along with | 
 |     /// a small header. | 
 |     /// | 
 |     void flushBufferWithBanner(); | 
 |  | 
 |   private: | 
 |     /// releaseStream - Delete the held stream if needed. Otherwise, | 
 |     /// transfer the buffer settings from this circular_raw_ostream | 
 |     /// back to the underlying stream. | 
 |     /// | 
 |     void releaseStream() { | 
 |       if (!TheStream) | 
 |         return; | 
 |       if (OwnsStream) | 
 |         delete TheStream; | 
 |     } | 
 |   }; | 
 | } // end llvm namespace | 
 |  | 
 | #endif |