diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2023-06-09 19:51:09 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2023-06-14 15:53:55 (GMT) |
commit | 0878306386d42084e8abc3525393ae2b65acf725 (patch) | |
tree | d2898e3d1a468132dc0893d35cd01e08f4164252 /Source/cmUVStream.h | |
parent | b8fd273ed7b14ff71cd55d39ffb7c41c2f5ee421 (diff) | |
download | CMake-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.h | 38 |
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; + } + }); +} |