XS-libunievent

 view release on metacpan or  search on metacpan

libunievent/src/panda/unievent/Fs.cc  view on Meta::CPAN

ex<void> Fs::datasync (fd_t fd) {
    UEFS_SYNC({
        uv_fs_fdatasync(nullptr, &uvr, fd, nullptr);
    }, {});
    return {};
}

ex<void> Fs::truncate (string_view file, int64_t length) {
    return open(file, OpenFlags::WRONLY).and_then([&](fd_t fd) {
        auto ret = truncate(fd, length);
        if (!ret) {
            close(fd).nevermind();
            return ret;
        }
        return close(fd);
    });
}

ex<void> Fs::truncate (fd_t fd, int64_t length) {
    UEFS_SYNC({
        uv_fs_ftruncate(nullptr, &uvr, fd, length, nullptr);
    }, {});
    return {};
}

ex<void> Fs::chmod (string_view path, int mode) {
    UE_NULL_TERMINATE(path, path_str);
    UEFS_SYNC({
        uv_fs_chmod(nullptr, &uvr, path_str, mode, nullptr);
    }, {});
    return {};
}

ex<void> Fs::chmod (fd_t fd, int mode) {
    UEFS_SYNC({
        uv_fs_fchmod(nullptr, &uvr, fd, mode, nullptr);
    }, {});
    return {};
}

ex<void> Fs::touch (string_view file, int mode) {
    if (exists(file)) return utime(file, gettimeofday().get(), gettimeofday().get());
    else              return open(file, OpenFlags::RDWR | OpenFlags::CREAT, mode).and_then([](fd_t fd){ return close(fd); });
}

ex<void> Fs::utime (string_view path, double atime, double mtime) {
    UE_NULL_TERMINATE(path, path_str);
    UEFS_SYNC({
        uv_fs_utime(nullptr, &uvr, path_str, atime, mtime, nullptr);
    }, {});
    return {};
}

ex<void> Fs::utime (fd_t fd, double atime, double mtime) {
    UEFS_SYNC({
        uv_fs_futime(nullptr, &uvr, fd, atime, mtime, nullptr);
    }, {});
    return {};
}

ex<void> Fs::chown (string_view path, uid_t uid, gid_t gid) {
    UE_NULL_TERMINATE(path, path_str);
    UEFS_SYNC({
        uv_fs_chown(nullptr, &uvr, path_str, uid, gid, nullptr);
    }, {});
    return {};
}

ex<void> Fs::lchown (string_view path, uid_t uid, gid_t gid) {
    UE_NULL_TERMINATE(path, path_str);
    UEFS_SYNC({
        uv_fs_lchown(nullptr, &uvr, path_str, uid, gid, nullptr);
    }, {});
    return {};
}

ex<void> Fs::chown (fd_t fd, uid_t uid, gid_t gid) {
    UEFS_SYNC({
        uv_fs_fchown(nullptr, &uvr, fd, uid, gid, nullptr);
    }, {});
    return {};
}

ex<string> Fs::read (fd_t fd, size_t length, int64_t offset) {
    string ret;
    char* ptr = ret.reserve(length);
    uv_buf_t uvbuf;
    uvbuf.base = ptr;
    uvbuf.len  = length;
    UEFS_SYNC({
        uv_fs_read(nullptr, &uvr, fd, &uvbuf, 1, offset, nullptr);
    }, {
        ret.length(uvr.result);
    });
    return ret;
}

ex<void> Fs::_write (fd_t fd, _buf_t* bufs, size_t nbufs, int64_t offset) {
    uv_buf_t uvbufs[nbufs];
    for (size_t i = 0; i < nbufs; ++i) {
        uvbufs[i].base = const_cast<char*>(bufs[i].base); // libuv read-only access
        uvbufs[i].len  = bufs[i].len;
    }
    UEFS_SYNC({
        uv_fs_write(nullptr, &uvr, fd, uvbufs, nbufs, offset, nullptr);
    }, {});
    return {};
}

ex<void> Fs::rename (string_view src, string_view dst) {
    UE_NULL_TERMINATE(src, src_str);
    UE_NULL_TERMINATE(dst, dst_str);
    UEFS_SYNC({
        uv_fs_rename(nullptr, &uvr, src_str, dst_str, nullptr);
    }, {});
    return {};
}

ex<size_t> Fs::sendfile (fd_t out, fd_t in, int64_t offset, size_t length) {
    size_t ret;
    UEFS_SYNC({
        uv_fs_sendfile(nullptr, &uvr, out, in, offset, length, nullptr);
    }, {
        ret = (size_t)uvr.result;
    });
    return ret;
}

