1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

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.

llvm-svn: 67057
This commit is contained in:
Daniel Dunbar 2009-03-16 22:55:06 +00:00
parent f15b4edb34
commit c2d554fe0b
2 changed files with 59 additions and 44 deletions

View File

@ -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();
};

View File

@ -116,17 +116,27 @@ raw_ostream &raw_ostream::operator<<(const void *P) {
return write(CurPtr, EndPtr-CurPtr);
}
raw_ostream &raw_ostream::write(unsigned char C) {
if (OutBufCur >= OutBufEnd)
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 (!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();
}
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();
}
//===----------------------------------------------------------------------===//
@ -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();
}
//===----------------------------------------------------------------------===//
@ -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();
}