Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 60 additions & 1 deletion include/boost/corosio/stream_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,18 @@ class BOOST_COROSIO_DECL stream_file : public io_stream
std::filesystem::path const& path,
file_base::flags mode = file_base::read_only);

/** Open a file.

@param path The filesystem path to open.
@param mode Bitmask of @ref file_base::flags specifying
access mode and creation behavior.
@param ec Output error code.
*/
void open(
std::filesystem::path const& path,
file_base::flags mode,
std::error_code& ec);

/** Close the file.

Releases file resources. Any pending operations complete
Expand Down Expand Up @@ -203,41 +215,76 @@ class BOOST_COROSIO_DECL stream_file : public io_stream
*/
std::uint64_t size() const;

/** Return the file size in bytes.

@param ec Output error code.
*/
std::uint64_t size(std::error_code& ec) const;

/** Resize the file to @p new_size bytes.

@param new_size The new file size.
@throws std::system_error on failure.
*/
void resize(std::uint64_t new_size);

/** Resize the file to @p new_size bytes.

@param new_size The new file size.
@param ec Output error code.
*/
void resize(std::uint64_t new_size, std::error_code& ec);

/** Synchronize file data to stable storage.

@throws std::system_error on failure.
*/
void sync_data();

/** Synchronize file data to stable storage.

@param ec Output error code.
*/
void sync_data(std::error_code& ec);

/** Synchronize file data and metadata to stable storage.

@throws std::system_error on failure.
*/
void sync_all();

/** Synchronize file data and metadata to stable storage.

@param ec Output error code.
*/
void sync_all(std::error_code& ec);

/** Release ownership of the native handle.

The file object becomes not-open. The caller is
responsible for closing the returned handle.

@return The native file descriptor or handle.
@throws std::system_error on failure.
*/
native_handle_type release();

/** Release ownership of the native handle.

The file object becomes not-open. The caller is
responsible for closing the returned handle.

@param ec Output error code.
@return The native file descriptor or handle.
*/
native_handle_type release(std::error_code& ec);

/** Adopt an existing native handle.

Closes any currently open file before adopting.
The file object takes ownership of the handle.

@param handle The native file descriptor or handle.
@throws std::system_error on failure.
*/
void assign(native_handle_type handle);

Expand All @@ -252,6 +299,18 @@ class BOOST_COROSIO_DECL stream_file : public io_stream
seek(std::int64_t offset,
file_base::seek_basis origin = file_base::seek_set);

/** Move the file position.

@param offset Signed offset from @p origin.
@param origin The reference point for the seek.
@param ec Output error code.
@return The new absolute position.
*/
std::uint64_t
seek(std::int64_t offset,
file_base::seek_basis origin,
std::error_code& ec);

protected:
/// Default-construct (for derived types that initialize io_object directly).
stream_file() noexcept = default;
Expand Down
121 changes: 98 additions & 23 deletions src/corosio/src/stream_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <boost/corosio/stream_file.hpp>
#include <boost/corosio/detail/except.hpp>
#include <boost/corosio/detail/platform.hpp>
#include <system_error>

#if BOOST_COROSIO_HAS_IOCP
#include <boost/corosio/native/detail/iocp/win_file_service.hpp>
Expand All @@ -33,16 +34,28 @@ stream_file::stream_file(capy::execution_context& ctx)
{
}

void
stream_file::open(std::filesystem::path const& path, file_base::flags mode)
{
std::error_code ec;
open(path, mode, ec);
if (ec)
{
detail::throw_system_error(ec, "stream_file::open");
}
}

void
stream_file::open(
std::filesystem::path const& path, file_base::flags mode)
std::filesystem::path const& path,
file_base::flags mode,
std::error_code& ec)
{
ec.clear();
if (is_open())
close();
auto& svc = static_cast<detail::file_service&>(h_.service());
std::error_code ec = svc.open_file(get(), path, mode);
if (ec)
detail::throw_system_error(ec, "stream_file::open");
auto& svc = static_cast<detail::file_service&>(h_.service());
ec = svc.open_file(get(), path, mode);
}

void
Expand Down Expand Up @@ -78,50 +91,100 @@ stream_file::native_handle() const noexcept
std::uint64_t
stream_file::size() const
{
std::error_code ec;
std::uint64_t sz = size(ec);
if (ec)
{
detail::throw_system_error(ec, "stream_file::size");
}
return sz;
}

std::uint64_t
stream_file::size(std::error_code& ec) const
{
ec.clear();
if (!is_open())
detail::throw_system_error(
make_error_code(std::errc::bad_file_descriptor),
"stream_file::size");
ec = make_error_code(std::errc::bad_file_descriptor);
return get().size();
}

void
stream_file::resize(std::uint64_t new_size)
{
std::error_code ec;
resize(new_size, ec);
if (ec)
{
detail::throw_system_error(ec, "stream_file::resize");
}
}

void
stream_file::resize(std::uint64_t new_size, std::error_code& ec)
{
ec.clear();
if (!is_open())
detail::throw_system_error(
make_error_code(std::errc::bad_file_descriptor),
"stream_file::resize");
ec = make_error_code(std::errc::bad_file_descriptor);
get().resize(new_size);
}

void
stream_file::sync_data()
{
std::error_code ec;
sync_data(ec);
if (ec)
{
detail::throw_system_error(ec, "stream_file::sync_data");
}
}

void
stream_file::sync_data(std::error_code& ec)
{
if (!is_open())
detail::throw_system_error(
make_error_code(std::errc::bad_file_descriptor),
"stream_file::sync_data");
ec = make_error_code(std::errc::bad_file_descriptor);
get().sync_data();
}

void
stream_file::sync_all()
{
std::error_code ec;
sync_all(ec);
if (ec)
{
detail::throw_system_error(ec, "stream_file::sync_all");
}
}

void
stream_file::sync_all(std::error_code& ec)
{
ec.clear();
if (!is_open())
detail::throw_system_error(
make_error_code(std::errc::bad_file_descriptor),
"stream_file::sync_all");
ec = make_error_code(std::errc::bad_file_descriptor);
get().sync_all();
}

native_handle_type
stream_file::release()
{
std::error_code ec;
native_handle_type h = release(ec);
if (ec)
{
detail::throw_system_error(ec, "stream_file::release");
}
return h;
}
native_handle_type
stream_file::release(std::error_code& ec)
{
ec.clear();
if (!is_open())
detail::throw_system_error(
make_error_code(std::errc::bad_file_descriptor),
"stream_file::release");
ec = make_error_code(std::errc::bad_file_descriptor);
return get().release();
}

Expand All @@ -136,10 +199,22 @@ stream_file::assign(native_handle_type handle)
std::uint64_t
stream_file::seek(std::int64_t offset, file_base::seek_basis origin)
{
std::error_code ec;
std::uint64_t pos = seek(offset, origin, ec);
if (ec)
{
detail::throw_system_error(ec, "stream_file::seek");
}
return pos;
}

std::uint64_t
stream_file::seek(
std::int64_t offset, file_base::seek_basis origin, std::error_code& ec)
{
ec.clear();
if (!is_open())
detail::throw_system_error(
make_error_code(std::errc::bad_file_descriptor),
"stream_file::seek");
ec = make_error_code(std::errc::bad_file_descriptor);
return get().seek(offset, origin);
}

Expand Down