ex<void> Fs::link (string_view src, string_view dst) {
    UE_NULL_TERMINATE(src, src_str);
    UE_NULL_TERMINATE(dst, dst_str);
    UEFS_SYNC({
        uv_fs_link(nullptr, &uvr, src_str, dst_str, nullptr);
    }, {});
    return {};
}

ex<void> Fs::symlink (string_view src, string_view dst, int flags) {
    UE_NULL_TERMINATE(src, src_str);

libunievent/src/panda/unievent/Fs.cc  view on Meta::CPAN

    return ret;
}

ex<void> Fs::copyfile (string_view src, string_view dst, int flags) {
    UE_NULL_TERMINATE(src, src_str);
    UE_NULL_TERMINATE(dst, dst_str);
    UEFS_SYNC({
        uv_fs_copyfile(nullptr, &uvr, src_str, dst_str, flags, nullptr);
    }, {});
    return {};
}

ex<string> Fs::mkdtemp (string_view path) {
    string ret;
    UE_NULL_TERMINATE(path, path_str);
    UEFS_SYNC({
        uv_fs_mkdtemp(nullptr, &uvr, path_str, nullptr);
    }, {
        ret.assign(uvr.path);
    });
    return ret;
}

/* ===============================================================================================
   =================================== ASYNC STATIC API ==========================================
   =============================================================================================== */

#define UEFS_ASYNC_S(call_code)             \
    Fs::RequestSP ret = new Fs::Request(l); \
    call_code;                              \
    return ret;

#define UEFS_ASYNC_SFD(call_code) UEFS_ASYNC_S({ ret->fd(f); call_code; })

Fs::RequestSP Fs::mkdir      (string_view path, int mode, const fn& cb, const LoopSP& l) { UEFS_ASYNC_S(ret->mkdir(path, mode, cb)); }
Fs::RequestSP Fs::rmdir      (string_view path, const fn& cb, const LoopSP& l)           { UEFS_ASYNC_S(ret->rmdir(path, cb)); }
Fs::RequestSP Fs::remove     (string_view path, const fn& cb, const LoopSP& l)           { UEFS_ASYNC_S(ret->remove(path, cb)); }
Fs::RequestSP Fs::mkpath     (string_view path, int mode, const fn& cb, const LoopSP& l) { UEFS_ASYNC_S(ret->mkpath(path, mode, cb)); }
Fs::RequestSP Fs::scandir    (string_view path, const scandir_fn& cb, const LoopSP& l)   { UEFS_ASYNC_S(ret->scandir(path, cb)); }
Fs::RequestSP Fs::remove_all (string_view path, const fn& cb, const LoopSP& l)           { UEFS_ASYNC_S(ret->remove_all(path, cb)); }

