Skip to content

Commit

Permalink
porting uvw to C++17 (part 4) - see #155
Browse files Browse the repository at this point in the history
  • Loading branch information
skypjack committed Jul 28, 2019
1 parent 208d568 commit 331f958
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 133 deletions.
152 changes: 45 additions & 107 deletions src/uvw/fs.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once


#include <optional>
#include <utility>
#include <memory>
#include <string>
Expand Down Expand Up @@ -553,21 +554,18 @@ class FileReq final: public FsRequest<FileReq> {
* @param offset Offset, as described in the official documentation.
* @param len Length, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * A `std::pair` composed as it follows:
* * A bunch of data read from the given path.
* * The amount of data read from the given path.
* @return An optional `std::pair` composed as it follows:
* * A bunch of data read from the given path.
* * The amount of data read from the given path.
*/
std::pair<bool, std::pair<std::unique_ptr<const char[]>, std::size_t>>
std::optional<std::pair<std::unique_ptr<const char[]>, std::size_t>>
readSync(int64_t offset, unsigned int len) {
current = std::unique_ptr<char[]>{new char[len]};
buffer = uv_buf_init(current.get(), len);
uv_buf_t bufs[] = { buffer };
auto req = get();
cleanupAndInvokeSync(&uv_fs_read, parent(), req, file, bufs, 1, offset);
bool err = req->result < 0;
return std::make_pair(!err, std::make_pair(std::move(current), err ? 0 : std::size_t(req->result)));
return req->result < 0 ? std::optional<std::pair<std::unique_ptr<const char[]>, std::size_t>>{} : std::make_pair(std::move(current), std::size_t(req->result));
}

/**
Expand Down Expand Up @@ -609,22 +607,17 @@ class FileReq final: public FsRequest<FileReq> {

/**
* @brief Sync [write](http://linux.die.net/man/2/pwritev).
*
* @param buf The data to be written.
* @param len The lenght of the submitted data.
* @param offset Offset, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * The amount of data written to the given path.
* @return An optional amount of data written to the given path.
*/
std::pair<bool, std::size_t> writeSync(std::unique_ptr<char[]> buf, unsigned int len, int64_t offset) {
std::optional<std::size_t> writeSync(std::unique_ptr<char[]> buf, unsigned int len, int64_t offset) {
current = std::move(buf);
uv_buf_t bufs[] = { uv_buf_init(current.get(), len) };
auto req = get();
cleanupAndInvokeSync(&uv_fs_write, parent(), req, file, bufs, 1, offset);
bool err = req->result < 0;
return std::make_pair(!err, err ? 0 : std::size_t(req->result));
return req->result < 0 ? std::optional<std::size_t>{} : std::size_t(req->result);
}

/**
Expand All @@ -639,15 +632,12 @@ class FileReq final: public FsRequest<FileReq> {

/**
* @brief Sync [fstat](http://linux.die.net/man/2/fstat).
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * An initialized instance of Stat.
* @return An optional instance of Stat correctly initialized.
*/
std::pair<bool, Stat> statSync() {
std::optional<Stat> statSync() {
auto req = get();
cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file);
return std::make_pair(!(req->result < 0), req->statbuf);
return req->result < 0 ? std::optional<Stat>{} : req->statbuf;
}

/**
Expand Down Expand Up @@ -729,20 +719,15 @@ class FileReq final: public FsRequest<FileReq> {

/**
* @brief Sync [sendfile](http://linux.die.net/man/2/sendfile).
*
* @param out A valid instance of FileHandle.
* @param offset Offset, as described in the official documentation.
* @param length Length, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * The amount of data transferred.
* @return An optional amount of data transferred.
*/
std::pair<bool, std::size_t> sendfileSync(FileHandle out, int64_t offset, std::size_t length) {
std::optional<std::size_t> sendfileSync(FileHandle out, int64_t offset, std::size_t length) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, file, offset, length);
bool err = req->result < 0;
return std::make_pair(!err, err ? 0 : std::size_t(req->result));
return req->result < 0 ? std::optional<std::size_t>{} : std::size_t(req->result);
}

/**
Expand Down Expand Up @@ -941,17 +926,13 @@ class FsReq final: public FsRequest<FsReq> {

/**
* @brief Sync [mktemp](http://linux.die.net/man/3/mkdtemp).
*
* @param tpl Template, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * The actual path of the newly created directoy.
* @return An optional path of the newly created directoy.
*/
std::pair<bool, const char *> mkdtempSync(std::string tpl) {
std::optional<const char *> mkdtempSync(std::string tpl) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), req, tpl.data());
return std::make_pair(!(req->result < 0), req->path);
return req->result < 0 ? std::optional<const char *>{} : req->path;
}

