llvm.org GIT mirror llvm / 89a66a9
raw_ostream: Replace flush_impl with write_impl, which takes data to write as arguments. - Add raw_ostream::GetNumBytesInBuffer. - Privatize buffer pointers. - Get rid of slow and unnecessary code for writing out large strings. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67060 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Dunbar 10 years ago
2 changed file(s) with 42 addition(s) and 73 deletion(s). Raw diff Collapse all Expand all
2929 /// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
3030 /// a chunk at a time.
3131 class raw_ostream {
32 protected:
32 private:
3333 /// \invariant { The buffer is uninitialized (OutBufStart,
3434 /// OutBufEnd, and OutBufCur are non-zero), or none of them are zero
3535 /// and there are at least 64 total bytes in the buffer. }
7272 Unbuffered = unbuffered;
7373 if (Unbuffered)
7474 flush();
75 }
76
77 unsigned GetNumBytesInBuffer() const {
78 return OutBufCur - OutBufStart;
7579 }
7680
7781 //===--------------------------------------------------------------------===//
146150 //===--------------------------------------------------------------------===//
147151
148152 private:
149 /// flush_impl - The is the piece of the class that is implemented by
150 /// subclasses. This only outputs the currently buffered data.
151 ///
152 /// raw_ostream guarantees to only call this routine when there is
153 /// buffered data, i.e. OutBufStart != OutBufCur.
154 virtual void flush_impl() = 0;
153 /// write_impl - The is the piece of the class that is implemented
154 /// by subclasses. This writes the \args Size bytes starting at
155 /// \arg Ptr to the underlying stream.
156 ///
157 /// \invariant { Size > 0 }
158 virtual void write_impl(const char *Ptr, unsigned Size) = 0;
155159
156160 // An out of line virtual method to provide a home for the class vtable.
157161 virtual void handle();
176180 int FD;
177181 bool ShouldClose;
178182 uint64_t pos;
183
184 /// write_impl - See raw_ostream::write_impl.
185 virtual void write_impl(const char *Ptr, unsigned Size);
179186 public:
180187 /// raw_fd_ostream - Open the specified file for writing. If an
181188 /// error occurs, information about the error is put into ErrorInfo,
196203
197204 ~raw_fd_ostream();
198205
199 /// flush_impl - The is the piece of the class that is implemented by
200 /// subclasses. This only outputs the currently buffered data.
201 ///
202 /// raw_ostream guarantees to only call this routine when there is
203 /// buffered data, i.e. OutBufStart != OutBufCur.
204 virtual void flush_impl();
205
206206 /// close - Manually flush the stream and close the file.
207207 void close();
208208
209209 /// tell - Return the current offset with the file.
210 uint64_t tell() {
211 return pos + (OutBufCur - OutBufStart);
212 }
210 uint64_t tell() { return pos + GetNumBytesInBuffer(); }
213211
214212 /// seek - Flushes the stream and repositions the underlying file descriptor
215213 /// positition to the offset specified from the beginning of the file.
251249 /// simple adaptor class.
252250 class raw_os_ostream : public raw_ostream {
253251 std::ostream &OS;
252
253 /// write_impl - See raw_ostream::write_impl.
254 virtual void write_impl(const char *Ptr, unsigned Size);
254255 public:
255256 raw_os_ostream(std::ostream &O) : OS(O) {}
256257 ~raw_os_ostream();
257
258 /// flush_impl - The is the piece of the class that is implemented by
259 /// subclasses. This only outputs the currently buffered data.
260 ///
261 /// raw_ostream guarantees to only call this routine when there is
262 /// buffered data, i.e. OutBufStart != OutBufCur.
263 virtual void flush_impl();
264258 };
265259
266260 /// raw_string_ostream - A raw_ostream that writes to an std::string. This is a
267261 /// simple adaptor class.
268262 class raw_string_ostream : public raw_ostream {
269263 std::string &OS;
264
265 /// write_impl - See raw_ostream::write_impl.
266 virtual void write_impl(const char *Ptr, unsigned Size);
270267 public:
271268 raw_string_ostream(std::string &O) : OS(O) {}
272269 ~raw_string_ostream();
277274 flush();
278275 return OS;
279276 }
280
281 /// flush_impl - The is the piece of the class that is implemented by
282 /// subclasses. This only outputs the currently buffered data.
283 ///
284 /// raw_ostream guarantees to only call this routine when there is
285 /// buffered data, i.e. OutBufStart != OutBufCur.
286 virtual void flush_impl();
287277 };
288278
289279 /// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
290280 /// SmallString. This is a simple adaptor class.
291281 class raw_svector_ostream : public raw_ostream {
292282 SmallVectorImpl &OS;
283
284 /// write_impl - See raw_ostream::write_impl.
285 virtual void write_impl(const char *Ptr, unsigned Size);
293286 public:
294287 raw_svector_ostream(SmallVectorImpl &O) : OS(O) {}
295288 ~raw_svector_ostream();
296
297 /// flush_impl - The is the piece of the class that is implemented by
298 /// subclasses. This only outputs the currently buffered data.
299 ///
300 /// raw_ostream guarantees to only call this routine when there is
301 /// buffered data, i.e. OutBufStart != OutBufCur.
302 virtual void flush_impl();
303289 };
304290
305291 } // end llvm namespace
117117
118118 void raw_ostream::flush_nonempty() {
119119 assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
120 flush_impl();
120 write_impl(OutBufStart, OutBufCur - OutBufStart);
121121 OutBufCur = OutBufStart;
122122 }
123123
150150 if (Size <= unsigned(OutBufEnd-OutBufStart)) {
151151 memcpy(OutBufCur, Ptr, Size);
152152 break;
153 }
154
155 // If emitting a string larger than our buffer, emit in chunks. In this
156 // case we know that we just flushed the buffer.
157 while (Size) {
158 unsigned NumToEmit = OutBufEnd-OutBufStart;
159 if (Size < NumToEmit) NumToEmit = Size;
160 assert(OutBufCur == OutBufStart);
161 memcpy(OutBufStart, Ptr, NumToEmit);
162 Ptr += NumToEmit;
163 Size -= NumToEmit;
164 OutBufCur = OutBufStart + NumToEmit;
165 flush_nonempty();
166 }
153 }
154
155 // Otherwise we are emitting a string larger than our buffer. We
156 // know we already flushed, so just write it out directly.
157 write_impl(Ptr, Size);
158 Size = 0;
167159 break;
168160 }
169161 OutBufCur += Size;
267259 }
268260 }
269261
270 void raw_fd_ostream::flush_impl() {
262 void raw_fd_ostream::write_impl(const char *Ptr, unsigned Size) {
271263 assert (FD >= 0 && "File already closed.");
272 pos += (OutBufCur - OutBufStart);
273 ::write(FD, OutBufStart, OutBufCur-OutBufStart);
264 pos += Size;
265 ::write(FD, Ptr, Size);
274266 }
275267
276268 void raw_fd_ostream::close() {
321313 flush();
322314 }
323315
324 /// flush_impl - The is the piece of the class that is implemented by
325 /// subclasses. This outputs the currently buffered data and resets the
326 /// buffer to empty.
327 void raw_os_ostream::flush_impl() {
328 OS.write(OutBufStart, OutBufCur-OutBufStart);
316 void raw_os_ostream::write_impl(const char *Ptr, unsigned Size) {
317 OS.write(Ptr, Size);
329318 }
330319
331320 //===----------------------------------------------------------------------===//
336325 flush();
337326 }
338327
339 /// flush_impl - The is the piece of the class that is implemented by
340 /// subclasses. This outputs the currently buffered data and resets the
341 /// buffer to empty.
342 void raw_string_ostream::flush_impl() {
343 OS.append(OutBufStart, OutBufCur-OutBufStart);
328 void raw_string_ostream::write_impl(const char *Ptr, unsigned Size) {
329 OS.append(Ptr, Size);
344330 }
345331
346332 //===----------------------------------------------------------------------===//
351337 flush();
352338 }
353339
354 /// flush_impl - The is the piece of the class that is implemented by
355 /// subclasses. This outputs the currently buffered data and resets the
356 /// buffer to empty.
357 void raw_svector_ostream::flush_impl() {
358 OS.append(OutBufStart, OutBufCur);
359 }
360
340 void raw_svector_ostream::write_impl(const char *Ptr, unsigned Size) {
341 OS.append(Ptr, Ptr + Size);
342 }
343