circular_raw_ostream.h 4.8 KB

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