/**
Expand Down Expand Up @@ -992,29 +973,19 @@ class FsReq final: public FsRequest<FsReq> {

/**
* @brief Sync [scandir](http://linux.die.net/man/3/scandir).
*
* @param path Path, as described in the official documentation.
* @param flags Flags, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * The number of directory entries selected.
* @return An optional number of directory entries selected.
*/
std::pair<bool, std::size_t> scandirSync(std::string path, int flags) {
std::optional<std::size_t> scandirSync(std::string path, int flags) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_scandir, parent(), req, path.data(), flags);
bool err = req->result < 0;
return std::make_pair(!err, err ? 0 : std::size_t(req->result));
return req->result < 0 ? std::optional<std::size_t>{} : std::size_t(req->result);
}

/**
* @brief Gets entries populated with the next directory entry data.
*
* Returns a composed value where:
*
* * The first parameter indicates the entry type (see below).
* * The second parameter is a string that contains the actual value.
*
* Available entry types are:
*
* * `FsReq::EntryType::UNKNOWN`
Expand All @@ -1030,26 +1001,15 @@ class FsReq final: public FsRequest<FsReq> {
* [documentation](http://docs.libuv.org/en/v1.x/fs.html#c.uv_dirent_t)
* for further details.
*
* @return A pair where:
*
* * The first parameter is a boolean value that indicates if the current
* entry is still valid.
* * The second parameter is a composed value (see above).
* @return An optional `std::pair` composed as it follows:
* * The first parameter indicates the entry type (see above).
* * The second parameter is a string that contains the actual value.
*/
std::pair<bool, std::pair<EntryType, const char *>> scandirNext() {
std::pair<bool, std::pair<EntryType, const char *>> ret{false, { EntryType::UNKNOWN, nullptr }};

std::optional<std::pair<EntryType, const char *>> scandirNext() {
// we cannot use cleanupAndInvokeSync because of the return value of uv_fs_scandir_next
uv_fs_req_cleanup(get());
auto res = uv_fs_scandir_next(get(), dirents);

if(UV_EOF != res) {
ret.second.first = static_cast<EntryType>(dirents[0].type);
ret.second.second = dirents[0].name;
ret.first = true;
}

return ret;
return UV_EOF == res ? std::optional<std::pair<EntryType, const char *>>{} : std::make_pair(static_cast<EntryType>(dirents[0].type), dirents[0].name);
}

/**
Expand All @@ -1066,17 +1026,13 @@ class FsReq final: public FsRequest<FsReq> {

/**
* @brief Sync [stat](http://linux.die.net/man/2/stat).
*
* @param path Path, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * An initialized instance of Stat.
* @return An optional instance of Stat properly initialized.
*/
std::pair<bool, Stat> statSync(std::string path) {
std::optional<Stat> statSync(std::string path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_stat, parent(), req, path.data());
return std::make_pair(!(req->result < 0), req->statbuf);
return req->result < 0 ? std::optional<Stat>{} : req->statbuf;
}

/**
Expand All @@ -1093,17 +1049,13 @@ class FsReq final: public FsRequest<FsReq> {

/**
* @brief Sync [lstat](http://linux.die.net/man/2/lstat).
*
* @param path Path, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * An initialized instance of Stat.
* @return An optional instance of Stat properly initialized.
*/
std::pair<bool, Stat> lstatSync(std::string path) {
std::optional<Stat> lstatSync(std::string path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_lstat, parent(), req, path.data());
return std::make_pair(!(req->result < 0), req->statbuf);
return req->result < 0 ? std::optional<Stat>{} : req->statbuf;
}

/**
Expand Down Expand Up @@ -1354,18 +1306,15 @@ class FsReq final: public FsRequest<FsReq> {
*
* @param path Path, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * A `std::pair` composed as it follows:
* * A bunch of data read from the given path.
* * The amount of data read from the given path.
* @return An optional `std::pair` composed as it follows:
* * A bunch of data read from the given path.
* * The amount of data read from the given path.
*/
std::pair<bool, std::pair<const char *, std::size_t>>
std::optional<std::pair<const char *, std::size_t>>
readlinkSync(std::string path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data());
bool err = req->result < 0;
return std::make_pair(!err, std::make_pair(static_cast<char *>(req->ptr), err ? 0 : std::size_t(req->result)));
return req->result < 0 ? std::optional<std::pair<const char *, std::size_t>>{} : std::make_pair(static_cast<char *>(req->ptr), std::size_t(req->result));
}