Fs::RequestSP Fs::open     (string_view path, int flags, int mode, const open_fn& cb, const LoopSP& l)          { UEFS_ASYNC_S(ret->open(path, flags, mode, cb)); }
Fs::RequestSP Fs::close    (fd_t f, const fn& cb, const LoopSP& l)                                              { UEFS_ASYNC_SFD(ret->close(cb)); }
Fs::RequestSP Fs::stat     (string_view path, const stat_fn& cb, const LoopSP& l)                               { UEFS_ASYNC_S(ret->stat(path, cb)); }
Fs::RequestSP Fs::stat     (fd_t f, const stat_fn& cb, const LoopSP& l)                                         { UEFS_ASYNC_SFD(ret->stat(cb)); }
Fs::RequestSP Fs::lstat    (string_view path, const stat_fn& cb, const LoopSP& l)                               { UEFS_ASYNC_S(ret->lstat(path, cb)); }
Fs::RequestSP Fs::exists   (string_view path, const bool_fn& cb, const LoopSP& l)                               { UEFS_ASYNC_S(ret->exists(path, cb)); }
Fs::RequestSP Fs::isfile   (string_view path, const bool_fn& cb, const LoopSP& l)                               { UEFS_ASYNC_S(ret->isfile(path, cb)); }
Fs::RequestSP Fs::isdir    (string_view path, const bool_fn& cb, const LoopSP& l)                               { UEFS_ASYNC_S(ret->isdir(path, cb)); }
Fs::RequestSP Fs::access   (string_view path, int mode, const fn& cb, const LoopSP& l)                          { UEFS_ASYNC_S(ret->access(path, mode, cb)); }
Fs::RequestSP Fs::unlink   (string_view path, const fn& cb, const LoopSP& l)                                    { UEFS_ASYNC_S(ret->unlink(path, cb)); }
Fs::RequestSP Fs::sync     (fd_t f, const fn& cb, const LoopSP& l)                                              { UEFS_ASYNC_SFD(ret->sync(cb)); }
Fs::RequestSP Fs::datasync (fd_t f, const fn& cb, const LoopSP& l)                                              { UEFS_ASYNC_SFD(ret->datasync(cb)); }
Fs::RequestSP Fs::truncate (string_view path, int64_t off, const fn& cb, const LoopSP& l)                       { UEFS_ASYNC_S(ret->truncate(path, off, cb)); }
Fs::RequestSP Fs::truncate (fd_t f, int64_t off, const fn& cb, const LoopSP& l)                                 { UEFS_ASYNC_SFD(ret->truncate(off, cb)); }
Fs::RequestSP Fs::chmod    (string_view path, int mode, const fn& cb, const LoopSP& l)                          { UEFS_ASYNC_S(ret->chmod(path, mode, cb)); }
Fs::RequestSP Fs::chmod    (fd_t f, int mode, const fn& cb, const LoopSP& l)                                    { UEFS_ASYNC_SFD(ret->chmod(mode, cb)); }
Fs::RequestSP Fs::touch    (string_view path, int mode, const fn& cb, const LoopSP& l)                          { UEFS_ASYNC_S(ret->touch(path, mode, cb)); }
Fs::RequestSP Fs::utime    (string_view path, double atime, double mtime, const fn& cb, const LoopSP& l)        { UEFS_ASYNC_S(ret->utime(path, atime, mtime, cb)); }
Fs::RequestSP Fs::utime    (fd_t f, double atime, double mtime, const fn& cb, const LoopSP& l)                  { UEFS_ASYNC_SFD(ret->utime(atime, mtime, cb)); }
Fs::RequestSP Fs::chown    (string_view path, uid_t uid, gid_t gid, const fn& cb, const LoopSP& l)              { UEFS_ASYNC_S(ret->chown(path, uid, gid, cb)); }
Fs::RequestSP Fs::lchown   (string_view path, uid_t uid, gid_t gid, const fn& cb, const LoopSP& l)              { UEFS_ASYNC_S(ret->lchown(path, uid, gid, cb)); }
Fs::RequestSP Fs::chown    (fd_t f, uid_t uid, gid_t gid, const fn& cb, const LoopSP& l)                        { UEFS_ASYNC_SFD(ret->chown(uid, gid, cb)); }
Fs::RequestSP Fs::rename   (string_view src, string_view dst, const fn& cb, const LoopSP& l)                    { UEFS_ASYNC_S(ret->rename(src, dst, cb)); }
Fs::RequestSP Fs::sendfile (fd_t out, fd_t in, int64_t off, size_t len, const sendfile_fn& cb, const LoopSP& l) { UEFS_ASYNC_S(ret->sendfile(out, in, off, len, cb)); }
Fs::RequestSP Fs::link     (string_view src, string_view dst, const fn& cb, const LoopSP& l)                    { UEFS_ASYNC_S(ret->link(src, dst, cb)); }
Fs::RequestSP Fs::symlink  (string_view src, string_view dst, int flags, const fn& cb, const LoopSP& l)         { UEFS_ASYNC_S(ret->symlink(src, dst, flags, cb)); }
Fs::RequestSP Fs::readlink (string_view path, const string_fn& cb, const LoopSP& l)                             { UEFS_ASYNC_S(ret->readlink(path, cb)); }
Fs::RequestSP Fs::realpath (string_view path, const string_fn& cb, const LoopSP& l)                             { UEFS_ASYNC_S(ret->realpath(path, cb)); }
Fs::RequestSP Fs::copyfile (string_view src, string_view dst, int flags, const fn& cb, const LoopSP& l)         { UEFS_ASYNC_S(ret->copyfile(src, dst, flags, cb)); }
Fs::RequestSP Fs::mkdtemp  (string_view path, const string_fn& cb, const LoopSP& l)                             { UEFS_ASYNC_S(ret->mkdtemp(path, cb)); }
Fs::RequestSP Fs::read     (fd_t f, size_t size, int64_t off, const string_fn& cb, const LoopSP& l)             { UEFS_ASYNC_SFD(ret->read(size, off, cb)); }
Fs::RequestSP Fs::_write   (fd_t f, std::vector<string>&& v, int64_t off, const fn& cb, const LoopSP& l)        { UEFS_ASYNC_SFD(ret->_write(std::move(v), off, cb)); }

