Переглянути джерело

cmUVPipeIStream: Add cmUVPipeIStream

Kyle Edwards 2 роки тому
батько
коміт
ec81d40be4
3 змінених файлів з 143 додано та 0 видалено
  1. 1 0
      Source/CMakeLists.txt
  2. 102 0
      Source/cmUVStream.h
  3. 40 0
      Tests/CMakeLib/testUVStreambuf.cxx

+ 1 - 0
Source/CMakeLists.txt

@@ -438,6 +438,7 @@ add_library(
   cmUVHandlePtr.h
   cmUVProcessChain.cxx
   cmUVProcessChain.h
+  cmUVStream.h
   cmUVStreambuf.h
   cmUVSignalHackRAII.h
   cmVariableWatch.cxx

+ 102 - 0
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>;

+ 40 - 0
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;
 }