/**
Expand All @@ -1382,17 +1331,13 @@ class FsReq final: public FsRequest<FsReq> {

/**
* @brief Sync [realpath](http://linux.die.net/man/3/realpath).
*
* @param path Path, as described in the official documentation.
*
* @return A `std::pair` composed as it follows:
* * A boolean value that is true in case of success, false otherwise.
* * The canonicalized absolute pathname.
* @return An optional canonicalized absolute pathname.
*/
std::pair<bool, const char *> realpathSync(std::string path) {
std::optional<const char *> realpathSync(std::string path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_realpath, parent(), req, path.data());
return std::make_pair(!(req->result < 0), req->path);
return req->result < 0 ? std::optional<const char *>{} : req->path;
}

/**
Expand Down Expand Up @@ -1533,11 +1478,6 @@ class FsReq final: public FsRequest<FsReq> {
* @brief Iterates synchronously over a directory stream one entry at a
* time.
*
* Returns a composed value where:
*
* * The first parameter indicates the entry type (see below).
* * The second parameter is a string that contains the actual value.
*
* Available entry types are:
*
* * `FsReq::EntryType::UNKNOWN`
Expand All @@ -1556,19 +1496,17 @@ class FsReq final: public FsRequest<FsReq> {
* This function isn't thread safe. Moreover, it doesn't return the `.` and
* `..` entries.
*
* @return A pair where:
*
* * The first parameter is a boolean value that indicates if the current
* entry is still valid.
* * The second parameter is a composed value (see above).
* @return An optional `std::pair` composed as it follows:
* * The first parameter indicates the entry type (see above).
* * The second parameter is a string that contains the actual value.
*/
std::pair<bool, std::pair<EntryType, const char *>> readdirSync() {
std::optional<std::pair<EntryType, const char *>> readdirSync() {
auto req = get();
auto *dir = static_cast<uv_dir_t *>(req->ptr);
dir->dirents = dirents;
dir->nentries = 1;
cleanupAndInvokeSync(&uv_fs_readdir, parent(), req, dir);
return {req->result != 0, { static_cast<EntryType>(dirents[0].type), dirents[0].name }};
return req->result != 0 ? std::optional<std::pair<EntryType, const char *>>{} : std::make_pair(static_cast<EntryType>(dirents[0].type), dirents[0].name);
}

private:
Expand Down
20 changes: 10 additions & 10 deletions test/uvw/file_req.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,14 @@ TEST(FileReq, RWSync) {

auto writeR = request->writeSync(std::unique_ptr<char[]>{new char[1]{ 42 }}, 1, 0);

ASSERT_TRUE(writeR.first);
ASSERT_EQ(writeR.second, std::size_t{1});
ASSERT_TRUE(writeR);
ASSERT_EQ(*writeR, std::size_t{1});

auto readR = request->readSync(0, 1);

ASSERT_TRUE(readR.first);
ASSERT_EQ(readR.second.first[0], 42);
ASSERT_EQ(readR.second.second, std::size_t{1});
ASSERT_TRUE(readR);
ASSERT_EQ(readR->first[0], 42);
ASSERT_EQ(readR->second, std::size_t{1});
ASSERT_TRUE(request->closeSync());

loop->run();
Expand Down Expand Up @@ -239,7 +239,7 @@ TEST(FileReq, StatSync) {

auto statR = request->statSync();

ASSERT_TRUE(statR.first);
ASSERT_TRUE(statR);
ASSERT_TRUE(request->closeSync());

loop->run();
Expand Down Expand Up @@ -426,7 +426,7 @@ TEST(FileReq, SendFileSync) {

auto sendfileR = srcReq->sendfileSync(static_cast<uvw::FileHandle>(*dstReq), 0, 0);

ASSERT_TRUE(sendfileR.first);
ASSERT_TRUE(sendfileR);
ASSERT_TRUE(srcReq->closeSync());
ASSERT_TRUE(dstReq->closeSync());

Expand Down Expand Up @@ -574,9 +574,9 @@ TEST(FileReq, ChownSync) {

auto statR = request->statSync();

ASSERT_TRUE(statR.first);
auto uid = static_cast<uvw::Uid>(statR.second.st_uid);
auto gid = static_cast<uvw::Uid>(statR.second.st_gid);
ASSERT_TRUE(statR);
auto uid = static_cast<uvw::Uid>(statR->st_uid);
auto gid = static_cast<uvw::Uid>(statR->st_gid);
ASSERT_TRUE(request->chownSync(uid, gid));
ASSERT_TRUE(request->closeSync());

Expand Down
Loading

0 comments on commit 331f958

Please sign in to comment.