diff --git a/src/uvw/event.hpp b/src/uvw/event.hpp index 9a11b5c1..7ae29444 100644 --- a/src/uvw/event.hpp +++ b/src/uvw/event.hpp @@ -37,9 +37,15 @@ struct ErrorEvent: Event { const char * what() const noexcept { return uv_strerror(ec); } int code() const noexcept { return ec; } + explicit operator bool() const noexcept { return !(0 == ec); } + private: const int ec; }; +template +struct TypedEvent; + + } diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index 9cc16e53..9689e1e0 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -14,23 +14,135 @@ namespace uvw { +namespace details { + + +enum class UVFsType: std::underlying_type_t { + UNKNOWN = UV_FS_UNKNOWN, + CUSTOM = UV_FS_CUSTOM, + OPEN = UV_FS_OPEN, + CLOSE = UV_FS_CLOSE, + READ = UV_FS_READ, + WRITE = UV_FS_WRITE, + SENDFILE = UV_FS_SENDFILE, + STAT = UV_FS_STAT, + LSTAT = UV_FS_LSTAT, + FSTAT = UV_FS_FSTAT, + FTRUNCATE = UV_FS_FTRUNCATE, + UTIME = UV_FS_UTIME, + FUTIME = UV_FS_FUTIME, + ACCESS = UV_FS_ACCESS, + CHMOD = UV_FS_CHMOD, + FCHMOD = UV_FS_FCHMOD, + FSYNC = UV_FS_FSYNC, + FDATASYNC = UV_FS_FDATASYNC, + UNLINK = UV_FS_UNLINK, + RMDIR = UV_FS_RMDIR, + MKDIR = UV_FS_MKDIR, + MKDTEMP = UV_FS_MKDTEMP, + RENAME = UV_FS_RENAME, + SCANDIR = UV_FS_SCANDIR, + LINK = UV_FS_LINK, + SYMLINK = UV_FS_SYMLINK, + READLINK = UV_FS_READLINK, + CHOWN = UV_FS_CHOWN, + FCHOWN = UV_FS_FCHOWN, + REALPATH = UV_FS_REALPATH +}; + + +enum class UVDirentTypeT: std::underlying_type_t { + UNKNOWN = UV_DIRENT_UNKNOWN, + FILE = UV_DIRENT_FILE, + DIR = UV_DIRENT_DIR, + LINK = UV_DIRENT_LINK, + FIFO = UV_DIRENT_FIFO, + SOCKET = UV_DIRENT_SOCKET, + CHAR = UV_DIRENT_CHAR, + BLOCK = UV_DIRENT_BLOCK +}; + + +} + + +template +struct TypedEvent + : Event> +{ + using Type = details::UVFsType; + static constexpr details::UVFsType value = e; +}; + + +template<> +struct TypedEvent + : Event> +{ + using Type = details::UVFsType; + static constexpr details::UVFsType value = details::UVFsType::STAT; + + TypedEvent(const Stat &s): fsStat{s} { } + + const Stat & stat() const noexcept { return fsStat; } + +private: + Stat fsStat; +}; + + +template<> +struct TypedEvent + : Event> +{ + using Type = details::UVFsType; + static constexpr details::UVFsType value = details::UVFsType::FSTAT; + + TypedEvent(const Stat &s): fsStat{s} { } + + const Stat & stat() const noexcept { return fsStat; } + +private: + Stat fsStat; +}; + + +template<> +struct TypedEvent + : Event> +{ + using Type = details::UVFsType; + static constexpr details::UVFsType value = details::UVFsType::LSTAT; + + TypedEvent(const Stat &s): fsStat{s} { } + + const Stat & stat() const noexcept { return fsStat; } + +private: + Stat fsStat; +}; + + +template +using FsEvent = TypedEvent; + + class Fs final: public Request { - static void fsCallback(uv_fs_t *req) { - // TODO type - /* + template + static void fsGenericCallback(uv_fs_t *req) { Fs &fs = *(static_cast(req->data)); - auto ptr = res.shared_from_this(); + auto ptr = fs.shared_from_this(); (void)ptr; - res.reset(); + fs.reset(); if(req->result) { - res.publish(ErrorEvent{status}); + int err = req->result; + fs.publish(ErrorEvent{err}); } else { - res.publish(FsEvent{}); + fs.publish(FsEvent{}); } - */ } static void fsReadCallback(uv_fs_t *req) { @@ -41,8 +153,21 @@ class Fs final: public Request { // TODO - uv_fs_write callback } + template static void fsStatCallback(uv_fs_t *req) { - // TODO - uv_fs_stat callback + Fs &fs = *(static_cast(req->data)); + + auto ptr = fs.shared_from_this(); + (void)ptr; + + fs.reset(); + + if(req->result) { + int err = req->result; + fs.publish(ErrorEvent{err}); + } else { + fs.publish(FsEvent{req->statbuf}); + } } static void fsReadlinkCallback(uv_fs_t *req) { @@ -53,9 +178,9 @@ class Fs final: public Request { public: using Time = std::chrono::seconds; - using Flags = int; - using Mode = int; - using Offset = int64_t; + using Type = details::UVFsType; + using EntryType = details::UVDirentTypeT; + using Entry = std::pair; template static std::shared_ptr create(Args&&... args) { @@ -67,134 +192,235 @@ public: } void close(FileHandle file) { - invoke(&uv_fs_close, parent(), get(), file, &fsCallback); + invoke(&uv_fs_close, parent(), get(), file, &fsGenericCallback); } - // TODO uv_fs_close (sync (cb null)) - - void open(std::string path, Flags flags, Mode mode) { - invoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsCallback); + auto closeSync(FileHandle file) { + auto err = uv_fs_close(parent(), get(), file, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } + + void open(std::string path, int flags, int mode) { + invoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsGenericCallback); + } + + auto openSync(std::string path, int flags, int mode) { + auto err = uv_fs_open(parent(), get(), path.data(), flags, mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); } - // TODO uv_fs_open (sync (cb null)) // TODO uv_fs_read (sync (cb null)/async) void unlink(std::string path) { - invoke(&uv_fs_unlink, parent(), get(), path.data(), &fsCallback); + invoke(&uv_fs_unlink, parent(), get(), path.data(), &fsGenericCallback); } - // TODO uv_fs_unlink (sync (cb null)) - // TODO uv_fs_write (sync (cb null)/async) - - void mkdir(std::string path, Mode mode) { - invoke(&uv_fs_mkdir, parent(), get(), path.data(), mode, &fsCallback); + auto unlinkSync(std::string path) { + auto err = uv_fs_unlink(parent(), get(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); } - // TODO uv_fs_mkdir (sync (cb null)) - - void mkdtemp(std::string tpl, Mode mode) { - invoke(&uv_fs_mkdtemp, parent(), get(), tpl.data(), &fsCallback); + void write(FileHandle file, char *data, ssize_t len, int64_t offset) { + uv_buf_t bufs[] = { uv_buf_init(data, len) }; + invoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsWriteCallback); } - // TODO uv_fs_mkdtemp (sync (cb null)) + void write(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { + write(file, data.get(), len, offset); + } + + auto writeSync(FileHandle file, char *data, ssize_t len, int64_t offset) { + // TODO uv_fs_write (sync (cb null)) + } + + auto writeSync(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { + // TODO uv_fs_write (sync (cb null)) + } + + void mkdir(std::string path, int mode) { + invoke(&uv_fs_mkdir, parent(), get(), path.data(), mode, &fsGenericCallback); + } + + auto mkdirSync(std::string path, int mode) { + auto err = uv_fs_mkdir(parent(), get(), path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } + + void mkdtemp(std::string tpl) { + invoke(&uv_fs_mkdtemp, parent(), get(), tpl.data(), &fsGenericCallback); + } + + auto mkdtempSync(std::string tpl) { + auto err = uv_fs_mkdtemp(parent(), get(), tpl.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } void rmdir(std::string path) { - invoke(&uv_fs_rmdir, parent(), get(), path.data(), &fsCallback); + invoke(&uv_fs_rmdir, parent(), get(), path.data(), &fsGenericCallback); } - // TODO uv_fs_rmdir (sync (cb null)) - - void scandir(std::string path, Flags flags) { - invoke(&uv_fs_scandir, parent(), get(), path.data(), flags, &fsCallback); + auto rmdirSync(std::string path) { + auto err = uv_fs_rmdir(parent(), get(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); } - // TODO uv_fs_scandir (sync (cb null)) - // TODO uv_fs_scandir_next (sync (cb null)/async) + void scandir(std::string path, int flags) { + invoke(&uv_fs_scandir, parent(), get(), path.data(), flags, &fsGenericCallback); + } + + auto scandirSync(std::string path, int flags) { + auto err = uv_fs_scandir(parent(), get(), path.data(), flags, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } + + std::pair scandirNext() { + uv_dirent_t dirent; + std::pair ret{false, { EntryType::UNKNOWN, "" }}; + auto res = uv_fs_scandir_next(get(), &dirent); + + if(UV_EOF != res) { + ret.second.first = static_cast(dirent.type); + ret.second.second = dirent.name; + ret.first = true; + } + + return ret; + } void stat(std::string path) { - invoke(&uv_fs_stat, parent(), get(), path.data(), &fsStatCallback); + invoke(&uv_fs_stat, parent(), get(), path.data(), &fsStatCallback); } - // TODO uv_fs_stat (sync (cb null)) + auto statSync(std::string path) { + auto err = uv_fs_stat(parent(), get(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); + } void fstat(FileHandle file) { - invoke(&uv_fs_fstat, parent(), get(), file, &fsCallback); + invoke(&uv_fs_fstat, parent(), get(), file, &fsStatCallback); } - // TODO uv_fs_fstat (sync (cb null)) + auto fstatSync(FileHandle file) { + auto err = uv_fs_fstat(parent(), get(), file, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); + } void lstat(std::string path) { - invoke(&uv_fs_lstat, parent(), get(), path.data(), &fsCallback); + invoke(&uv_fs_lstat, parent(), get(), path.data(), &fsStatCallback); } - // TODO uv_fs_lstat (sync (cb null)) + auto lstatSync(std::string path) { + auto err = uv_fs_lstat(parent(), get(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); + } void rename(std::string old, std::string path) { - invoke(&uv_fs_rename, parent(), get(), old.data(), path.data(), &fsCallback); + invoke(&uv_fs_rename, parent(), get(), old.data(), path.data(), &fsGenericCallback); } - // TODO uv_fs_rename (sync (cb null)) + auto renameSync(std::string old, std::string path) { + auto err = uv_fs_rename(parent(), get(), old.data(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } void fsync(FileHandle file) { - invoke(&uv_fs_fsync, parent(), get(), file, &fsCallback); + invoke(&uv_fs_fsync, parent(), get(), file, &fsGenericCallback); } - // TODO uv_fs_fsync (sync (cb null)) + auto fsyncSync(FileHandle file) { + auto err = uv_fs_fsync(parent(), get(), file, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } void fdatasync(FileHandle file) { - invoke(&uv_fs_fdatasync, parent(), get(), file, &fsCallback); + invoke(&uv_fs_fdatasync, parent(), get(), file, &fsGenericCallback); } - // TODO uv_fs_fdatasync (sync (cb null)) - - void ftruncate(FileHandle file, Offset offset) { - invoke(&uv_fs_ftruncate, parent(), get(), file, offset, &fsCallback); + auto fdatasyncSync(FileHandle file) { + auto err = uv_fs_fdatasync(parent(), get(), file, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); } - // TODO uv_fs_ftruncate (sync (cb null)) - // TODO uv_fs_sendfile (sync (cb null)/async) - - void access(std::string path, Mode mode) { - invoke(&uv_fs_access, parent(), get(), path.data(), mode, &fsCallback); + void ftruncate(FileHandle file, int64_t offset) { + invoke(&uv_fs_ftruncate, parent(), get(), file, offset, &fsGenericCallback); } - // TODO uv_fs_access (sync (cb null)) - - void chmod(std::string path, Mode mode) { - invoke(&uv_fs_chmod, parent(), get(), path.data(), mode, &fsCallback); + auto ftruncateSync(FileHandle file, int64_t offset) { + auto err = uv_fs_ftruncate(parent(), get(), file, offset, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); } - // TODO uv_fs_chmod (sync (cb null)) - - void fchmod(FileHandle file, Mode mode) { - invoke(&uv_fs_fchmod, parent(), get(), file, mode, &fsCallback); + void sendfile(FileHandle out, FileHandle in, int64_t offset, size_t length) { + invoke(&uv_fs_sendfile, parent(), get(), out, in, offset, length, &fsGenericCallback); } - // TODO uv_fs_fchmod (sync (cb null)) + auto sendfileSync(FileHandle out, FileHandle in, int64_t offset, size_t length) { + auto err = uv_fs_sendfile(parent(), get(), out, in, offset, length, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } + + void access(std::string path, int mode) { + invoke(&uv_fs_access, parent(), get(), path.data(), mode, &fsGenericCallback); + } + + auto accessSync(std::string path, int mode) { + auto err = uv_fs_access(parent(), get(), path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } + + void chmod(std::string path, int mode) { + invoke(&uv_fs_chmod, parent(), get(), path.data(), mode, &fsGenericCallback); + } + + auto chmodSync(std::string path, int mode) { + auto err = uv_fs_chmod(parent(), get(), path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } + + void fchmod(FileHandle file, int mode) { + invoke(&uv_fs_fchmod, parent(), get(), file, mode, &fsGenericCallback); + } + + auto fchmodSync(FileHandle file, int mode) { + auto err = uv_fs_fchmod(parent(), get(), file, mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } void utime(std::string path, Time atime, Time mtime) { - invoke(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), &fsCallback); + invoke(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), &fsGenericCallback); } - // TODO uv_fs_utime (sync (cb null)) - - void utime(FileHandle file, Time atime, Time mtime) { - invoke(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), &fsCallback); + auto utimeSync(std::string path, Time atime, Time mtime) { + auto err = uv_fs_utime(parent(), get(), path.data(), atime.count(), mtime.count(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); } - // TODO uv_fs_futime (sync (cb null)) + void futime(FileHandle file, Time atime, Time mtime) { + invoke(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), &fsGenericCallback); + } + + auto futimeSync(FileHandle file, Time atime, Time mtime) { + auto err = uv_fs_futime(parent(), get(), file, atime.count(), mtime.count(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } void link(std::string old, std::string path) { - invoke(&uv_fs_link, parent(), get(), old.data(), path.data(), &fsCallback); + invoke(&uv_fs_link, parent(), get(), old.data(), path.data(), &fsGenericCallback); } - // TODO uv_fs_link (sync (cb null)) - - void symlink(std::string old, std::string path, Flags flags) { - invoke(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, &fsCallback); + auto linkSync(std::string old, std::string path) { + auto err = uv_fs_link(parent(), get(), old.data(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); } - // TODO uv_fs_symlink (sync (cb null)) + void symlink(std::string old, std::string path, int flags) { + invoke(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, &fsGenericCallback); + } + + auto symlinkSync(std::string old, std::string path, int flags) { + auto err = uv_fs_symlink(parent(), get(), old.data(), path.data(), flags, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } void readlink(std::string path) { invoke(&uv_fs_readlink, parent(), get(), path.data(), &fsReadlinkCallback); @@ -203,22 +429,31 @@ public: // TODO uv_fs_readlink (sync (cb null)) void realpath(std::string path) { - invoke(&uv_fs_realpath, parent(), get(), path.data(), &fsCallback); + invoke(&uv_fs_realpath, parent(), get(), path.data(), &fsGenericCallback); } - // TODO uv_fs_realpath (sync (cb null)/async) + auto realpathSync(std::string path) { + auto err = uv_fs_realpath(parent(), get(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } void chown(std::string path, Uid uid, Gid gid) { - invoke(&uv_fs_chown, parent(), get(), path.data(), uid, gid, &fsCallback); + invoke(&uv_fs_chown, parent(), get(), path.data(), uid, gid, &fsGenericCallback); } - // TODO uv_fs_chown (sync (cb null)) + auto chownSync(std::string path, Uid uid, Gid gid) { + auto err = uv_fs_chown(parent(), get(), path.data(), uid, gid, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } void fchown(FileHandle file, Uid uid, Gid gid) { - invoke(&uv_fs_fchown, parent(), get(), file, uid, gid, &fsCallback); + invoke(&uv_fs_fchown, parent(), get(), file, uid, gid, &fsGenericCallback); } - // TODO uv_fs_fchown (sync (cb null)) + auto fchownSync(FileHandle file, Uid uid, Gid gid) { + auto err = uv_fs_fchown(parent(), get(), file, uid, gid, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{}); + } }; diff --git a/src/uvw/fs_event.hpp b/src/uvw/fs_event.hpp index abd8b3a0..17827339 100644 --- a/src/uvw/fs_event.hpp +++ b/src/uvw/fs_event.hpp @@ -32,8 +32,8 @@ enum class UVFsEvent: std::underlying_type_t { } -struct FsEventEvent: Event { - FsEventEvent(std::string fPath, Flags f) +struct FsMonitorEvent: Event { + FsMonitorEvent(std::string fPath, Flags f) : flgs{std::move(f)}, relPath{std::move(fPath)} { } @@ -46,11 +46,11 @@ private: }; -class FsEvent final: public Handle { +class FsMonitor final: public Handle { static void startCallback(uv_fs_event_t *handle, const char *filename, int events, int status) { - FsEvent &fsEvent = *(static_cast(handle->data)); - if(status) { fsEvent.publish(ErrorEvent{status}); } - else { fsEvent.publish(FsEventEvent{filename, static_cast>(events)}); } + FsMonitor &fsMonitor = *(static_cast(handle->data)); + if(status) { fsMonitor.publish(ErrorEvent{status}); } + else { fsMonitor.publish(FsMonitorEvent{filename, static_cast>(events)}); } } using Handle::Handle; @@ -60,8 +60,8 @@ public: using Event = details::UVFsEventFlags; template - static std::shared_ptr create(Args&&... args) { - return std::shared_ptr{new FsEvent{std::forward(args)...}}; + static std::shared_ptr create(Args&&... args) { + return std::shared_ptr{new FsMonitor{std::forward(args)...}}; } bool init() { return initialize(&uv_fs_event_init); }