1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
13 #include "cmUVHandlePtr.h"
14 #include "cmUVStreambuf.h"
16 template <typename CharT
, typename Traits
= std::char_traits
<CharT
>>
17 class cmBasicUVIStream
: public std::basic_istream
<CharT
>
21 cmBasicUVIStream(uv_stream_t
* stream
);
25 void open(uv_stream_t
* stream
);
30 cmBasicUVStreambuf
<CharT
, Traits
> Buffer
;
33 template <typename CharT
, typename Traits
>
34 cmBasicUVIStream
<CharT
, Traits
>::cmBasicUVIStream()
35 : std::basic_istream
<CharT
, Traits
>(&this->Buffer
)
39 template <typename CharT
, typename Traits
>
40 cmBasicUVIStream
<CharT
, Traits
>::cmBasicUVIStream(uv_stream_t
* stream
)
46 template <typename CharT
, typename Traits
>
47 bool cmBasicUVIStream
<CharT
, Traits
>::is_open() const
49 return this->Buffer
.is_open();
52 template <typename CharT
, typename Traits
>
53 void cmBasicUVIStream
<CharT
, Traits
>::open(uv_stream_t
* stream
)
55 this->Buffer
.open(stream
);
58 template <typename CharT
, typename Traits
>
59 void cmBasicUVIStream
<CharT
, Traits
>::close()
64 using cmUVIStream
= cmBasicUVIStream
<char>;
66 template <typename CharT
, typename Traits
= std::char_traits
<CharT
>>
67 class cmBasicUVPipeIStream
: public cmBasicUVIStream
<CharT
, Traits
>
70 cmBasicUVPipeIStream();
71 cmBasicUVPipeIStream(uv_loop_t
& loop
, int fd
);
73 using cmBasicUVIStream
<CharT
, Traits
>::is_open
;
75 void open(uv_loop_t
& loop
, int fd
);
83 template <typename CharT
, typename Traits
>
84 cmBasicUVPipeIStream
<CharT
, Traits
>::cmBasicUVPipeIStream() = default;
86 template <typename CharT
, typename Traits
>
87 cmBasicUVPipeIStream
<CharT
, Traits
>::cmBasicUVPipeIStream(uv_loop_t
& loop
,
93 template <typename CharT
, typename Traits
>
94 void cmBasicUVPipeIStream
<CharT
, Traits
>::open(uv_loop_t
& loop
, int fd
)
96 this->Pipe
.init(loop
, 0);
97 uv_pipe_open(this->Pipe
, fd
);
98 this->cmBasicUVIStream
<CharT
, Traits
>::open(this->Pipe
);
101 template <typename CharT
, typename Traits
>
102 void cmBasicUVPipeIStream
<CharT
, Traits
>::close()
104 this->cmBasicUVIStream
<CharT
, Traits
>::close();
108 using cmUVPipeIStream
= cmBasicUVPipeIStream
<char>;
110 class cmUVStreamReadHandle
113 std::vector
<char> Buffer
;
114 std::function
<void(std::vector
<char>)> OnRead
;
115 std::function
<void()> OnFinish
;
117 template <typename ReadCallback
, typename FinishCallback
>
118 friend std::unique_ptr
<cmUVStreamReadHandle
> cmUVStreamRead(
119 uv_stream_t
* stream
, ReadCallback onRead
, FinishCallback onFinish
);
122 template <typename ReadCallback
, typename FinishCallback
>
123 std::unique_ptr
<cmUVStreamReadHandle
> cmUVStreamRead(uv_stream_t
* stream
,
125 FinishCallback onFinish
)
127 auto handle
= cm::make_unique
<cmUVStreamReadHandle
>();
128 handle
->OnRead
= std::move(onRead
);
129 handle
->OnFinish
= std::move(onFinish
);
131 stream
->data
= handle
.get();
134 [](uv_handle_t
* s
, std::size_t suggestedSize
, uv_buf_t
* buffer
) {
135 auto* data
= static_cast<cmUVStreamReadHandle
*>(s
->data
);
136 data
->Buffer
.resize(suggestedSize
);
137 buffer
->base
= data
->Buffer
.data();
138 buffer
->len
= suggestedSize
;
140 [](uv_stream_t
* s
, ssize_t nread
, const uv_buf_t
* buffer
) {
141 auto* data
= static_cast<cmUVStreamReadHandle
*>(s
->data
);
144 assert(buffer
->base
== data
->Buffer
.data());
145 data
->Buffer
.resize(nread
);
146 data
->OnRead(std::move(data
->Buffer
));
147 } else if (nread
< 0 /*|| nread == UV_EOF*/) {