llvm.org GIT mirror llvm / 33e49ef
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 Dan Gohman 10 years ago
2 changed file(s) with 30 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
260260 /// non-empty. This outputs the currently buffered data and resets
261261 /// the buffer to empty.
262262 void flush_nonempty();
263
264 /// copy_to_buffer - Copy data into the buffer. Size must not be
265 /// greater than the number of unused bytes in the buffer.
266 void copy_to_buffer(const char *Ptr, size_t Size);
263267 };
264268
265269 //===----------------------------------------------------------------------===//
163163 raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
164164 // Group exceptional cases into a single branch.
165165 if (BUILTIN_EXPECT(OutBufCur+Size > OutBufEnd, false)) {
166 if (Unbuffered) {
167 write_impl(Ptr, Size);
168 return *this;
166 if (BUILTIN_EXPECT(!OutBufStart, false)) {
167 if (Unbuffered) {
168 write_impl(Ptr, Size);
169 return *this;
170 }
171 // Set up a buffer and start over.
172 SetBufferSize();
173 return write(Ptr, Size);
169174 }
170
171 if (!OutBufStart)
172 SetBufferSize();
173 else
175 // Write out the data in buffer-sized blocks until the remainder
176 // fits within the buffer.
177 do {
178 size_t NumBytes = OutBufEnd - OutBufCur;
179 copy_to_buffer(Ptr, NumBytes);
174180 flush_nonempty();
175 }
176
181 Ptr += NumBytes;
182 Size -= NumBytes;
183 } while (OutBufCur+Size > OutBufEnd);
184 }
185
186 copy_to_buffer(Ptr, Size);
187
188 return *this;
189 }
190
191 void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
177192 // Handle short strings specially, memcpy isn't very good at very short
178193 // strings.
179194 switch (Size) {
183198 case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH
184199 case 0: break;
185200 default:
186 // Normally the string to emit is shorter than the buffer.
187 if (Size <= unsigned(OutBufEnd-OutBufCur)) {
188 memcpy(OutBufCur, Ptr, Size);
189 break;
190 }
191
192 // Otherwise we are emitting a string larger than our buffer. We
193 // know we already flushed, so just write it out directly.
194 write_impl(Ptr, Size);
195 Size = 0;
201 memcpy(OutBufCur, Ptr, Size);
196202 break;
197203 }
204
198205 OutBufCur += Size;
199
200 return *this;
201206 }
202207
203208 // Formatted output.