/* ===============================================================================================
   =================================== ASYNC OBJECT API ==========================================
   =============================================================================================== */

#define UEFS_ASYNC_RAW(work_code, after_work_code) { \
    if (_busy) throw Error("cannot start request while processing another");    \
    _busy = true;                                    \
    work_cb = [=](auto) { work_code  };              \
    after_work_cb = [=](auto&, auto& err) {          \
        if (err) _err = err;                         \
        _busy = false;                               \
        after_work_code;                             \
        _err.clear();                                \
        _dir_entries.clear();                        \
        _string.clear();                             \
    };                                               \
    queue();                                         \
}

#define UEFS_ASYNC(call_expr, save_result_code, cb_code)        \
    UEFS_ASYNC_RAW({                                            \
        auto ret = call_expr;                                   \
        if (ret) {save_result_code;}                            \
        else     _err = ret.error();                            \
    }, cb_code);

#define UEFS_ASYNC_VOID(call_expr) UEFS_ASYNC(call_expr, {}, cb(_err, this))
#define UEFS_ASYNC_STAT(call_expr) UEFS_ASYNC(call_expr, (_stat = *std::move(ret)), cb(_stat, _err, this))
#define UEFS_ASYNC_BOOL(call_expr) UEFS_ASYNC_RAW( { _bool = call_expr; }, cb(_bool, _err, this))
#define UEFS_ASYNC_STR(call_expr)  UEFS_ASYNC(call_expr, (_string = *std::move(ret)), cb(_string, _err, this))

void Fs::Request::mkdir      (string_view _path, int mode, const fn& cb) { auto path = string(_path); UEFS_ASYNC_VOID(Fs::mkdir(path, mode)); }
void Fs::Request::rmdir      (string_view _path, const fn& cb)           { auto path = string(_path); UEFS_ASYNC_VOID(Fs::rmdir(path)); }
void Fs::Request::remove     (string_view _path, const fn& cb)           { auto path = string(_path); UEFS_ASYNC_VOID(Fs::remove(path)); }
void Fs::Request::mkpath     (string_view _path, int mode, const fn& cb) { auto path = string(_path); UEFS_ASYNC_VOID(Fs::mkpath(path, mode)); }
void Fs::Request::scandir    (string_view _path, const scandir_fn& cb)   { auto path = string(_path); UEFS_ASYNC(Fs::scandir(path), (_dir_entries = *std::move(ret)), cb(_dir_entries, _err, this)); }
void Fs::Request::remove_all (string_view _path, const fn& cb)           { auto path = string(_path); UEFS_ASYNC_VOID(Fs::remove_all(path)); }

