/home/arjun/llvm-project/llvm/include/llvm/Support/circular_raw_ostream.h
Line | Count | Source (jump to first uncovered line) |
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; |
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; |
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; |
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 | 0 | void flushBuffer() { |
73 | 0 | if (Filled) |
74 | 0 | // Write the older portion of the buffer. |
75 | 0 | TheStream->write(Cur, BufferArray + BufferSize - Cur); |
76 | 0 | // Write the newer portion of the buffer. |
77 | 0 | TheStream->write(BufferArray, Cur - BufferArray); |
78 | 0 | Cur = BufferArray; |
79 | 0 | Filled = false; |
80 | 0 | } |
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 | 0 | uint64_t current_pos() const override { |
88 | 0 | // This has the same effect as calling TheStream.current_pos(), |
89 | 0 | // but that interface is private. |
90 | 0 | return TheStream->tell() - TheStream->GetNumBytesInBuffer(); |
91 | 0 | } |
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), TheStream(nullptr), |
110 | | OwnsStream(Owns), BufferSize(BuffSize), BufferArray(nullptr), |
111 | 0 | Filled(false), Banner(Header) { |
112 | 0 | if (BufferSize != 0) |
113 | 0 | BufferArray = new char[BufferSize]; |
114 | 0 | Cur = BufferArray; |
115 | 0 | setStream(Stream, Owns); |
116 | 0 | } |
117 | | |
118 | 0 | ~circular_raw_ostream() override { |
119 | 0 | flush(); |
120 | 0 | flushBufferWithBanner(); |
121 | 0 | releaseStream(); |
122 | 0 | delete[] BufferArray; |
123 | 0 | } |
124 | | |
125 | 0 | bool is_displayed() const override { |
126 | 0 | return TheStream->is_displayed(); |
127 | 0 | } |
128 | | |
129 | | /// setStream - Tell the circular_raw_ostream to output a |
130 | | /// different stream. "Owns" tells circular_raw_ostream whether |
131 | | /// it should take responsibility for managing the underlying |
132 | | /// stream. |
133 | | /// |
134 | 0 | void setStream(raw_ostream &Stream, bool Owns = REFERENCE_ONLY) { |
135 | 0 | releaseStream(); |
136 | 0 | TheStream = &Stream; |
137 | 0 | OwnsStream = Owns; |
138 | 0 | } |
139 | | |
140 | | /// flushBufferWithBanner - Force output of the buffer along with |
141 | | /// a small header. |
142 | | /// |
143 | | void flushBufferWithBanner(); |
144 | | |
145 | | private: |
146 | | /// releaseStream - Delete the held stream if needed. Otherwise, |
147 | | /// transfer the buffer settings from this circular_raw_ostream |
148 | | /// back to the underlying stream. |
149 | | /// |
150 | 0 | void releaseStream() { |
151 | 0 | if (!TheStream) |
152 | 0 | return; |
153 | 0 | if (OwnsStream) |
154 | 0 | delete TheStream; |
155 | 0 | } |
156 | | }; |
157 | | } // end llvm namespace |
158 | | |
159 | | #endif |