diff options
author | Dan Gohman <gohman@apple.com> | 2009-08-13 15:44:52 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-08-13 15:44:52 +0000 |
commit | 072828e99bb310b69349dd1c0c1701f6ff655e02 (patch) | |
tree | 454bfbd24e64505c541c1355a0ced1e5c09ac0c3 /lib | |
parent | 7efa530000dcac8292d83b9ac3557b3ff7e4e7da (diff) | |
download | external_llvm-072828e99bb310b69349dd1c0c1701f6ff655e02.zip external_llvm-072828e99bb310b69349dd1c0c1701f6ff655e02.tar.gz external_llvm-072828e99bb310b69349dd1c0c1701f6ff655e02.tar.bz2 |
Fix the buffer handling logic so that write_impl is always called with
a full buffer, rather than often being called with a
slightly-less-than-full buffer.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78907 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Support/raw_ostream.cpp | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index e3ab0c6..11a11bd 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -164,17 +164,32 @@ raw_ostream &raw_ostream::write(unsigned char C) { raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) { // Group exceptional cases into a single branch. if (BUILTIN_EXPECT(OutBufCur+Size > OutBufEnd, false)) { - if (Unbuffered) { - write_impl(Ptr, Size); - return *this; - } - - if (!OutBufStart) + if (BUILTIN_EXPECT(!OutBufStart, false)) { + if (Unbuffered) { + write_impl(Ptr, Size); + return *this; + } + // Set up a buffer and start over. SetBufferSize(); - else + return write(Ptr, Size); + } + // Write out the data in buffer-sized blocks until the remainder + // fits within the buffer. + do { + size_t NumBytes = OutBufEnd - OutBufCur; + copy_to_buffer(Ptr, NumBytes); flush_nonempty(); + Ptr += NumBytes; + Size -= NumBytes; + } while (OutBufCur+Size > OutBufEnd); } - + + copy_to_buffer(Ptr, Size); + + return *this; +} + +void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) { // Handle short strings specially, memcpy isn't very good at very short // strings. switch (Size) { @@ -184,21 +199,11 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) { case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH case 0: break; default: - // Normally the string to emit is shorter than the buffer. - if (Size <= unsigned(OutBufEnd-OutBufCur)) { - memcpy(OutBufCur, Ptr, Size); - break; - } - - // 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; + memcpy(OutBufCur, Ptr, Size); break; } - OutBufCur += Size; - return *this; + OutBufCur += Size; } // Formatted output. |