Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- llvm/Support/circular_raw_ostream.h - Buffered streams --*- 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. // This file contains raw_ostream implementations for streams to do circular
  10. // buffering of their output.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H
  15. #define LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H
  16.  
  17. #include "llvm/Support/raw_ostream.h"
  18.  
  19. namespace llvm {
  20.   /// circular_raw_ostream - A raw_ostream which *can* save its data
  21.   /// to a circular buffer, or can pass it through directly to an
  22.   /// underlying stream if specified with a buffer of zero.
  23.   ///
  24.   class circular_raw_ostream : public raw_ostream {
  25.   public:
  26.     /// TAKE_OWNERSHIP - Tell this stream that it owns the underlying
  27.     /// stream and is responsible for cleanup, memory management
  28.     /// issues, etc.
  29.     ///
  30.     static constexpr bool TAKE_OWNERSHIP = true;
  31.  
  32.     /// REFERENCE_ONLY - Tell this stream it should not manage the
  33.     /// held stream.
  34.     ///
  35.     static constexpr bool REFERENCE_ONLY = false;
  36.  
  37.   private:
  38.     /// TheStream - The real stream we output to. We set it to be
  39.     /// unbuffered, since we're already doing our own buffering.
  40.     ///
  41.     raw_ostream *TheStream = nullptr;
  42.  
  43.     /// OwnsStream - Are we responsible for managing the underlying
  44.     /// stream?
  45.     ///
  46.     bool OwnsStream;
  47.  
  48.     /// BufferSize - The size of the buffer in bytes.
  49.     ///
  50.     size_t BufferSize;
  51.  
  52.     /// BufferArray - The actual buffer storage.
  53.     ///
  54.     char *BufferArray = nullptr;
  55.  
  56.     /// Cur - Pointer to the current output point in BufferArray.
  57.     ///
  58.     char *Cur;
  59.  
  60.     /// Filled - Indicate whether the buffer has been completely
  61.     /// filled.  This helps avoid garbage output.
  62.     ///
  63.     bool Filled = false;
  64.  
  65.     /// Banner - A pointer to a banner to print before dumping the
  66.     /// log.
  67.     ///
  68.     const char *Banner;
  69.  
  70.     /// flushBuffer - Dump the contents of the buffer to Stream.
  71.     ///
  72.     void flushBuffer() {
  73.       if (Filled)
  74.         // Write the older portion of the buffer.
  75.         TheStream->write(Cur, BufferArray + BufferSize - Cur);
  76.       // Write the newer portion of the buffer.
  77.       TheStream->write(BufferArray, Cur - BufferArray);
  78.       Cur = BufferArray;
  79.       Filled = false;
  80.     }
  81.  
  82.     void write_impl(const char *Ptr, size_t Size) override;
  83.  
  84.     /// current_pos - Return the current position within the stream,
  85.     /// not counting the bytes currently in the buffer.
  86.     ///
  87.     uint64_t current_pos() const override {
  88.       // This has the same effect as calling TheStream.current_pos(),
  89.       // but that interface is private.
  90.       return TheStream->tell() - TheStream->GetNumBytesInBuffer();
  91.     }
  92.  
  93.   public:
  94.     /// circular_raw_ostream - Construct an optionally
  95.     /// circular-buffered stream, handing it an underlying stream to
  96.     /// do the "real" output.
  97.     ///
  98.     /// As a side effect, if BuffSize is nonzero, the given Stream is
  99.     /// set to be Unbuffered.  This is because circular_raw_ostream
  100.     /// does its own buffering, so it doesn't want another layer of
  101.     /// buffering to be happening underneath it.
  102.     ///
  103.     /// "Owns" tells the circular_raw_ostream whether it is
  104.     /// responsible for managing the held stream, doing memory
  105.     /// management of it, etc.
  106.     ///
  107.     circular_raw_ostream(raw_ostream &Stream, const char *Header,
  108.                          size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
  109.         : raw_ostream(/*unbuffered*/ true), OwnsStream(Owns),
  110.           BufferSize(BuffSize), Banner(Header) {
  111.       if (BufferSize != 0)
  112.         BufferArray = new char[BufferSize];
  113.       Cur = BufferArray;
  114.       setStream(Stream, Owns);
  115.     }
  116.  
  117.     ~circular_raw_ostream() override {
  118.       flush();
  119.       flushBufferWithBanner();
  120.       releaseStream();
  121.       delete[] BufferArray;
  122.     }
  123.  
  124.     bool is_displayed() const override {
  125.       return TheStream->is_displayed();
  126.     }
  127.  
  128.     /// setStream - Tell the circular_raw_ostream to output a
  129.     /// different stream.  "Owns" tells circular_raw_ostream whether
  130.     /// it should take responsibility for managing the underlying
  131.     /// stream.
  132.     ///
  133.     void setStream(raw_ostream &Stream, bool Owns = REFERENCE_ONLY) {
  134.       releaseStream();
  135.       TheStream = &Stream;
  136.       OwnsStream = Owns;
  137.     }
  138.  
  139.     /// flushBufferWithBanner - Force output of the buffer along with
  140.     /// a small header.
  141.     ///
  142.     void flushBufferWithBanner();
  143.  
  144.   private:
  145.     /// releaseStream - Delete the held stream if needed. Otherwise,
  146.     /// transfer the buffer settings from this circular_raw_ostream
  147.     /// back to the underlying stream.
  148.     ///
  149.     void releaseStream() {
  150.       if (!TheStream)
  151.         return;
  152.       if (OwnsStream)
  153.         delete TheStream;
  154.     }
  155.   };
  156. } // end llvm namespace
  157.  
  158. #endif
  159.