void Fs::Request::open     (string_view _path, int flags, int mode, const open_fn& cb)         { auto path = string(_path); UEFS_ASYNC(Fs::open(path, flags, mode), (_fd = *ret), cb(_fd, _err, this)); }
void Fs::Request::close    (const fn& cb)                                                      { UEFS_ASYNC_VOID(Fs::close(_fd)); }
void Fs::Request::stat     (string_view _path, const stat_fn& cb)                              { auto path = string(_path); UEFS_ASYNC_STAT(Fs::stat(path)); }
void Fs::Request::stat     (const stat_fn& cb)                                                 { UEFS_ASYNC_STAT(Fs::stat(_fd)); }
void Fs::Request::lstat    (string_view _path, const stat_fn& cb)                              { auto path = string(_path); UEFS_ASYNC_STAT(Fs::lstat(path)); }
void Fs::Request::exists   (string_view _path, const bool_fn& cb)                              { auto path = string(_path); UEFS_ASYNC_BOOL(Fs::exists(path)); }
void Fs::Request::isfile   (string_view _path, const bool_fn& cb)                              { auto path = string(_path); UEFS_ASYNC_BOOL(Fs::isfile(path)); }
void Fs::Request::isdir    (string_view _path, const bool_fn& cb)                              { auto path = string(_path); UEFS_ASYNC_BOOL(Fs::isdir(path)); }
void Fs::Request::access   (string_view _path, int mode, const fn& cb)                         { auto path = string(_path); UEFS_ASYNC_VOID(Fs::access(path, mode)); }
void Fs::Request::unlink   (string_view _path, const fn& cb)                                   { auto path = string(_path); UEFS_ASYNC_VOID(Fs::unlink(path)); }
void Fs::Request::sync     (const fn& cb)                                                      { UEFS_ASYNC_VOID(Fs::sync(_fd)); }
void Fs::Request::datasync (const fn& cb)                                                      { UEFS_ASYNC_VOID(Fs::datasync(_fd)); }
void Fs::Request::truncate (string_view _path, int64_t off, const fn& cb)                      { auto path = string(_path); UEFS_ASYNC_VOID(Fs::truncate(path, off)); }
void Fs::Request::truncate (int64_t off, const fn& cb)                                         { UEFS_ASYNC_VOID(Fs::truncate(_fd, off)); }
void Fs::Request::chmod    (string_view _path, int mode, const fn& cb)                         { auto path = string(_path); UEFS_ASYNC_VOID(Fs::chmod(path, mode)); }
void Fs::Request::chmod    (int mode, const fn& cb)                                            { UEFS_ASYNC_VOID(Fs::chmod(_fd, mode)); }
void Fs::Request::touch    (string_view _path, int mode, const fn& cb)                         { auto path = string(_path); UEFS_ASYNC_VOID(Fs::touch(path, mode)); }
void Fs::Request::utime    (string_view _path, double atime, double mtime, const fn& cb)       { auto path = string(_path); UEFS_ASYNC_VOID(Fs::utime(path, atime, mtime)); }
void Fs::Request::utime    (double atime, double mtime, const fn& cb)                          { UEFS_ASYNC_VOID(Fs::utime(_fd, atime, mtime)); }
void Fs::Request::chown    (string_view _path, uid_t uid, gid_t gid, const fn& cb)             { auto path = string(_path); UEFS_ASYNC_VOID(Fs::chown(path, uid, gid)); }
void Fs::Request::lchown   (string_view _path, uid_t uid, gid_t gid, const fn& cb)             { auto path = string(_path); UEFS_ASYNC_VOID(Fs::lchown(path, uid, gid)); }
void Fs::Request::chown    (uid_t uid, gid_t gid, const fn& cb)                                { UEFS_ASYNC_VOID(Fs::chown(_fd, uid, gid)); }
void Fs::Request::rename   (string_view _src, string_view _dst, const fn& cb)                  { auto src = string(_src); auto dst = string(_dst); UEFS_ASYNC_VOID(Fs::rename(src, dst)); }
void Fs::Request::sendfile (fd_t out, fd_t in, int64_t off, size_t len, const sendfile_fn& cb) { UEFS_ASYNC(Fs::sendfile(out, in, off, len), (_size = *ret), cb(_size, _err, this)); }
void Fs::Request::link     (string_view _src, string_view _dst, const fn& cb)                  { auto src = string(_src); auto dst = string(_dst); UEFS_ASYNC_VOID(Fs::link(src, dst)); }
void Fs::Request::symlink  (string_view _src, string_view _dst, int flags, const fn& cb)       { auto src = string(_src); auto dst = string(_dst); UEFS_ASYNC_VOID(Fs::symlink(src, dst, flags)); }
void Fs::Request::readlink (string_view _path, const string_fn& cb)                            { auto path = string(_path); UEFS_ASYNC_STR(Fs::readlink(path)); }
void Fs::Request::realpath (string_view _path, const string_fn& cb)                            { auto path = string(_path); UEFS_ASYNC_STR(Fs::realpath(path)); }
void Fs::Request::copyfile (string_view _src, string_view _dst, int flags, const fn& cb)       { auto src = string(_src); auto dst = string(_dst); UEFS_ASYNC_VOID(Fs::copyfile(src, dst, flags)); }
void Fs::Request::mkdtemp  (string_view _path, const string_fn& cb)                            { auto path = string(_path); UEFS_ASYNC_STR(Fs::mkdtemp(path)); }
void Fs::Request::read     (size_t size, int64_t off, const string_fn& cb)                     { UEFS_ASYNC_STR(Fs::read(_fd, size, off)); }
void Fs::Request::_write   (std::vector<string>&& v, int64_t off, const fn& cb)                {
    UEFS_ASYNC_RAW({
        auto nbufs = v.size();
        _buf_t bufs[nbufs];
        _buf_t* ptr = bufs;
        for (const auto& s : v) {
            ptr->base = s.data();
            ptr->len  = s.length();
            ++ptr;
        }
        auto ret = Fs::_write(_fd, bufs, nbufs, off);
        if (!ret) _err = ret.error();
    }, {
        cb(_err, this);
    });
}



( run in 0.581 second using v1.01-cache-2.11-cpan-5511b514fd6 )