From cf2a2c6a26427733f31dd539c6ee6486ea191da2 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 16 Mar 2009 22:55:06 +0000 Subject: [PATCH] raw_ostream: Lift out flush_nonempty. - Flush a known non-empty buffers; enforces the interface to flush_impl and kills off HandleFlush (which I saw no reason to be an inline method, Chris?). - Clarify invariant that flush_impl is only called with OutBufCur > OutBufStart. - This also cleary collects all places where we have to deal with the buffer possibly not existing. - A few more comments and fixing the unbuffered behavior remain in this commit sequence. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67057 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/raw_ostream.h | 62 ++++++++++++++++++------------ lib/Support/raw_ostream.cpp | 41 ++++++++++---------- 2 files changed, 59 insertions(+), 44 deletions(-) diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 85746599005..7ea182b0d7b 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -31,6 +31,10 @@ namespace llvm { /// a chunk at a time. class raw_ostream { protected: + /// \invariant { The buffer is uninitialized (OutBufStart, + /// OutBufEnd, and OutBufCur are non-zero), or none of them are zero + /// and there are at least 64 total bytes in the buffer. } + char *OutBufStart, *OutBufEnd, *OutBufCur; bool Unbuffered; @@ -77,7 +81,7 @@ public: void flush() { if (OutBufCur != OutBufStart) - flush_impl(); + flush_nonempty(); } raw_ostream &operator<<(char C) { @@ -85,7 +89,7 @@ public: return write(C); *OutBufCur++ = C; if (Unbuffered) - flush_impl(); + flush_nonempty(); return *this; } @@ -94,7 +98,7 @@ public: return write(C); *OutBufCur++ = C; if (Unbuffered) - flush_impl(); + flush_nonempty(); return *this; } @@ -103,7 +107,7 @@ public: return write(C); *OutBufCur++ = C; if (Unbuffered) - flush_impl(); + flush_nonempty(); return *this; } @@ -142,23 +146,25 @@ public: // Subclass Interface //===--------------------------------------------------------------------===// -protected: - +private: /// flush_impl - The is the piece of the class that is implemented by - /// subclasses. This outputs the currently buffered data and resets the - /// buffer to empty. + /// subclasses. This only outputs the currently buffered data. + /// + /// raw_ostream guarantees to only call this routine when there is + /// buffered data, i.e. OutBufStart != OutBufCur. virtual void flush_impl() = 0; - /// HandleFlush - A stream's implementation of flush should call this after - /// emitting the bytes to the data sink. - void HandleFlush() { - if (OutBufStart == 0) - SetBufferSize(4096); - OutBufCur = OutBufStart; - } -private: // An out of line virtual method to provide a home for the class vtable. virtual void handle(); + + //===--------------------------------------------------------------------===// + // Private Interface + //===--------------------------------------------------------------------===// +private: + /// flush_nonempty - Flush the current buffer, which is known to be + /// non-empty. This outputs the currently buffered data and resets + /// the buffer to empty. + void flush_nonempty(); }; //===----------------------------------------------------------------------===// @@ -192,8 +198,10 @@ public: ~raw_fd_ostream(); /// flush_impl - The is the piece of the class that is implemented by - /// subclasses. This outputs the currently buffered data and resets the - /// buffer to empty. + /// subclasses. This only outputs the currently buffered data. + /// + /// raw_ostream guarantees to only call this routine when there is + /// buffered data, i.e. OutBufStart != OutBufCur. virtual void flush_impl(); /// close - Manually flush the stream and close the file. @@ -249,8 +257,10 @@ public: ~raw_os_ostream(); /// flush_impl - The is the piece of the class that is implemented by - /// subclasses. This outputs the currently buffered data and resets the - /// buffer to empty. + /// subclasses. This only outputs the currently buffered data. + /// + /// raw_ostream guarantees to only call this routine when there is + /// buffered data, i.e. OutBufStart != OutBufCur. virtual void flush_impl(); }; @@ -270,8 +280,10 @@ public: } /// flush_impl - The is the piece of the class that is implemented by - /// subclasses. This outputs the currently buffered data and resets the - /// buffer to empty. + /// subclasses. This only outputs the currently buffered data. + /// + /// raw_ostream guarantees to only call this routine when there is + /// buffered data, i.e. OutBufStart != OutBufCur. virtual void flush_impl(); }; @@ -284,8 +296,10 @@ public: ~raw_svector_ostream(); /// flush_impl - The is the piece of the class that is implemented by - /// subclasses. This outputs the currently buffered data and resets the - /// buffer to empty. + /// subclasses. This only outputs the currently buffered data. + /// + /// raw_ostream guarantees to only call this routine when there is + /// buffered data, i.e. OutBufStart != OutBufCur. virtual void flush_impl(); }; diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index 3c242424beb..bbd1994206f 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -116,17 +116,27 @@ raw_ostream &raw_ostream::operator<<(const void *P) { return write(CurPtr, EndPtr-CurPtr); } +void raw_ostream::flush_nonempty() { + assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty."); + flush_impl(); + OutBufCur = OutBufStart; +} + raw_ostream &raw_ostream::write(unsigned char C) { - if (OutBufCur >= OutBufEnd) - flush_impl(); + if (!OutBufStart) + SetBufferSize(4096); + else if (OutBufCur >= OutBufEnd) + flush_nonempty(); *OutBufCur++ = C; return *this; } raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) { - if (OutBufCur+Size > OutBufEnd) - flush_impl(); + if (!OutBufStart) + SetBufferSize(4096); + else if (OutBufCur+Size > OutBufEnd) + flush_nonempty(); // Handle short strings specially, memcpy isn't very good at very short // strings. @@ -153,14 +163,14 @@ raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) { Ptr += NumToEmit; Size -= NumToEmit; OutBufCur = OutBufStart + NumToEmit; - flush_impl(); + flush_nonempty(); } break; } OutBufCur += Size; if (Unbuffered) - flush_impl(); + flush(); return *this; } @@ -260,11 +270,8 @@ raw_fd_ostream::~raw_fd_ostream() { void raw_fd_ostream::flush_impl() { assert (FD >= 0 && "File already closed."); - if (OutBufCur-OutBufStart) { - pos += (OutBufCur - OutBufStart); - ::write(FD, OutBufStart, OutBufCur-OutBufStart); - } - HandleFlush(); + pos += (OutBufCur - OutBufStart); + ::write(FD, OutBufStart, OutBufCur-OutBufStart); } void raw_fd_ostream::close() { @@ -319,9 +326,7 @@ raw_os_ostream::~raw_os_ostream() { /// subclasses. This outputs the currently buffered data and resets the /// buffer to empty. void raw_os_ostream::flush_impl() { - if (OutBufCur-OutBufStart) - OS.write(OutBufStart, OutBufCur-OutBufStart); - HandleFlush(); + OS.write(OutBufStart, OutBufCur-OutBufStart); } //===----------------------------------------------------------------------===// @@ -336,9 +341,7 @@ raw_string_ostream::~raw_string_ostream() { /// subclasses. This outputs the currently buffered data and resets the /// buffer to empty. void raw_string_ostream::flush_impl() { - if (OutBufCur-OutBufStart) - OS.append(OutBufStart, OutBufCur-OutBufStart); - HandleFlush(); + OS.append(OutBufStart, OutBufCur-OutBufStart); } //===----------------------------------------------------------------------===// @@ -353,8 +356,6 @@ raw_svector_ostream::~raw_svector_ostream() { /// subclasses. This outputs the currently buffered data and resets the /// buffer to empty. void raw_svector_ostream::flush_impl() { - if (OutBufCur-OutBufStart) - OS.append(OutBufStart, OutBufCur); - HandleFlush(); + OS.append(OutBufStart, OutBufCur); } -- 2.34.1