diff options
-rw-r--r-- | Source/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/cmUVStream.h | 102 | ||||
-rw-r--r-- | Tests/CMakeLib/testUVStreambuf.cxx | 40 |
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; } |