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
This commit is contained in:
Daniel Dunbar 2009-03-16 23:29:31 +00:00
parent cf2a2c6a26
commit 89a66a96fe
2 changed files with 39 additions and 70 deletions

View File

@ -30,7 +30,7 @@ namespace llvm {
/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
/// a chunk at a time.
class raw_ostream {
protected:
private:
/// \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. }
@ -75,6 +75,10 @@ public:
flush();
}
unsigned GetNumBytesInBuffer() const {
return OutBufCur - OutBufStart;
}
//===--------------------------------------------------------------------===//
// Data Output Interface
//===--------------------------------------------------------------------===//
@ -147,12 +151,12 @@ public:
//===--------------------------------------------------------------------===//
private:
/// flush_impl - The is the piece of the class that is implemented by
/// 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;
/// write_impl - The is the piece of the class that is implemented
/// by subclasses. This writes the \args Size bytes starting at
/// \arg Ptr to the underlying stream.
///
/// \invariant { Size > 0 }
virtual void write_impl(const char *Ptr, unsigned Size) = 0;
// An out of line virtual method to provide a home for the class vtable.
virtual void handle();
@ -177,6 +181,9 @@ class raw_fd_ostream : public raw_ostream {
int FD;
bool ShouldClose;
uint64_t pos;
/// write_impl - See raw_ostream::write_impl.
virtual void write_impl(const char *Ptr, unsigned Size);
public:
/// raw_fd_ostream - Open the specified file for writing. If an
/// error occurs, information about the error is put into ErrorInfo,
@ -197,20 +204,11 @@ public:
~raw_fd_ostream();
/// flush_impl - The is the piece of the class that is implemented by
/// 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.
void close();
/// tell - Return the current offset with the file.
uint64_t tell() {
return pos + (OutBufCur - OutBufStart);
}
uint64_t tell() { return pos + GetNumBytesInBuffer(); }
/// seek - Flushes the stream and repositions the underlying file descriptor
/// positition to the offset specified from the beginning of the file.
@ -252,22 +250,21 @@ raw_ostream &errs();
/// simple adaptor class.
class raw_os_ostream : public raw_ostream {
std::ostream &OS;
/// write_impl - See raw_ostream::write_impl.
virtual void write_impl(const char *Ptr, unsigned Size);
public:
raw_os_ostream(std::ostream &O) : OS(O) {}
~raw_os_ostream();
/// flush_impl - The is the piece of the class that is implemented by
/// 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();
};
/// raw_string_ostream - A raw_ostream that writes to an std::string. This is a
/// simple adaptor class.
class raw_string_ostream : public raw_ostream {
std::string &OS;
/// write_impl - See raw_ostream::write_impl.
virtual void write_impl(const char *Ptr, unsigned Size);
public:
raw_string_ostream(std::string &O) : OS(O) {}
~raw_string_ostream();
@ -278,29 +275,18 @@ public:
flush();
return OS;
}
/// flush_impl - The is the piece of the class that is implemented by
/// 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();
};
/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
/// SmallString. This is a simple adaptor class.
class raw_svector_ostream : public raw_ostream {
SmallVectorImpl<char> &OS;
/// write_impl - See raw_ostream::write_impl.
virtual void write_impl(const char *Ptr, unsigned Size);
public:
raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {}
~raw_svector_ostream();
/// flush_impl - The is the piece of the class that is implemented by
/// 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();
};
} // end llvm namespace

View File

@ -118,7 +118,7 @@ raw_ostream &raw_ostream::operator<<(const void *P) {
void raw_ostream::flush_nonempty() {
assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
flush_impl();
write_impl(OutBufStart, OutBufCur - OutBufStart);
OutBufCur = OutBufStart;
}
@ -151,20 +151,12 @@ raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) {
if (Size <= unsigned(OutBufEnd-OutBufStart)) {
memcpy(OutBufCur, Ptr, Size);
break;
}
}
// If emitting a string larger than our buffer, emit in chunks. In this
// case we know that we just flushed the buffer.
while (Size) {
unsigned NumToEmit = OutBufEnd-OutBufStart;
if (Size < NumToEmit) NumToEmit = Size;
assert(OutBufCur == OutBufStart);
memcpy(OutBufStart, Ptr, NumToEmit);
Ptr += NumToEmit;
Size -= NumToEmit;
OutBufCur = OutBufStart + NumToEmit;
flush_nonempty();
}
// Otherwise we are emitting a string larger than our buffer. We
// know we already flushed, so just write it out directly.
write_impl(Ptr, Size);
Size = 0;
break;
}
OutBufCur += Size;
@ -268,10 +260,10 @@ raw_fd_ostream::~raw_fd_ostream() {
}
}
void raw_fd_ostream::flush_impl() {
void raw_fd_ostream::write_impl(const char *Ptr, unsigned Size) {
assert (FD >= 0 && "File already closed.");
pos += (OutBufCur - OutBufStart);
::write(FD, OutBufStart, OutBufCur-OutBufStart);
pos += Size;
::write(FD, Ptr, Size);
}
void raw_fd_ostream::close() {
@ -322,11 +314,8 @@ raw_os_ostream::~raw_os_ostream() {
flush();
}
/// 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.
void raw_os_ostream::flush_impl() {
OS.write(OutBufStart, OutBufCur-OutBufStart);
void raw_os_ostream::write_impl(const char *Ptr, unsigned Size) {
OS.write(Ptr, Size);
}
//===----------------------------------------------------------------------===//
@ -337,11 +326,8 @@ raw_string_ostream::~raw_string_ostream() {
flush();
}
/// 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.
void raw_string_ostream::flush_impl() {
OS.append(OutBufStart, OutBufCur-OutBufStart);
void raw_string_ostream::write_impl(const char *Ptr, unsigned Size) {
OS.append(Ptr, Size);
}
//===----------------------------------------------------------------------===//
@ -352,10 +338,7 @@ raw_svector_ostream::~raw_svector_ostream() {
flush();
}
/// 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.
void raw_svector_ostream::flush_impl() {
OS.append(OutBufStart, OutBufCur);
void raw_svector_ostream::write_impl(const char *Ptr, unsigned Size) {
OS.append(Ptr, Ptr + Size);
}