summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/cmUVStream.h102
-rw-r--r--Tests/CMakeLib/testUVStreambuf.cxx40
3 files changed, 143 insertions, 0 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index b01e1e7..a79366e 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -438,6 +438,7 @@ add_library(
cmUVHandlePtr.h
cmUVProcessChain.cxx
cmUVProcessChain.h
+ cmUVStream.h
cmUVStreambuf.h
cmUVSignalHackRAII.h
cmVariableWatch.cxx
diff --git a/Source/cmUVStream.h b/Source/cmUVStream.h
new file mode 100644
index 0000000..fff2381
--- /dev/null
+++ b/Source/cmUVStream.h
@@ -0,0 +1,102 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <istream>
+
+#include "cmUVHandlePtr.h"
+#include "cmUVStreambuf.h"
+
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+class cmBasicUVIStream : public std::basic_istream<CharT>
+{
+public:
+ cmBasicUVIStream();
+ cmBasicUVIStream(uv_stream_t* stream);
+
+ bool is_open() const;
+
+ void open(uv_stream_t* stream);
+
+ void close();
+
+private:
+ cmBasicUVStreambuf<CharT, Traits> Buffer;
+};
+
+template <typename CharT, typename Traits>
+cmBasicUVIStream<CharT, Traits>::cmBasicUVIStream()
+ : std::basic_istream<CharT, Traits>(&this->Buffer)
+{
+}
+
+template <typename CharT, typename Traits>
+cmBasicUVIStream<CharT, Traits>::cmBasicUVIStream(uv_stream_t* stream)
+ : cmBasicUVIStream()
+{
+ this->open(stream);
+}
+
+template <typename CharT, typename Traits>
+bool cmBasicUVIStream<CharT, Traits>::is_open() const
+{
+ return this->Buffer.is_open();
+}
+
+template <typename CharT, typename Traits>
+void cmBasicUVIStream<CharT, Traits>::open(uv_stream_t* stream)
+{
+ this->Buffer.open(stream);
+}
+
+template <typename CharT, typename Traits>
+void cmBasicUVIStream<CharT, Traits>::close()
+{
+ this->Buffer.close();
+}
+
+using cmUVIStream = cmBasicUVIStream<char>;
+
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+class cmBasicUVPipeIStream : public cmBasicUVIStream<CharT, Traits>
+{
+public:
+ cmBasicUVPipeIStream();
+ cmBasicUVPipeIStream(uv_loop_t& loop, int fd);
+
+ using cmBasicUVIStream<CharT, Traits>::is_open;
+
+ void open(uv_loop_t& loop, int fd);
+
+ void close();
+
+private:
+ cm::uv_pipe_ptr Pipe;
+};
+
+template <typename CharT, typename Traits>
+cmBasicUVPipeIStream<CharT, Traits>::cmBasicUVPipeIStream() = default;
+
+template <typename CharT, typename Traits>
+cmBasicUVPipeIStream<CharT, Traits>::cmBasicUVPipeIStream(uv_loop_t& loop,
+ int fd)
+{
+ this->open(loop, fd);
+}
+
+template <typename CharT, typename Traits>
+void cmBasicUVPipeIStream<CharT, Traits>::open(uv_loop_t& loop, int fd)
+{
+ this->Pipe.init(loop, 0);
+ uv_pipe_open(this->Pipe, fd);
+ this->cmBasicUVIStream<CharT, Traits>::open(this->Pipe);
+}
+
+template <typename CharT, typename Traits>
+void cmBasicUVPipeIStream<CharT, Traits>::close()
+{
+ this->cmBasicUVIStream<CharT, Traits>::close();
+ this->Pipe.reset();
+}
+
+using cmUVPipeIStream = cmBasicUVPipeIStream<char>;
diff --git a/Tests/CMakeLib/testUVStreambuf.cxx b/Tests/CMakeLib/testUVStreambuf.cxx
index f9ed6af..c97e695 100644
--- a/Tests/CMakeLib/testUVStreambuf.cxx
+++ b/Tests/CMakeLib/testUVStreambuf.cxx
@@ -8,6 +8,7 @@
#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"
+#include "cmUVStream.h"
#include "cmUVStreambuf.h"
#define TEST_STR_LINE_1 "This string must be exactly 128 characters long so"
@@ -437,6 +438,40 @@ end:
return success;
}
+bool testUVPipeIStream()
+{
+ int pipe[] = { -1, -1 };
+ if (cmGetPipes(pipe) < 0) {
+ std::cout << "cmGetPipes() returned an error" << std::endl;
+ return false;
+ }
+
+ cm::uv_loop_ptr loop;
+ loop.init();
+ cm::uv_pipe_ptr pipeSink;
+ pipeSink.init(*loop, 0);
+ uv_pipe_open(pipeSink, pipe[1]);
+
+ std::string str = "Hello world!\n";
+ uv_write_t writeReq;
+ uv_buf_t buf;
+ buf.base = &str.front();
+ buf.len = str.length();
+ uv_write(&writeReq, pipeSink, &buf, 1, nullptr);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ cmUVPipeIStream pin(*loop, pipe[0]);
+ std::string line;
+ std::getline(pin, line);
+ if (line != "Hello world!") {
+ std::cout << "Line was \"" << line << "\", should be \"Hello world!\""
+ << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
int testUVStreambuf(int argc, char** const argv)
{
if (argc < 2) {
@@ -454,5 +489,10 @@ int testUVStreambuf(int argc, char** const argv)
return -1;
}
+ if (!testUVPipeIStream()) {
+ std::cout << "While executing testUVPipeIStream().\n";
+ return -1;
+ }
+
return 0;
}