<div dir="ltr">Just wanted to say, thanks for the iterations here, I like the end result a lot. =]<br></div><br><div class="gmail_quote">On Tue, Apr 14, 2015 at 8:08 AM Rafael Espindola <<a href="mailto:rafael.espindola@gmail.com">rafael.espindola@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rafael<br>
Date: Tue Apr 14 10:00:34 2015<br>
New Revision: 234895<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=234895&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=234895&view=rev</a><br>
Log:<br>
Add raw_pwrite_stream type.<br>
<br>
This is a raw_ostream that also supports pwrite.<br>
I will be used in a sec.<br>
<br>
Added:<br>
llvm/trunk/unittests/Support/raw_pwrite_stream_test.cpp<br>
Modified:<br>
llvm/trunk/include/llvm/Support/raw_ostream.h<br>
llvm/trunk/lib/Support/raw_ostream.cpp<br>
llvm/trunk/unittests/Support/CMakeLists.txt<br>
<br>
Modified: llvm/trunk/include/llvm/Support/raw_ostream.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/raw_ostream.h?rev=234895&r1=234894&r2=234895&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/raw_ostream.h?rev=234895&r1=234894&r2=234895&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Support/raw_ostream.h (original)<br>
+++ llvm/trunk/include/llvm/Support/raw_ostream.h Tue Apr 14 10:00:34 2015<br>
@@ -313,13 +313,22 @@ private:<br>
void copy_to_buffer(const char *Ptr, size_t Size);<br>
};<br>
<br>
+/// An abstract base class for streams implementations that also support a<br>
+/// pwrite operation. This is usefull for code that can mostly stream out data,<br>
+/// but needs to patch in a header that needs to know the output size.<br>
+class raw_pwrite_stream : public raw_ostream {<br>
+public:<br>
+ using raw_ostream::raw_ostream;<br>
+ virtual void pwrite(const char *Ptr, size_t Size, uint64_t Offset) = 0;<br>
+};<br>
+<br>
//===----------------------------------------------------------------------===//<br>
// File Output Streams<br>
//===----------------------------------------------------------------------===//<br>
<br>
/// A raw_ostream that writes to a file descriptor.<br>
///<br>
-class raw_fd_ostream : public raw_ostream {<br>
+class raw_fd_ostream : public raw_pwrite_stream {<br>
int FD;<br>
bool ShouldClose;<br>
<br>
@@ -378,6 +387,8 @@ public:<br>
/// to the offset specified from the beginning of the file.<br>
uint64_t seek(uint64_t off);<br>
<br>
+ void pwrite(const char *Ptr, size_t Size, uint64_t Offset) override;<br>
+<br>
/// Set the stream to attempt to use atomic writes for individual output<br>
/// routines where possible.<br>
///<br>
@@ -460,7 +471,7 @@ public:<br>
<br>
/// A raw_ostream that writes to an SmallVector or SmallString. This is a<br>
/// simple adaptor class. This class does not encounter output errors.<br>
-class raw_svector_ostream : public raw_ostream {<br>
+class raw_svector_ostream : public raw_pwrite_stream {<br>
SmallVectorImpl<char> &OS;<br>
<br>
/// See raw_ostream::write_impl.<br>
@@ -469,6 +480,12 @@ class raw_svector_ostream : public raw_o<br>
/// Return the current position within the stream, not counting the bytes<br>
/// currently in the buffer.<br>
uint64_t current_pos() const override;<br>
+<br>
+protected:<br>
+ // Like the regular constructor, but doesn't call init.<br>
+ explicit raw_svector_ostream(SmallVectorImpl<char> &O, unsigned);<br>
+ void init();<br>
+<br>
public:<br>
/// Construct a new raw_svector_ostream.<br>
///<br>
@@ -477,6 +494,8 @@ public:<br>
explicit raw_svector_ostream(SmallVectorImpl<char> &O);<br>
~raw_svector_ostream() override;<br>
<br>
+ void pwrite(const char *Ptr, size_t Size, uint64_t Offset) override;<br>
+<br>
/// This is called when the SmallVector we're appending to is changed outside<br>
/// of the raw_svector_ostream's control. It is only safe to do this if the<br>
/// raw_svector_ostream has previously been flushed.<br>
@@ -488,7 +507,7 @@ public:<br>
};<br>
<br>
/// A raw_ostream that discards all output.<br>
-class raw_null_ostream : public raw_ostream {<br>
+class raw_null_ostream : public raw_pwrite_stream {<br>
/// See raw_ostream::write_impl.<br>
void write_impl(const char *Ptr, size_t size) override;<br>
<br>
@@ -499,6 +518,18 @@ class raw_null_ostream : public raw_ostr<br>
public:<br>
explicit raw_null_ostream() {}<br>
~raw_null_ostream() override;<br>
+ void pwrite(const char *Ptr, size_t Size, uint64_t Offset) override;<br>
+};<br>
+<br>
+class buffer_ostream : public raw_svector_ostream {<br>
+ raw_ostream &OS;<br>
+ SmallVector<char, 0> Buffer;<br>
+<br>
+public:<br>
+ buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer, 0), OS(OS) {<br>
+ init();<br>
+ }<br>
+ ~buffer_ostream() { OS << str(); }<br>
};<br>
<br>
} // end llvm namespace<br>
<br>
Modified: llvm/trunk/lib/Support/raw_ostream.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/raw_ostream.cpp?rev=234895&r1=234894&r2=234895&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/raw_ostream.cpp?rev=234895&r1=234894&r2=234895&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Support/raw_ostream.cpp (original)<br>
+++ llvm/trunk/lib/Support/raw_ostream.cpp Tue Apr 14 10:00:34 2015<br>
@@ -516,8 +516,8 @@ raw_fd_ostream::raw_fd_ostream(StringRef<br>
/// FD is the file descriptor that this writes to. If ShouldClose is true, this<br>
/// closes the file when the stream is destroyed.<br>
raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)<br>
- : raw_ostream(unbuffered), FD(fd),<br>
- ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) {<br>
+ : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose),<br>
+ Error(false), UseAtomicWrites(false) {<br>
if (FD < 0 ) {<br>
ShouldClose = false;<br>
return;<br>
@@ -630,6 +630,13 @@ uint64_t raw_fd_ostream::seek(uint64_t o<br>
return pos;<br>
}<br>
<br>
+void raw_fd_ostream::pwrite(const char *Ptr, size_t Size, uint64_t Offset) {<br>
+ uint64_t Pos = tell();<br>
+ seek(Offset);<br>
+ write(Ptr, Size);<br>
+ seek(Pos);<br>
+}<br>
+<br>
size_t raw_fd_ostream::preferred_buffer_size() const {<br>
#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__minix)<br>
// Windows and Minix have no st_blksize.<br>
@@ -753,7 +760,14 @@ void raw_string_ostream::write_impl(cons<br>
// capacity. This allows raw_ostream to write directly into the correct place,<br>
// and we only need to set the vector size when the data is flushed.<br>
<br>
+raw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O, unsigned)<br>
+ : OS(O) {}<br>
+<br>
raw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {<br>
+ init();<br>
+}<br>
+<br>
+void raw_svector_ostream::init() {<br>
// Set up the initial external buffer. We make sure that the buffer has at<br>
// least 128 bytes free; raw_ostream itself only requires 64, but we want to<br>
// make sure that we don't grow the buffer unnecessarily on destruction (when<br>
@@ -767,6 +781,17 @@ raw_svector_ostream::~raw_svector_ostrea<br>
flush();<br>
}<br>
<br>
+void raw_svector_ostream::pwrite(const char *Ptr, size_t Size,<br>
+ uint64_t Offset) {<br>
+ flush();<br>
+<br>
+ uint64_t End = Offset + Size;<br>
+ if (End > OS.size())<br>
+ OS.resize(End);<br>
+<br>
+ memcpy(OS.begin() + Offset, Ptr, Size);<br>
+}<br>
+<br>
/// resync - This is called when the SmallVector we're appending to is changed<br>
/// outside of the raw_svector_ostream's control. It is only safe to do this<br>
/// if the raw_svector_ostream has previously been flushed.<br>
@@ -821,3 +846,5 @@ void raw_null_ostream::write_impl(const<br>
uint64_t raw_null_ostream::current_pos() const {<br>
return 0;<br>
}<br>
+<br>
+void raw_null_ostream::pwrite(const char *Ptr, size_t Size, uint64_t Offset) {}<br>
<br>
Modified: llvm/trunk/unittests/Support/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=234895&r1=234894&r2=234895&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=234895&r1=234894&r2=234895&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/Support/CMakeLists.txt (original)<br>
+++ llvm/trunk/unittests/Support/CMakeLists.txt Tue Apr 14 10:00:34 2015<br>
@@ -44,6 +44,7 @@ add_llvm_unittest(SupportTests<br>
YAMLParserTest.cpp<br>
formatted_raw_ostream_test.cpp<br>
raw_ostream_test.cpp<br>
+ raw_pwrite_stream_test.cpp<br>
)<br>
<br>
# ManagedStatic.cpp uses <pthread>.<br>
<br>
Added: llvm/trunk/unittests/Support/raw_pwrite_stream_test.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/raw_pwrite_stream_test.cpp?rev=234895&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/raw_pwrite_stream_test.cpp?rev=234895&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/Support/raw_pwrite_stream_test.cpp (added)<br>
+++ llvm/trunk/unittests/Support/raw_pwrite_stream_test.cpp Tue Apr 14 10:00:34 2015<br>
@@ -0,0 +1,25 @@<br>
+//===- raw_pwrite_stream_test.cpp - raw_pwrite_stream tests ---------------===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "gtest/gtest.h"<br>
+#include "llvm/ADT/SmallString.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+namespace {<br>
+<br>
+TEST(raw_pwrite_ostreamTest, TestSVector) {<br>
+ SmallString<64> Buffer;<br>
+ raw_svector_ostream OS(Buffer);<br>
+ StringRef Test = "test";<br>
+ OS.pwrite(Test.data(), Test.size(), 0);<br>
+ EXPECT_EQ(Test, OS.str());<br>
+}<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>