summaryrefslogtreecommitdiffstats
path: root/Source/cmUVStream.h
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2023-06-09 19:51:09 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2023-06-14 15:53:55 (GMT)
commit0878306386d42084e8abc3525393ae2b65acf725 (patch)
treed2898e3d1a468132dc0893d35cd01e08f4164252 /Source/cmUVStream.h
parentb8fd273ed7b14ff71cd55d39ffb7c41c2f5ee421 (diff)
downloadCMake-0878306386d42084e8abc3525393ae2b65acf725.zip
CMake-0878306386d42084e8abc3525393ae2b65acf725.tar.gz
CMake-0878306386d42084e8abc3525393ae2b65acf725.tar.bz2
cmUVStream: Add cmUVStreamRead() function
Diffstat (limited to 'Source/cmUVStream.h')
-rw-r--r--Source/cmUVStream.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/Source/cmUVStream.h b/Source/cmUVStream.h
index fff2381..5998256 100644
--- a/Source/cmUVStream.h
+++ b/Source/cmUVStream.h
@@ -2,8 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include <cassert>
#include <istream>
+#include <cm3p/uv.h>
+
#include "cmUVHandlePtr.h"
#include "cmUVStreambuf.h"
@@ -100,3 +103,38 @@ void cmBasicUVPipeIStream<CharT, Traits>::close()
}
using cmUVPipeIStream = cmBasicUVPipeIStream<char>;
+
+template <typename ReadCallback, typename FinishCallback>
+void cmUVStreamRead(uv_stream_t* stream, ReadCallback onRead,
+ FinishCallback onFinish)
+{
+ struct ReadData
+ {
+ std::vector<char> Buffer;
+ ReadCallback OnRead;
+ FinishCallback OnFinish;
+ };
+
+ stream->data = new ReadData{ {}, std::move(onRead), std::move(onFinish) };
+ uv_read_start(
+ stream,
+ [](uv_handle_t* s, std::size_t suggestedSize, uv_buf_t* buffer) {
+ auto* data = static_cast<ReadData*>(s->data);
+ data->Buffer.resize(suggestedSize);
+ buffer->base = data->Buffer.data();
+ buffer->len = suggestedSize;
+ },
+ [](uv_stream_t* s, ssize_t nread, const uv_buf_t* buffer) {
+ auto* data = static_cast<ReadData*>(s->data);
+ if (nread > 0) {
+ (void)buffer;
+ assert(buffer->base == data->Buffer.data());
+ data->Buffer.resize(nread);
+ data->OnRead(std::move(data->Buffer));
+ } else if (nread < 0 /*|| nread == UV_EOF*/) {
+ data->OnFinish();
+ uv_read_stop(s);
+ delete data;
+ }
+ });
+}