Skip to content

Commit

Permalink
Add error_code overloads for observers and modifiers (#141)
Browse files Browse the repository at this point in the history
Add overloads with `std::error_code&` for error reporting for:
- `entry::move`
- `directory::list`
- `file::read`
- `file::write`
- `file::append`
  • Loading branch information
bugdea1er authored Jan 16, 2025
1 parent a4a0dca commit b07e26f
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 11 deletions.
11 changes: 10 additions & 1 deletion include/tmp/directory
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <cstddef>
#include <filesystem>
#include <string_view>
#include <system_error>

namespace tmp {

Expand All @@ -29,6 +30,7 @@ namespace tmp {
///
/// auto func() {
/// auto tmpdir = tmp::directory("org.example.product");
/// std::ostream(tmpdir / "file.txt") << "Hello, world!";
///
/// // the temporary directory is deleted recursively when the
/// // tmp::directory object goes out of scope and is destroyed
Expand All @@ -52,15 +54,22 @@ public:
std::string_view label = "");

/// Concatenates this directory path with a given source
/// @param source A string which represents a path name
/// @param[in] source A string which represents a path name
/// @returns The result of path concatenation
std::filesystem::path operator/(std::string_view source) const;

/// Returns an iterator over the contents of this directory
/// @note The special pathnames `.` and `..` are skipped
/// @returns The iterator over this directory
/// @throws std::filesystem::filesystem_error on underlying OS API errors
std::filesystem::directory_iterator list() const;

/// Returns an iterator over the contents of this directory
/// @note The special pathnames `.` and `..` are skipped
/// @param[out] ec Parameter for error reporting
/// @returns The iterator over this directory
std::filesystem::directory_iterator list(std::error_code& ec) const;

/// Deletes the managed directory recursively
~directory() noexcept override;

Expand Down
11 changes: 10 additions & 1 deletion include/tmp/entry
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <cstddef>
#include <filesystem>
#include <system_error>
#include <utility>

namespace tmp {
Expand Down Expand Up @@ -45,10 +46,18 @@ public:
/// ownership of the managed path; behaves like `std::filesystem::rename`
/// even when moving between filesystems
/// @note The target path parent is created when this function is called
/// @param to A path to the target file or directory
/// @param[in] to A path to the target file or directory
/// @throws std::filesystem::filesystem_error if cannot move the owned path
void move(const std::filesystem::path& to);

/// Moves the managed path recursively to a given target, releasing
/// ownership of the managed path; behaves like `std::filesystem::rename`
/// even when moving between filesystems
/// @note The target path parent is created when this function is called
/// @param[in] to A path to the target file or directory
/// @param[out] ec Parameter for error reporting
void move(const std::filesystem::path& to, std::error_code& ec);

/// Deletes the managed path recursively and closes its handle
virtual ~entry() noexcept;

Expand Down
19 changes: 17 additions & 2 deletions include/tmp/file
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,31 @@ public:
/// @throws std::filesystem::filesystem_error if cannot read the file contents
std::string read() const;

/// Reads the entire contents of this file
/// @param[out] ec Parameter for error reporting
/// @returns A string with this file contents
std::string read(std::error_code& ec) const;

/// Writes the given content to this file discarding any previous content
/// @param content A string to write to this file
/// @param[in] content A string to write to this file
/// @throws std::filesystem::filesystem_error if cannot write to the file
void write(std::string_view content) const;

/// Writes the given content to this file discarding any previous content
/// @param[in] content A string to write to this file
/// @param[out] ec Parameter for error reporting
void write(std::string_view content, std::error_code& ec) const;

/// Appends the given content to the end of this file
/// @param content A string to append to this file
/// @param[in] content A string to append to this file
/// @throws std::filesystem::filesystem_error if cannot append to the file
void append(std::string_view content) const;

/// Appends the given content to the end of this file
/// @param[in] content A string to append to this file
/// @param[out] ec Parameter for error reporting
void append(std::string_view content, std::error_code& ec) const;

/// Returns the input stream to this file
/// @returns An opened stream for input operations
std::ifstream input_stream() const;
Expand Down
14 changes: 13 additions & 1 deletion src/directory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,19 @@ fs::path directory::operator/(std::string_view source) const {
}

fs::directory_iterator directory::list() const {
return fs::directory_iterator(path());
// TODO: can be optimized to not open the directory again using native API

std::error_code ec;
fs::directory_iterator iterator = list(ec);
if (ec) {
throw fs::filesystem_error("Cannot list a temporary directory", path(), ec);
}

return iterator;
}

fs::directory_iterator directory::list(std::error_code& ec) const {
return fs::directory_iterator(path(), ec);
}

directory::~directory() noexcept = default;
Expand Down
11 changes: 8 additions & 3 deletions src/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,18 @@ entry::native_handle_type entry::native_handle() const noexcept {

void entry::move(const fs::path& to) {
std::error_code ec;
tmp::move(*this, to, ec);
move(to, ec);

if (ec) {
throw fs::filesystem_error("Cannot move temporary entry", to, ec);
throw fs::filesystem_error("Cannot move a temporary entry", path(), to, ec);
}
}

pathobject.clear();
void entry::move(const fs::path& to, std::error_code& ec) {
tmp::move(*this, to, ec);
if (!ec) {
pathobject.clear();
}
}

bool entry::operator==(const entry& rhs) const noexcept {
Expand Down
42 changes: 39 additions & 3 deletions src/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,35 +90,71 @@ file file::copy(const fs::path& path, std::string_view label,
}

std::string file::read() const {
std::error_code ec;
std::string content = read(ec);

if (ec) {
throw fs::filesystem_error("Cannot read a temporary file", path(), ec);
}

return content;
}

std::string file::read(std::error_code& ec) const {
// TODO: can be optimized to not open the file again using native API

try {
std::ifstream stream = input_stream();
stream.exceptions(std::ios::failbit | std::ios::badbit);

return std::string(std::istreambuf_iterator(stream), {});
} catch (const std::ios::failure& err) {
throw fs::filesystem_error("Cannot read a temporary file", err.code());
ec = err.code();
return std::string();
}
}

void file::write(std::string_view content) const {
std::error_code ec;
write(content, ec);

if (ec) {
throw fs::filesystem_error("Cannot write to a temporary file", path(), ec);
}
}

void file::write(std::string_view content, std::error_code& ec) const {
// TODO: can be optimized to not open the file again using native API

try {
std::ofstream stream = output_stream(std::ios::trunc);
stream.exceptions(std::ios::failbit | std::ios::badbit);

stream << content;
} catch (const std::ios::failure& err) {
throw fs::filesystem_error("Cannot write to a temporary file", err.code());
ec = err.code();
}
}

void file::append(std::string_view content) const {
std::error_code ec;
append(content, ec);

if (ec) {
throw fs::filesystem_error("Cannot append to a temporary file", path(), ec);
}
}

void file::append(std::string_view content, std::error_code& ec) const {
// TODO: can be optimized to not open the file again using native API

try {
std::ofstream stream = output_stream(std::ios::app);
stream.exceptions(std::ios::failbit | std::ios::badbit);

stream << content;
} catch (const std::ios::failure& err) {
throw fs::filesystem_error("Cannot write to a temporary file", err.code());
ec = err.code();
}
}

Expand Down

0 comments on commit b07e26f

Please sign in to comment.