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