diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index 65df5fc9..cea902c6 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -98,6 +98,25 @@ private: }; +template<> +struct TypedEvent + : Event> +{ + TypedEvent(const char *p, std::unique_ptr ptr, ssize_t l) noexcept + : rPath{p}, dt{std::move(ptr)}, len{l} + { } + + const char * path() const noexcept { return rPath; } + const char * data() const noexcept { return dt.get(); } + ssize_t length() const noexcept { return len; } + +private: + const char *rPath; + std::unique_ptr dt; + const ssize_t len; +}; + + template<> struct TypedEvent : Event> @@ -230,6 +249,12 @@ class FsReq final: public Request { else { ptr->publish(FsEvent{req->path, static_cast(req->result)}); } } + static void fsReadCallback(uv_fs_t *req) { + auto ptr = reserve(reinterpret_cast(req)); + if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); } + else { ptr->publish(FsEvent{req->path, std::move(ptr->data), req->result}); } + } + template static void fsGenericCallback(uv_fs_t *req) { auto ptr = reserve(reinterpret_cast(req)); @@ -237,10 +262,6 @@ class FsReq final: public Request { else { ptr->publish(FsEvent{req->path}); } } - static void fsReadCallback(uv_fs_t *req) { - // TODO - uv_fs_read callback - } - template static void fsResultCallback(uv_fs_t *req) { auto ptr = reserve(reinterpret_cast(req)); @@ -264,15 +285,15 @@ class FsReq final: public Request { using Request::Request; template - void cleanupAndInvoke(Args&&... args) { + auto cleanupAndInvoke(Args&&... args) { uv_fs_req_cleanup(get()); - invoke(std::forward(args)...); + return invoke(std::forward(args)...); } template - void cleanupAndInvokeSync(F &&f, Args&&... args) { + auto cleanupAndInvokeSync(F &&f, Args&&... args) { uv_fs_req_cleanup(get()); - std::forward(f)(std::forward(args)...); + return std::forward(f)(std::forward(args)...); } public: @@ -311,12 +332,21 @@ public: return std::make_pair(ErrorEvent{fd < 0 ? fd : 0}, FsEvent{req->path, static_cast(fd)}); } - void read(int64_t offset, unsigned int len) { - // TODO uv_fs_read (async) + void read(FileHandle file, int64_t offset, unsigned int len) { + data = std::unique_ptr{new char[len]}; + buffer = uv_buf_init(data.get(), len); + uv_buf_t bufs[] = { buffer }; + cleanupAndInvoke(&uv_fs_read, parent(), get(), file, bufs, 1, offset, &fsReadCallback); } - auto readSync(int64_t offset, unsigned int len) { - // TODO uv_fs_read (sync (cb null)) + auto readSync(FileHandle file, int64_t offset, unsigned int len) { + data = std::unique_ptr{new char[len]}; + buffer = uv_buf_init(data.get(), len); + uv_buf_t bufs[] = { buffer }; + auto req = get(); + cleanupAndInvokeSync(&uv_fs_read, parent(), req, file, bufs, 1, offset, nullptr); + auto bw = req->result; + return std::make_pair(ErrorEvent{bw < 0 ? bw : 0}, FsEvent{req->path, std::move(data), bw}); } void unlink(std::string path) { @@ -588,6 +618,10 @@ public: cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid, nullptr); return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } + +private: + std::unique_ptr data; + uv_buf_t buffer; };