diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index ae974192..fb9bccef 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -1,6 +1,10 @@ #pragma once +#include +#include +#include +#include #include #include "handle.hpp" #include "loop.hpp" @@ -9,6 +13,37 @@ namespace uvw { +template +class Stream; + + +class Buffer final { + template + friend class Stream; + + uv_buf_t uvBuf() const noexcept { + return uv_buf_init(data.get(), size); + } + +public: + Buffer(std::unique_ptr dt, std::size_t s) + : data{std::move(dt)}, size{s} + { } + + Buffer(Buffer &&) = default; + Buffer& operator=(Buffer &&) = default; + + void reset(std::unique_ptr dt, std::size_t s) noexcept { + data.swap(dt); + size = s; + } + +private: + std::unique_ptr data; + std::size_t size; +}; + + template class Stream: public Handle { static constexpr unsigned int DEFAULT_BACKLOG = 128; @@ -50,7 +85,20 @@ public: } // TODO write - // TODO tryWrite + + UVWOptionalData tryWrite(Buffer buf) noexcept { + Buffer data[] = { std::move(buf) }; + return tryWrite(std::begin(data), std::end(data)); + } + + template + UVWOptionalData tryWrite(It first, It last) noexcept { + uv_buf_t data[last - first]; + std::size_t pos = 0; + while(first != last) { data[pos++] = (first++)->uvBuf(); } + auto bw = uv_try_write(this->template get(), data, pos); + return (bw >= 0 ? bw : UVWError{bw}); + } bool readable() const noexcept { return (uv_is_readable(this->template get()) == 1); diff --git a/test/main.cpp b/test/main.cpp index d8a6cce0..77928b07 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -62,7 +62,18 @@ void conn(uvw::Loop &loop) { auto cb = [](uvw::UVWError err, uvw::Tcp &tcp) mutable { std::cout << "connect: " << ((bool)err) << std::endl; - auto cb = [](uvw::UVWError err, uvw::Tcp &tcp) mutable { + auto data = std::unique_ptr(new char[1]); + data[0] = 42; + uvw::Buffer buf{std::move(data), 1}; + uvw::UVWOptionalData bw = tcp.tryWrite(std::move(buf)); + + if(bw) { + std::cout << "written: " << ((int)bw) << std::endl; + } else { + std::cout << "written err: " << ((int)bw) << std::endl; + } + + auto cb = [](uvw::UVWError err, uvw::Tcp &) mutable { std::cout << "close: " << ((bool)err) << std::endl; };