mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-18 14:31:27 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67057 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4752bd3b40
commit
cf2a2c6a26
@ -31,6 +31,10 @@ namespace llvm {
|
|||||||
/// a chunk at a time.
|
/// a chunk at a time.
|
||||||
class raw_ostream {
|
class raw_ostream {
|
||||||
protected:
|
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;
|
char *OutBufStart, *OutBufEnd, *OutBufCur;
|
||||||
bool Unbuffered;
|
bool Unbuffered;
|
||||||
|
|
||||||
@ -77,7 +81,7 @@ public:
|
|||||||
|
|
||||||
void flush() {
|
void flush() {
|
||||||
if (OutBufCur != OutBufStart)
|
if (OutBufCur != OutBufStart)
|
||||||
flush_impl();
|
flush_nonempty();
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_ostream &operator<<(char C) {
|
raw_ostream &operator<<(char C) {
|
||||||
@ -85,7 +89,7 @@ public:
|
|||||||
return write(C);
|
return write(C);
|
||||||
*OutBufCur++ = C;
|
*OutBufCur++ = C;
|
||||||
if (Unbuffered)
|
if (Unbuffered)
|
||||||
flush_impl();
|
flush_nonempty();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +98,7 @@ public:
|
|||||||
return write(C);
|
return write(C);
|
||||||
*OutBufCur++ = C;
|
*OutBufCur++ = C;
|
||||||
if (Unbuffered)
|
if (Unbuffered)
|
||||||
flush_impl();
|
flush_nonempty();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +107,7 @@ public:
|
|||||||
return write(C);
|
return write(C);
|
||||||
*OutBufCur++ = C;
|
*OutBufCur++ = C;
|
||||||
if (Unbuffered)
|
if (Unbuffered)
|
||||||
flush_impl();
|
flush_nonempty();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,23 +146,25 @@ public:
|
|||||||
// Subclass Interface
|
// Subclass Interface
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
/// flush_impl - The is the piece of the class that is implemented by
|
/// flush_impl - The is the piece of the class that is implemented by
|
||||||
/// subclasses. This outputs the currently buffered data and resets the
|
/// subclasses. This only outputs the currently buffered data.
|
||||||
/// buffer to empty.
|
///
|
||||||
|
/// raw_ostream guarantees to only call this routine when there is
|
||||||
|
/// buffered data, i.e. OutBufStart != OutBufCur.
|
||||||
virtual void flush_impl() = 0;
|
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.
|
// An out of line virtual method to provide a home for the class vtable.
|
||||||
virtual void handle();
|
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();
|
~raw_fd_ostream();
|
||||||
|
|
||||||
/// flush_impl - The is the piece of the class that is implemented by
|
/// flush_impl - The is the piece of the class that is implemented by
|
||||||
/// subclasses. This outputs the currently buffered data and resets the
|
/// subclasses. This only outputs the currently buffered data.
|
||||||
/// buffer to empty.
|
///
|
||||||
|
/// raw_ostream guarantees to only call this routine when there is
|
||||||
|
/// buffered data, i.e. OutBufStart != OutBufCur.
|
||||||
virtual void flush_impl();
|
virtual void flush_impl();
|
||||||
|
|
||||||
/// close - Manually flush the stream and close the file.
|
/// close - Manually flush the stream and close the file.
|
||||||
@ -249,8 +257,10 @@ public:
|
|||||||
~raw_os_ostream();
|
~raw_os_ostream();
|
||||||
|
|
||||||
/// flush_impl - The is the piece of the class that is implemented by
|
/// flush_impl - The is the piece of the class that is implemented by
|
||||||
/// subclasses. This outputs the currently buffered data and resets the
|
/// subclasses. This only outputs the currently buffered data.
|
||||||
/// buffer to empty.
|
///
|
||||||
|
/// raw_ostream guarantees to only call this routine when there is
|
||||||
|
/// buffered data, i.e. OutBufStart != OutBufCur.
|
||||||
virtual void flush_impl();
|
virtual void flush_impl();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -270,8 +280,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// flush_impl - The is the piece of the class that is implemented by
|
/// flush_impl - The is the piece of the class that is implemented by
|
||||||
/// subclasses. This outputs the currently buffered data and resets the
|
/// subclasses. This only outputs the currently buffered data.
|
||||||
/// buffer to empty.
|
///
|
||||||
|
/// raw_ostream guarantees to only call this routine when there is
|
||||||
|
/// buffered data, i.e. OutBufStart != OutBufCur.
|
||||||
virtual void flush_impl();
|
virtual void flush_impl();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -284,8 +296,10 @@ public:
|
|||||||
~raw_svector_ostream();
|
~raw_svector_ostream();
|
||||||
|
|
||||||
/// flush_impl - The is the piece of the class that is implemented by
|
/// flush_impl - The is the piece of the class that is implemented by
|
||||||
/// subclasses. This outputs the currently buffered data and resets the
|
/// subclasses. This only outputs the currently buffered data.
|
||||||
/// buffer to empty.
|
///
|
||||||
|
/// raw_ostream guarantees to only call this routine when there is
|
||||||
|
/// buffered data, i.e. OutBufStart != OutBufCur.
|
||||||
virtual void flush_impl();
|
virtual void flush_impl();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,17 +116,27 @@ raw_ostream &raw_ostream::operator<<(const void *P) {
|
|||||||
return write(CurPtr, EndPtr-CurPtr);
|
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) {
|
raw_ostream &raw_ostream::write(unsigned char C) {
|
||||||
if (OutBufCur >= OutBufEnd)
|
if (!OutBufStart)
|
||||||
flush_impl();
|
SetBufferSize(4096);
|
||||||
|
else if (OutBufCur >= OutBufEnd)
|
||||||
|
flush_nonempty();
|
||||||
|
|
||||||
*OutBufCur++ = C;
|
*OutBufCur++ = C;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) {
|
raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) {
|
||||||
if (OutBufCur+Size > OutBufEnd)
|
if (!OutBufStart)
|
||||||
flush_impl();
|
SetBufferSize(4096);
|
||||||
|
else if (OutBufCur+Size > OutBufEnd)
|
||||||
|
flush_nonempty();
|
||||||
|
|
||||||
// Handle short strings specially, memcpy isn't very good at very short
|
// Handle short strings specially, memcpy isn't very good at very short
|
||||||
// strings.
|
// strings.
|
||||||
@ -153,14 +163,14 @@ raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) {
|
|||||||
Ptr += NumToEmit;
|
Ptr += NumToEmit;
|
||||||
Size -= NumToEmit;
|
Size -= NumToEmit;
|
||||||
OutBufCur = OutBufStart + NumToEmit;
|
OutBufCur = OutBufStart + NumToEmit;
|
||||||
flush_impl();
|
flush_nonempty();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
OutBufCur += Size;
|
OutBufCur += Size;
|
||||||
|
|
||||||
if (Unbuffered)
|
if (Unbuffered)
|
||||||
flush_impl();
|
flush();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,11 +270,8 @@ raw_fd_ostream::~raw_fd_ostream() {
|
|||||||
|
|
||||||
void raw_fd_ostream::flush_impl() {
|
void raw_fd_ostream::flush_impl() {
|
||||||
assert (FD >= 0 && "File already closed.");
|
assert (FD >= 0 && "File already closed.");
|
||||||
if (OutBufCur-OutBufStart) {
|
pos += (OutBufCur - OutBufStart);
|
||||||
pos += (OutBufCur - OutBufStart);
|
::write(FD, OutBufStart, OutBufCur-OutBufStart);
|
||||||
::write(FD, OutBufStart, OutBufCur-OutBufStart);
|
|
||||||
}
|
|
||||||
HandleFlush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void raw_fd_ostream::close() {
|
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
|
/// subclasses. This outputs the currently buffered data and resets the
|
||||||
/// buffer to empty.
|
/// buffer to empty.
|
||||||
void raw_os_ostream::flush_impl() {
|
void raw_os_ostream::flush_impl() {
|
||||||
if (OutBufCur-OutBufStart)
|
OS.write(OutBufStart, 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
|
/// subclasses. This outputs the currently buffered data and resets the
|
||||||
/// buffer to empty.
|
/// buffer to empty.
|
||||||
void raw_string_ostream::flush_impl() {
|
void raw_string_ostream::flush_impl() {
|
||||||
if (OutBufCur-OutBufStart)
|
OS.append(OutBufStart, 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
|
/// subclasses. This outputs the currently buffered data and resets the
|
||||||
/// buffer to empty.
|
/// buffer to empty.
|
||||||
void raw_svector_ostream::flush_impl() {
|
void raw_svector_ostream::flush_impl() {
|
||||||
if (OutBufCur-OutBufStart)
|
OS.append(OutBufStart, OutBufCur);
|
||||||
OS.append(OutBufStart, OutBufCur);
|
|
||||||
HandleFlush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user