diff --git a/include/boost/http_proto.hpp b/include/boost/http_proto.hpp index f552d00c..de591acd 100644 --- a/include/boost/http_proto.hpp +++ b/include/boost/http_proto.hpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/include/boost/http_proto/detail/file_posix.hpp b/include/boost/http_proto/detail/file_posix.hpp deleted file mode 100644 index caba34f8..00000000 --- a/include/boost/http_proto/detail/file_posix.hpp +++ /dev/null @@ -1,116 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#ifndef BOOST_HTTP_PROTO_DETAIL_FILE_POSIX_HPP -#define BOOST_HTTP_PROTO_DETAIL_FILE_POSIX_HPP - -#include - -#if ! defined(BOOST_HTTP_PROTO_NO_POSIX_FILE) -# if ! defined(__APPLE__) && ! defined(__linux__) && ! defined(__FreeBSD__) && ! defined(__NetBSD__) -# define BOOST_HTTP_PROTO_NO_POSIX_FILE -# endif -#endif - -#if ! defined(BOOST_HTTP_PROTO_USE_POSIX_FILE) -# if ! defined(BOOST_HTTP_PROTO_NO_POSIX_FILE) -# define BOOST_HTTP_PROTO_USE_POSIX_FILE 1 -# else -# define BOOST_HTTP_PROTO_USE_POSIX_FILE 0 -# endif -#endif - -#if BOOST_HTTP_PROTO_USE_POSIX_FILE - -#include -#include -#include -#include - -namespace boost { -namespace http_proto { -namespace detail { - -// Implementation of File for POSIX systems. -class file_posix -{ - int fd_ = -1; - - BOOST_HTTP_PROTO_DECL - static - int - native_close(int& fd); - -public: - using native_handle_type = int; - - BOOST_HTTP_PROTO_DECL - ~file_posix(); - - file_posix() = default; - - BOOST_HTTP_PROTO_DECL - file_posix(file_posix&& other) noexcept; - - BOOST_HTTP_PROTO_DECL - file_posix& - operator=(file_posix&& other) noexcept; - - native_handle_type - native_handle() const - { - return fd_; - } - - BOOST_HTTP_PROTO_DECL - void - native_handle(native_handle_type fd); - - bool - is_open() const - { - return fd_ != -1; - } - - BOOST_HTTP_PROTO_DECL - void - close(system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - void - open(char const* path, file_mode mode, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::uint64_t - size(system::error_code& ec) const; - - BOOST_HTTP_PROTO_DECL - std::uint64_t - pos(system::error_code& ec) const; - - BOOST_HTTP_PROTO_DECL - void - seek(std::uint64_t offset, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::size_t - read(void* buffer, std::size_t n, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::size_t - write(void const* buffer, std::size_t n, system::error_code& ec); -}; - -} // detail -} // http_proto -} // boost - -#endif - -#endif diff --git a/include/boost/http_proto/detail/file_stdio.hpp b/include/boost/http_proto/detail/file_stdio.hpp deleted file mode 100644 index e6121dc9..00000000 --- a/include/boost/http_proto/detail/file_stdio.hpp +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#ifndef BOOST_HTTP_PROTO_DETAIL_FILE_STDIO_HPP -#define BOOST_HTTP_PROTO_DETAIL_FILE_STDIO_HPP - -#include -#include -#include -#include -#include - -namespace boost { -namespace http_proto { -namespace detail { - -// Implementation of File which uses cstdio. -class file_stdio -{ - std::FILE* f_ = nullptr; - -public: - using native_handle_type = std::FILE*; - - BOOST_HTTP_PROTO_DECL - ~file_stdio(); - - file_stdio() = default; - - BOOST_HTTP_PROTO_DECL - file_stdio(file_stdio&& other) noexcept; - - BOOST_HTTP_PROTO_DECL - file_stdio& - operator=(file_stdio&& other) noexcept; - - std::FILE* - native_handle() const - { - return f_; - } - - BOOST_HTTP_PROTO_DECL - void - native_handle(std::FILE* f); - - bool - is_open() const - { - return f_ != nullptr; - } - - BOOST_HTTP_PROTO_DECL - void - close(system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - void - open(char const* path, file_mode mode, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::uint64_t - size(system::error_code& ec) const; - - BOOST_HTTP_PROTO_DECL - std::uint64_t - pos(system::error_code& ec) const; - - BOOST_HTTP_PROTO_DECL - void - seek(std::uint64_t offset, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::size_t - read(void* buffer, std::size_t n, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::size_t - write(void const* buffer, std::size_t n, system::error_code& ec); -}; - -} // detail -} // http_proto -} // boost - -#endif diff --git a/include/boost/http_proto/detail/file_win32.hpp b/include/boost/http_proto/detail/file_win32.hpp deleted file mode 100644 index 21f20e03..00000000 --- a/include/boost/http_proto/detail/file_win32.hpp +++ /dev/null @@ -1,106 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#ifndef BOOST_HTTP_PROTO_DETAIL_FILE_WIN32_HPP -#define BOOST_HTTP_PROTO_DETAIL_FILE_WIN32_HPP - -#include - -#if ! defined(BOOST_HTTP_PROTO_USE_WIN32_FILE) -# ifdef _WIN32 -# define BOOST_HTTP_PROTO_USE_WIN32_FILE 1 -# else -# define BOOST_HTTP_PROTO_USE_WIN32_FILE 0 -# endif -#endif - -#if BOOST_HTTP_PROTO_USE_WIN32_FILE - -#include -#include -#include -#include - -namespace boost { -namespace http_proto { -namespace detail { - -// Implementation of File for Win32. -class file_win32 -{ - boost::winapi::HANDLE_ h_ = - boost::winapi::INVALID_HANDLE_VALUE_; - -public: - using native_handle_type = boost::winapi::HANDLE_; - - BOOST_HTTP_PROTO_DECL - ~file_win32(); - - file_win32() = default; - - BOOST_HTTP_PROTO_DECL - file_win32(file_win32&& other) noexcept; - - BOOST_HTTP_PROTO_DECL - file_win32& - operator=(file_win32&& other) noexcept; - - native_handle_type - native_handle() - { - return h_; - } - - BOOST_HTTP_PROTO_DECL - void - native_handle(native_handle_type h); - - bool - is_open() const - { - return h_ != boost::winapi::INVALID_HANDLE_VALUE_; - } - - BOOST_HTTP_PROTO_DECL - void - close(system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - void - open(char const* path, file_mode mode, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::uint64_t - size(system::error_code& ec) const; - - BOOST_HTTP_PROTO_DECL - std::uint64_t - pos(system::error_code& ec) const; - - BOOST_HTTP_PROTO_DECL - void - seek(std::uint64_t offset, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::size_t - read(void* buffer, std::size_t n, system::error_code& ec); - - BOOST_HTTP_PROTO_DECL - std::size_t - write(void const* buffer, std::size_t n, system::error_code& ec); -}; - -} // detail -} // http_proto -} // boost - -#endif - -#endif diff --git a/include/boost/http_proto/file.hpp b/include/boost/http_proto/file.hpp deleted file mode 100644 index c03df376..00000000 --- a/include/boost/http_proto/file.hpp +++ /dev/null @@ -1,394 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) -// Copyright (c) 2025 Mohammad Nejati -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#ifndef BOOST_HTTP_PROTO_FILE_HPP -#define BOOST_HTTP_PROTO_FILE_HPP - -#include -#include -#include -#include -#include -#include -namespace boost { -namespace http_proto { - -/** A platform-independent file stream. - - This class provides a portable interface for - reading from and writing to files. It is - intended for use with @ref file_sink and @ref - file_source to enable streaming HTTP message - bodies to and from files. - - @par Example 1 - @code - file f("example.zip", file_mode::scan); - response.set_payload_size(f.size()); - serializer.start(response, std::move(f)); - @endcode - - @par Example 2 - @code - parser.set_body("example.zip", file_mode::write_new); - @endcode - - @see - @ref file_mode, - @ref file_sink, - @ref file_source. -*/ -class file -{ -#if BOOST_HTTP_PROTO_USE_WIN32_FILE - using impl_type = detail::file_win32; -#elif BOOST_HTTP_PROTO_USE_POSIX_FILE - using impl_type = detail::file_posix; -#else - using impl_type = detail::file_stdio; -#endif - - impl_type impl_; - -public: - /** The type of the underlying native file handle. - - This type is platform-specific. - */ - using native_handle_type = impl_type::native_handle_type; - - /** Constructor. - - There is no open file initially. - */ - file() = default; - - /** Constructor. - - Open a file at the given path with the specified mode. - - @par Exception Safety - Exception thrown if operation fails. - - @throw system_error - Operation fails. - - @param path The UTF-8 encoded path to the file. - - @param mode The file mode to use. - - @see - @ref file_mode, - @ref open. - */ - file(char const* path, file_mode mode) - { - open(path, mode); - } - - /** Constructor. - - The moved-from object behaves as if default-constructed. - */ - file(file&& other) noexcept = default; - - /** Assignment - - The moved-from object behaves as if default-constructed. - */ - file& - operator=( - file&& other) noexcept = default; - - /** Destructor - - If the file is open it is first closed. - */ - ~file() = default; - - /** Returns the native handle associated with the file. - */ - native_handle_type - native_handle() - { - return impl_.native_handle(); - } - - /** Set the native file handle. - - If the file is open it is first closed. - - @param h The native handle to assign. - */ - void - native_handle(native_handle_type h) - { - impl_.native_handle(h); - } - - /** Return true if the file is open. - */ - bool - is_open() const - { - return impl_.is_open(); - } - - /** Close the file if open. - - Note that, The descriptor is closed even if the function - reports an error. - - @param ec Set to the error, if any occurred. - */ - void - close(system::error_code& ec) - { - impl_.close(ec); - } - - /** Close the file if open. - - Note that, The descriptor is closed even if the function - reports an error. - - @par Exception Safety - Exception thrown if operation fails. - - @throw system_error - Operation fails. - */ - void - close() - { - system::error_code ec; - impl_.close(ec); - if(ec.failed()) - detail::throw_system_error(ec); - } - - /** Open a file at the given path with the specified mode. - - @param path The UTF-8 encoded path to the file. - - @param mode The file mode to use. - - @param ec Set to the error, if any occurred. - - @see - @ref file_mode. - */ - void - open(char const* path, file_mode mode, system::error_code& ec) - { - impl_.open(path, mode, ec); - } - - /** Open a file at the given path with the specified mode. - - @param path The UTF-8 encoded path to the file. - - @param mode The file mode to use. - - @par Exception Safety - Exception thrown if operation fails. - - @throw system_error - Operation fails. - - @see - @ref file_mode. - */ - void - open(char const* path, file_mode mode) - { - system::error_code ec; - impl_.open(path, mode, ec); - if(ec.failed()) - detail::throw_system_error(ec); - } - - /** Return the size of the open file in bytes. - - @param ec Set to the error, if any occurred. - */ - std::uint64_t - size(system::error_code& ec) const - { - return impl_.size(ec); - } - - /** Return the size of the open file in bytes. - - @par Exception Safety - Exception thrown if operation fails. - - @throw system_error - Operation fails. - */ - std::uint64_t - size() const - { - system::error_code ec; - auto r = impl_.size(ec); - if(ec.failed()) - detail::throw_system_error(ec); - return r; - } - - /** Return the current position in the file, in bytes from the beginning. - - @param ec Set to the error, if any occurred. - */ - std::uint64_t - pos(system::error_code& ec) const - { - return impl_.pos(ec); - } - - /** Return the current position in the file, in bytes from the beginning. - - @par Exception Safety - Exception thrown if operation fails. - - @throw system_error - Operation fails. - */ - std::uint64_t - pos() const - { - system::error_code ec; - auto r = impl_.pos(ec); - if(ec.failed()) - detail::throw_system_error(ec); - return r; - } - - /** Set the current position in the file. - - @param offset The byte offset from the beginning of the file. - - @param ec Set to the error, if any occurred. - */ - void - seek(std::uint64_t offset, system::error_code& ec) - { - impl_.seek(offset, ec); - } - - /** Set the current position in the file. - - @par Exception Safety - Exception thrown if operation fails. - - @throw system_error - Operation fails. - - @param offset The byte offset from the beginning of the file. - */ - void - seek(std::uint64_t offset) - { - system::error_code ec; - impl_.seek(offset, ec); - if(ec.failed()) - detail::throw_system_error(ec); - } - - /** Read data from the file. - - @return The number of bytes read. Returns - 0 on end-of-file or if an error occurs (in - which case @p ec is set). - - @param buffer The buffer to store the read data. - - @param n The number of bytes to read. - - @param ec Set to the error, if any occurred. - */ - std::size_t - read(void* buffer, std::size_t n, system::error_code& ec) - { - return impl_.read(buffer, n, ec); - } - - /** Read data from the file. - - @par Exception Safety - Exception thrown if operation fails. - - @throw system_error - Operation fails. - - @return The number of bytes read. Returns - 0 on end-of-file. - - @param buffer The buffer to store the read data. - - @param n The number of bytes to read. - */ - std::size_t - read(void* buffer, std::size_t n) - { - system::error_code ec; - auto r = impl_.read(buffer, n, ec); - if(ec.failed()) - detail::throw_system_error(ec); - return r; - } - - /** Write data to the file. - - @return The number of bytes written. - Returns 0 on error (in which case @p ec is - set). - - @param buffer The buffer containing the data to write. - - @param n The number of bytes to write. - - @param ec Set to the error, if any occurred. - */ - std::size_t - write(void const* buffer, std::size_t n, system::error_code& ec) - { - return impl_.write(buffer, n, ec); - } - - /** Write data to the file. - - @par Exception Safety - Exception thrown if operation fails. - - @throw system_error - Operation fails. - - @return The number of bytes written. - - @param buffer The buffer containing the data to write. - - @param n The number of bytes to write. - */ - std::size_t - write(void const* buffer, std::size_t n) - { - system::error_code ec; - auto r = impl_.write(buffer, n, ec); - if(ec.failed()) - detail::throw_system_error(ec); - return r; - } -}; - -} // http_proto -} // boost - -#endif diff --git a/include/boost/http_proto/file_mode.hpp b/include/boost/http_proto/file_mode.hpp deleted file mode 100644 index 266a7298..00000000 --- a/include/boost/http_proto/file_mode.hpp +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) -// Copyright (c) 2025 Mohammad Nejati -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#ifndef BOOST_HTTP_PROTO_FILE_MODE_HPP -#define BOOST_HTTP_PROTO_FILE_MODE_HPP - -namespace boost { -namespace http_proto { - -/** File open modes - - These modes are used when opening files using - instances of the @ref file. - - @code - file_mode access sharing seeking file std mode - -------------------------------------------------------------------------------------- - read read-only shared random must exist "rb" - scan read-only shared sequential must exist "rbS" - write read/write exclusive random create/truncate "wb+" - write_new read/write exclusive random must not exist "wbx" - write_existing read/write exclusive random must exist "rb+" - append write-only exclusive sequential create/truncate "ab" - append_existing write-only exclusive sequential must exist "ab" - @endcode - - @see - @ref file. -*/ -enum class file_mode -{ - /** Random read-only access to an existing file. - */ - read, - - /** Sequential read-only access to an existing file. - */ - scan, - - /** Random reading and writing to a new or truncated file. - - This mode permits random-access reading and writing - for the specified file. If the file does not exist - prior to the function call, it is created with an - initial size of zero bytes. Otherwise if the file - already exists, the size is truncated to zero bytes. - */ - write, - - /** Random reading and writing to a new file only. - - This mode permits random-access reading and writing - for the specified file. The file will be created with - an initial size of zero bytes. If the file already exists - prior to the function call, an error is returned and - no file is opened. - */ - write_new, - - /** Random write-only access to existing file. - - If the file does not exist, an error is generated. - */ - write_existing, - - /** Appending to a new or truncated file. - - The current file position shall be set to the end of - the file prior to each write. - - @li If the file does not exist, it is created. - - @li If the file exists, it is truncated to - zero size upon opening. - */ - append, - - /** Appending to an existing file. - - The current file position shall be set to the end of - the file prior to each write. - - If the file does not exist, an error is generated. - */ - append_existing -}; - -} // http_proto -} // boost - -#endif diff --git a/include/boost/http_proto/file_sink.hpp b/include/boost/http_proto/file_sink.hpp index 574e70fc..2cbc7fab 100644 --- a/include/boost/http_proto/file_sink.hpp +++ b/include/boost/http_proto/file_sink.hpp @@ -12,8 +12,8 @@ #define BOOST_HTTP_PROTO_FILE_SINK_HPP #include -#include #include +#include namespace boost { namespace http_proto { @@ -39,7 +39,7 @@ namespace http_proto { class file_sink : public sink { - file f_; + capy::file f_; public: /** Constructor. @@ -49,7 +49,7 @@ class file_sink */ BOOST_HTTP_PROTO_DECL explicit - file_sink(file&& f) noexcept; + file_sink(capy::file&& f) noexcept; file_sink() = delete; file_sink(file_sink const&) = delete; diff --git a/include/boost/http_proto/file_source.hpp b/include/boost/http_proto/file_source.hpp index 88d98a21..a7f71555 100644 --- a/include/boost/http_proto/file_source.hpp +++ b/include/boost/http_proto/file_source.hpp @@ -12,8 +12,8 @@ #define BOOST_HTTP_PROTO_FILE_SOURCE_HPP #include -#include #include +#include #include namespace boost { @@ -41,7 +41,7 @@ namespace http_proto { class file_source : public source { - file f_; + capy::file f_; std::uint64_t n_; public: @@ -57,7 +57,7 @@ class file_source */ BOOST_HTTP_PROTO_DECL file_source( - file&& f, + capy::file&& f, std::uint64_t limit = std::uint64_t(-1)) noexcept; diff --git a/src/detail/file_posix.cpp b/src/detail/file_posix.cpp deleted file mode 100644 index cc1f14f5..00000000 --- a/src/detail/file_posix.cpp +++ /dev/null @@ -1,358 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#include - -#if BOOST_HTTP_PROTO_USE_POSIX_FILE - -#include -#include -#include -#include -#include -#include -#include -#include - -#if ! defined(BOOST_HTTP_PROTO_NO_POSIX_FADVISE) -# if defined(__APPLE__) || (defined(__ANDROID__) && (__ANDROID_API__ < 21)) -# define BOOST_HTTP_PROTO_NO_POSIX_FADVISE -# endif -#endif - -#if ! defined(BOOST_HTTP_PROTO_USE_POSIX_FADVISE) -# if ! defined(BOOST_HTTP_PROTO_NO_POSIX_FADVISE) -# define BOOST_HTTP_PROTO_USE_POSIX_FADVISE 1 -# else -# define BOOST_HTTP_PROTO_USE_POSIX_FADVISE 0 -# endif -#endif - -namespace boost { -namespace http_proto { -namespace detail { - -int -file_posix:: -native_close(native_handle_type& fd) -{ -/* https://github.com/boostorg/beast/issues/1445 - - This function is tuned for Linux / Mac OS: - - * only calls close() once - * returns the error directly to the caller - * does not loop on EINTR - - If this is incorrect for the platform, then the - caller will need to implement their own type - meeting the File requirements and use the correct - behavior. - - See: - http://man7.org/linux/man-pages/man2/close.2.html -*/ - int ev = 0; - if(fd != -1) - { - if(::close(fd) != 0) - ev = errno; - fd = -1; - } - return ev; -} - -file_posix:: -~file_posix() -{ - native_close(fd_); -} - -file_posix:: -file_posix( - file_posix&& other) noexcept - : fd_(boost::exchange(other.fd_, -1)) -{ -} - -file_posix& -file_posix:: -operator=( - file_posix&& other) noexcept -{ - if(&other == this) - return *this; - native_close(fd_); - fd_ = other.fd_; - other.fd_ = -1; - return *this; -} - -void -file_posix:: -native_handle(native_handle_type fd) -{ - native_close(fd_); - fd_ = fd; -} - -void -file_posix:: -close( - system::error_code& ec) -{ - auto const ev = native_close(fd_); - if(ev) - ec.assign(ev, - system::system_category()); - else - ec = {}; -} - -void -file_posix:: -open(char const* path, file_mode mode, system::error_code& ec) -{ - auto const ev = native_close(fd_); - if(ev) - ec.assign(ev, - system::system_category()); - else - ec = {}; - - int f = 0; -#if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - int advise = 0; -#endif - switch(mode) - { - default: - case file_mode::read: - f = O_RDONLY; - #if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - advise = POSIX_FADV_RANDOM; - #endif - break; - case file_mode::scan: - f = O_RDONLY; - #if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - advise = POSIX_FADV_SEQUENTIAL; - #endif - break; - - case file_mode::write: - f = O_RDWR | O_CREAT | O_TRUNC; - #if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - advise = POSIX_FADV_RANDOM; - #endif - break; - - case file_mode::write_new: - f = O_RDWR | O_CREAT | O_EXCL; - #if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - advise = POSIX_FADV_RANDOM; - #endif - break; - - case file_mode::write_existing: - f = O_RDWR | O_EXCL; - #if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - advise = POSIX_FADV_RANDOM; - #endif - break; - - case file_mode::append: - f = O_WRONLY | O_CREAT | O_APPEND; - #if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - advise = POSIX_FADV_SEQUENTIAL; - #endif - break; - - case file_mode::append_existing: - f = O_WRONLY | O_APPEND; - #if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - advise = POSIX_FADV_SEQUENTIAL; - #endif - break; - } - for(;;) - { - fd_ = ::open(path, f, 0644); - if(fd_ != -1) - break; - auto const ev = errno; - if(ev != EINTR) - { - ec.assign(ev, - system::system_category()); - return; - } - } -#if BOOST_HTTP_PROTO_USE_POSIX_FADVISE - if(::posix_fadvise(fd_, 0, 0, advise)) - { - auto const ev = errno; - native_close(fd_); - ec.assign(ev, - system::system_category()); - return; - } -#endif - ec = {}; -} - -std::uint64_t -file_posix:: -size( - system::error_code& ec) const -{ - if(fd_ == -1) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - struct stat st; - if(::fstat(fd_, &st) != 0) - { - ec.assign(errno, - system::system_category()); - return 0; - } - ec = {}; - return st.st_size; -} - -std::uint64_t -file_posix:: -pos( - system::error_code& ec) const -{ - if(fd_ == -1) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - auto const result = ::lseek(fd_, 0, SEEK_CUR); - if(result == (::off_t)-1) - { - ec.assign(errno, - system::system_category()); - return 0; - } - ec = {}; - return result; -} - -void -file_posix:: -seek(std::uint64_t offset, - system::error_code& ec) -{ - if(fd_ == -1) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return; - } - auto const result = ::lseek(fd_, offset, SEEK_SET); - if(result == static_cast<::off_t>(-1)) - { - ec.assign(errno, - system::system_category()); - return; - } - ec = {}; -} - -std::size_t -file_posix:: -read(void* buffer, std::size_t n, - system::error_code& ec) -{ - if(fd_ == -1) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - std::size_t nread = 0; - while(n > 0) - { - // not required to define SSIZE_MAX so we avoid it - constexpr auto ssmax = - static_cast((std::numeric_limits< - decltype(::read(fd_, buffer, n))>::max)()); - auto const amount = (std::min)( - n, ssmax); - auto const result = ::read(fd_, buffer, amount); - if(result == -1) - { - auto const ev = errno; - if(ev == EINTR) - continue; - ec.assign(ev, - system::system_category()); - return nread; - } - if(result == 0) - { - // short read - return nread; - } - n -= result; - nread += result; - buffer = static_cast(buffer) + result; - } - return nread; -} - -std::size_t -file_posix:: -write(void const* buffer, std::size_t n, - system::error_code& ec) -{ - if(fd_ == -1) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - std::size_t nwritten = 0; - while(n > 0) - { - // not required to define SSIZE_MAX so we avoid it - constexpr auto ssmax = - static_cast((std::numeric_limits< - decltype(::write(fd_, buffer, n))>::max)()); - auto const amount = (std::min)( - n, ssmax); - auto const result = ::write(fd_, buffer, amount); - if(result == -1) - { - auto const ev = errno; - if(ev == EINTR) - continue; - ec.assign(ev, - system::system_category()); - return nwritten; - } - n -= result; - nwritten += result; - buffer = static_cast(buffer) + result; - } - return nwritten; -} - -} // detail -} // http_proto -} // boost - -#endif diff --git a/src/detail/file_stdio.cpp b/src/detail/file_stdio.cpp deleted file mode 100644 index a2fa3717..00000000 --- a/src/detail/file_stdio.cpp +++ /dev/null @@ -1,357 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#include "src/detail/win32_unicode_path.hpp" -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace http_proto { -namespace detail { - -file_stdio:: -~file_stdio() -{ - if(f_) - fclose(f_); -} - -file_stdio:: -file_stdio( - file_stdio&& other) noexcept - : f_(boost::exchange(other.f_, nullptr)) -{ -} - -file_stdio& -file_stdio:: -operator=( - file_stdio&& other) noexcept -{ - if(&other == this) - return *this; - if(f_) - fclose(f_); - f_ = other.f_; - other.f_ = nullptr; - return *this; -} - -void -file_stdio:: -native_handle(std::FILE* f) -{ - if(f_) - fclose(f_); - f_ = f; -} - -void -file_stdio:: -close( - system::error_code& ec) -{ - if(f_) - { - int failed = fclose(f_); - f_ = nullptr; - if(failed) - { - ec.assign(errno, - system::generic_category()); - return; - } - } - ec = {}; -} - -void -file_stdio:: -open(char const* path, file_mode mode, - system::error_code& ec) -{ - if(f_) - { - fclose(f_); - f_ = nullptr; - } - ec = {}; -#ifdef _WIN32 - boost::winapi::WCHAR_ const* s; - detail::win32_unicode_path unicode_path(path, ec); - if (ec) - return; -#else - char const* s; -#endif - switch(mode) - { - default: - case file_mode::read: - #ifdef _WIN32 - s = L"rb"; - #else - s = "rb"; - #endif - break; - - case file_mode::scan: - #ifdef _WIN32 - s = L"rbS"; - #else - s = "rb"; - #endif - break; - - case file_mode::write: - #ifdef _WIN32 - s = L"wb+"; - #else - s = "wb+"; - #endif - break; - - case file_mode::write_new: - { -#ifdef _WIN32 -# if (defined(BOOST_MSVC) && BOOST_MSVC >= 1910) || (defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION >= 141) - s = L"wbx"; -# else - std::FILE* f0; - auto const ev = ::_wfopen_s(&f0, unicode_path.c_str(), L"rb"); - if(! ev) - { - std::fclose(f0); - ec = make_error_code( - system::errc::file_exists); - return; - } - else if(ev != - system::errc::no_such_file_or_directory) - { - ec.assign(ev, - system::generic_category()); - return; - } - s = L"wb"; -# endif -#else - s = "wbx"; -#endif - break; - } - - case file_mode::write_existing: - #ifdef _WIN32 - s = L"rb+"; - #else - s = "rb+"; - #endif - break; - - case file_mode::append: - #ifdef _WIN32 - s = L"ab"; - #else - s = "ab"; - #endif - break; - - case file_mode::append_existing: - { -#ifdef _WIN32 - std::FILE* f0; - auto const ev = - ::_wfopen_s(&f0, unicode_path.c_str(), L"rb+"); - if(ev) - { - ec.assign(ev, - system::generic_category()); - return; - } -#else - auto const f0 = - std::fopen(path, "rb+"); - if(! f0) - { - ec.assign(errno, - system::generic_category()); - return; - } -#endif - std::fclose(f0); - #ifdef _WIN32 - s = L"ab"; - #else - s = "ab"; - #endif - break; - } - } - -#ifdef _WIN32 - auto const ev = ::_wfopen_s( - &f_, unicode_path.c_str(), s); - if(ev) - { - f_ = nullptr; - ec.assign(ev, - system::generic_category()); - return; - } -#else - f_ = std::fopen(path, s); - if(! f_) - { - ec.assign(errno, - system::generic_category()); - return; - } -#endif -} - -std::uint64_t -file_stdio:: -size( - system::error_code& ec) const -{ - if(! f_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - long pos = std::ftell(f_); - if(pos == -1L) - { - ec.assign(errno, - system::generic_category()); - return 0; - } - int result = std::fseek(f_, 0, SEEK_END); - if(result != 0) - { - ec.assign(errno, - system::generic_category()); - return 0; - } - long size = std::ftell(f_); - if(size == -1L) - { - ec.assign(errno, - system::generic_category()); - std::fseek(f_, pos, SEEK_SET); - return 0; - } - result = std::fseek(f_, pos, SEEK_SET); - if(result != 0) - ec.assign(errno, - system::generic_category()); - else - ec = {}; - return size; -} - -std::uint64_t -file_stdio:: -pos( - system::error_code& ec) const -{ - if(! f_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - long pos = std::ftell(f_); - if(pos == -1L) - { - ec.assign(errno, - system::generic_category()); - return 0; - } - ec = {}; - return pos; -} - -void -file_stdio:: -seek(std::uint64_t offset, - system::error_code& ec) -{ - if(! f_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return; - } - if(offset > static_cast((std::numeric_limits::max)())) - { - ec = make_error_code( - system::errc::invalid_seek); - return; - } - int result = std::fseek(f_, - static_cast(offset), SEEK_SET); - if(result != 0) - ec.assign(errno, - system::generic_category()); - else - ec = {}; -} - -std::size_t -file_stdio:: -read(void* buffer, std::size_t n, - system::error_code& ec) -{ - if(! f_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - auto nread = std::fread(buffer, 1, n, f_); - if(std::ferror(f_)) - { - ec.assign(errno, - system::generic_category()); - return 0; - } - return nread; -} - -std::size_t -file_stdio:: -write(void const* buffer, std::size_t n, - system::error_code& ec) -{ - if(! f_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - auto nwritten = std::fwrite(buffer, 1, n, f_); - if(std::ferror(f_)) - { - ec.assign(errno, - system::generic_category()); - return 0; - } - return nwritten; -} - -} // detail -} // http_proto -} // boost diff --git a/src/detail/file_win32.cpp b/src/detail/file_win32.cpp deleted file mode 100644 index e5203fc1..00000000 --- a/src/detail/file_win32.cpp +++ /dev/null @@ -1,385 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#include - -#if BOOST_HTTP_PROTO_USE_WIN32_FILE - -#include "src/detail/win32_unicode_path.hpp" -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace http_proto { -namespace detail { - -// VFALCO Can't seem to get boost/detail/winapi to work with -// this so use the non-Ex version for now. -BOOST_HTTP_PROTO_DECL -winapi::BOOL_ -set_file_pointer_ex( - winapi::HANDLE_ hFile, - winapi::LARGE_INTEGER_ lpDistanceToMove, - winapi::PLARGE_INTEGER_ lpNewFilePointer, - winapi::DWORD_ dwMoveMethod) -{ - auto dwHighPart = lpDistanceToMove.u.HighPart; - auto dwLowPart = winapi::SetFilePointer( - hFile, - lpDistanceToMove.u.LowPart, - &dwHighPart, - dwMoveMethod); - if(dwLowPart == winapi::INVALID_SET_FILE_POINTER_) - return 0; - if(lpNewFilePointer) - { - lpNewFilePointer->u.LowPart = dwLowPart; - lpNewFilePointer->u.HighPart = dwHighPart; - } - return 1; -} - -file_win32:: -~file_win32() -{ - if(h_ != winapi::INVALID_HANDLE_VALUE_) - winapi::CloseHandle(h_); -} - -file_win32:: -file_win32( - file_win32&& other) noexcept - : h_(boost::exchange(other.h_, - winapi::INVALID_HANDLE_VALUE_)) -{ -} - -file_win32& -file_win32:: -operator=( - file_win32&& other) noexcept -{ - if(&other == this) - return *this; - if(h_) - winapi::CloseHandle(h_); - h_ = other.h_; - other.h_ = winapi::INVALID_HANDLE_VALUE_; - return *this; -} - -void -file_win32:: -native_handle(native_handle_type h) -{ - if(h_ != winapi::INVALID_HANDLE_VALUE_) - winapi::CloseHandle(h_); - h_ = h; -} - -void -file_win32:: -close( - system::error_code& ec) -{ - if(h_ != winapi::INVALID_HANDLE_VALUE_) - { - if(! winapi::CloseHandle(h_)) - ec.assign( - winapi::GetLastError(), - system::system_category()); - else - ec = {}; - h_ = winapi::INVALID_HANDLE_VALUE_; - } - else - { - ec = {}; - } -} - -void -file_win32:: -open(char const* path, file_mode mode, - system::error_code& ec) -{ - if(h_ != winapi::INVALID_HANDLE_VALUE_) - { - winapi::CloseHandle(h_); - h_ = winapi::INVALID_HANDLE_VALUE_; - } - winapi::DWORD_ share_mode = 0; - winapi::DWORD_ desired_access = 0; - winapi::DWORD_ creation_disposition = 0; - winapi::DWORD_ flags_and_attributes = 0; -/* - | When the file... - This argument: | Exists Does not exist - -------------------------+------------------------------------------------------ - CREATE_ALWAYS | Truncates Creates - CREATE_NEW +-----------+ Fails Creates - OPEN_ALWAYS ===| does this |===> Opens Creates - OPEN_EXISTING +-----------+ Opens Fails - TRUNCATE_EXISTING | Truncates Fails -*/ - switch(mode) - { - default: - case file_mode::read: - desired_access = winapi::GENERIC_READ_; - share_mode = winapi::FILE_SHARE_READ_; - creation_disposition = winapi::OPEN_EXISTING_; - flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS - break; - - case file_mode::scan: - desired_access = winapi::GENERIC_READ_; - share_mode = winapi::FILE_SHARE_READ_; - creation_disposition = winapi::OPEN_EXISTING_; - flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN - break; - - case file_mode::write: - desired_access = winapi::GENERIC_READ_ | - winapi::GENERIC_WRITE_; - creation_disposition = winapi::CREATE_ALWAYS_; - flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS - break; - - case file_mode::write_new: - desired_access = winapi::GENERIC_READ_ | - winapi::GENERIC_WRITE_; - creation_disposition = winapi::CREATE_NEW_; - flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS - break; - - case file_mode::write_existing: - desired_access = winapi::GENERIC_READ_ | - winapi::GENERIC_WRITE_; - creation_disposition = winapi::OPEN_EXISTING_; - flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS - break; - - case file_mode::append: - desired_access = winapi::GENERIC_READ_ | - winapi::GENERIC_WRITE_; - - creation_disposition = winapi::OPEN_ALWAYS_; - flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN - break; - - case file_mode::append_existing: - desired_access = winapi::GENERIC_READ_ | - winapi::GENERIC_WRITE_; - creation_disposition = winapi::OPEN_EXISTING_; - flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN - break; - } - - detail::win32_unicode_path unicode_path(path, ec); - if (ec) - return; - h_ = ::CreateFileW( - unicode_path.c_str(), - desired_access, - share_mode, - NULL, - creation_disposition, - flags_and_attributes, - NULL); - if (h_ == winapi::INVALID_HANDLE_VALUE_) - { - ec.assign(winapi::GetLastError(), - system::system_category()); - return; - } - if (mode == file_mode::append || - mode == file_mode::append_existing) - { - winapi::LARGE_INTEGER_ in; - in.QuadPart = 0; - if (!detail::set_file_pointer_ex(h_, in, 0, - winapi::FILE_END_)) - { - ec.assign(winapi::GetLastError(), - system::system_category()); - winapi::CloseHandle(h_); - h_ = winapi::INVALID_HANDLE_VALUE_; - return; - } - } - ec = {}; -} - -std::uint64_t -file_win32:: -size( - system::error_code& ec) const -{ - if(h_ == winapi::INVALID_HANDLE_VALUE_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - winapi::LARGE_INTEGER_ fileSize; - if(! winapi::GetFileSizeEx(h_, &fileSize)) - { - ec.assign(winapi::GetLastError(), - system::system_category()); - return 0; - } - ec = {}; - return fileSize.QuadPart; -} - -std::uint64_t -file_win32:: -pos( - system::error_code& ec) const -{ - if(h_ == winapi::INVALID_HANDLE_VALUE_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - winapi::LARGE_INTEGER_ in; - winapi::LARGE_INTEGER_ out; - in.QuadPart = 0; - if(! detail::set_file_pointer_ex(h_, in, &out, - winapi::FILE_CURRENT_)) - { - ec.assign(winapi::GetLastError(), - system::system_category()); - return 0; - } - ec = {}; - return out.QuadPart; -} - -void -file_win32:: -seek(std::uint64_t offset, - system::error_code& ec) -{ - if(h_ == winapi::INVALID_HANDLE_VALUE_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return; - } - winapi::LARGE_INTEGER_ in; - in.QuadPart = offset; - if(! detail::set_file_pointer_ex(h_, in, 0, - winapi::FILE_BEGIN_)) - { - ec.assign(winapi::GetLastError(), - system::system_category()); - return; - } - ec = {}; -} - -std::size_t -file_win32:: -read(void* buffer, std::size_t n, - system::error_code& ec) -{ - if(h_ == winapi::INVALID_HANDLE_VALUE_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - std::size_t nread = 0; - while(n > 0) - { - winapi::DWORD_ amount; - if(n > (std::numeric_limits< - winapi::DWORD_>::max)()) - amount = (std::numeric_limits< - winapi::DWORD_>::max)(); - else - amount = static_cast< - winapi::DWORD_>(n); - winapi::DWORD_ bytesRead; - if(! ::ReadFile(h_, buffer, amount, &bytesRead, 0)) - { - auto const dwError = winapi::GetLastError(); - if(dwError != winapi::ERROR_HANDLE_EOF_) - ec.assign(dwError, - system::system_category()); - else - ec = {}; - return nread; - } - if(bytesRead == 0) - return nread; - n -= bytesRead; - nread += bytesRead; - buffer = static_cast(buffer) + bytesRead; - } - ec = {}; - return nread; -} - -std::size_t -file_win32:: -write(void const* buffer, std::size_t n, - system::error_code& ec) -{ - if(h_ == winapi::INVALID_HANDLE_VALUE_) - { - ec = make_error_code( - system::errc::bad_file_descriptor); - return 0; - } - std::size_t nwritten = 0; - while(n > 0) - { - winapi::DWORD_ amount; - if(n > (std::numeric_limits< - winapi::DWORD_>::max)()) - amount = (std::numeric_limits< - winapi::DWORD_>::max)(); - else - amount = static_cast< - winapi::DWORD_>(n); - winapi::DWORD_ bytesWritten; - if(! ::WriteFile(h_, buffer, amount, &bytesWritten, 0)) - { - auto const dwError = winapi::GetLastError(); - if(dwError != winapi::ERROR_HANDLE_EOF_) - ec.assign(dwError, - system::system_category()); - else - ec = {}; - return nwritten; - } - if(bytesWritten == 0) - return nwritten; - n -= bytesWritten; - nwritten += bytesWritten; - buffer = static_cast(buffer) + bytesWritten; - } - ec = {}; - return nwritten; -} - -} // detail -} // http_proto -} // boost - -#endif diff --git a/src/file_sink.cpp b/src/file_sink.cpp index b6df9c2d..3f4bf723 100644 --- a/src/file_sink.cpp +++ b/src/file_sink.cpp @@ -14,7 +14,8 @@ namespace boost { namespace http_proto { file_sink:: -file_sink(file&& f) noexcept +file_sink( + capy::file&& f) noexcept : f_(std::move(f)) { } diff --git a/src/file_source.cpp b/src/file_source.cpp index 7cded95b..df9a11e1 100644 --- a/src/file_source.cpp +++ b/src/file_source.cpp @@ -21,7 +21,7 @@ file_source(file_source&&) noexcept = default; file_source:: file_source( - file&& f, + capy::file&& f, std::uint64_t limit) noexcept : f_(std::move(f)) , n_(limit) diff --git a/test/unit/detail/file_posix.cpp b/test/unit/detail/file_posix.cpp deleted file mode 100644 index 5b9791f8..00000000 --- a/test/unit/detail/file_posix.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -// Test that header file is self-contained. -#include - -#if BOOST_HTTP_PROTO_USE_POSIX_FILE - -#include "file_test.hpp" - -namespace boost { -namespace http_proto { -namespace detail { - -class file_posix_test -{ -public: - void - run() - { - test_file(); - } -}; - -TEST_SUITE( - file_posix_test, - "boost.http_proto.detail.file_posix"); - -} // detail -} // http_proto -} // boost - -#endif diff --git a/test/unit/detail/file_stdio.cpp b/test/unit/detail/file_stdio.cpp deleted file mode 100644 index 9e09d672..00000000 --- a/test/unit/detail/file_stdio.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -// Test that header file is self-contained. -#include - -#include "file_test.hpp" - -namespace boost { -namespace http_proto { -namespace detail { - -class file_stdio_test -{ -public: - void - run() - { -#ifdef _WIN32 - test_file(); -#else - test_file(); -#endif - } -}; - -TEST_SUITE( - file_stdio_test, - "boost.http_proto.detail.file_stdio"); - -} // detail -} // http_proto -} // boost diff --git a/test/unit/detail/file_win32.cpp b/test/unit/detail/file_win32.cpp deleted file mode 100644 index 7be66613..00000000 --- a/test/unit/detail/file_win32.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -// Test that header file is self-contained. -#include - -#if BOOST_HTTP_PROTO_USE_WIN32_FILE - -#include "file_test.hpp" - -namespace boost { -namespace http_proto { -namespace detail { - -class file_win32_test -{ -public: - void - run() - { - test_file(); - } -}; - -TEST_SUITE( - file_win32_test, - "boost.http_proto.detail.file_win32"); - -} // detail -} // http_proto -} // boost - -#endif // BOOST_HTTP_PROTO_USE_WIN32_FILE diff --git a/test/unit/file.cpp b/test/unit/file.cpp deleted file mode 100644 index 703c66fd..00000000 --- a/test/unit/file.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com) -// Copyright (c) 2025 Mohammad Nejati -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -// Test that header file is self-contained. -#include - -#include -#include "file_test.hpp" - -namespace boost { -namespace http_proto { - -struct file_test -{ - void - testThrowingOverloads() - { - // constructor - BOOST_TEST_THROWS( - file("missing.txt", file_mode::scan), - system::system_error); - - file f; - char buf[1]; - - BOOST_TEST_THROWS( - f.open("missing.txt", file_mode::scan), - system::system_error); - // BOOST_TEST_THROWS( - // f.close(), - // system::system_error); - BOOST_TEST_THROWS( - f.size(), - system::system_error); - BOOST_TEST_THROWS( - f.pos(), - system::system_error); - BOOST_TEST_THROWS( - f.seek(1), - system::system_error); - BOOST_TEST_THROWS( - f.read(buf, 1), - system::system_error); - BOOST_TEST_THROWS( - f.write(buf, 1), - system::system_error); - } - - void - run() - { - test_file(); - testThrowingOverloads(); - } -}; - -TEST_SUITE( - file_test, - "boost.http_proto.file"); - -} // http_proto -} // boost diff --git a/test/unit/file_mode.cpp b/test/unit/file_mode.cpp deleted file mode 100644 index 5ff75fa6..00000000 --- a/test/unit/file_mode.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -// Test that header file is self-contained. -#include diff --git a/test/unit/file_sink.cpp b/test/unit/file_sink.cpp index f900e9fa..e73da841 100644 --- a/test/unit/file_sink.cpp +++ b/test/unit/file_sink.cpp @@ -57,7 +57,7 @@ struct file_sink_test { // passing a closed file { - file f; + capy::file f; file_sink fsink(std::move(f)); buffers::const_buffer cb("123", 3); auto rs = fsink.write(cb, true); @@ -70,9 +70,9 @@ struct file_sink_test testWrite() { temp_path path; - file f; + capy::file f; system::error_code ec; - f.open(path, file_mode::write, ec); + f.open(path, capy::file_mode::write, ec); BOOST_TEST(!ec); BOOST_TEST(f.is_open()); file_sink fsink(std::move(f)); diff --git a/test/unit/file_source.cpp b/test/unit/file_source.cpp index aae19b10..1f52e272 100644 --- a/test/unit/file_source.cpp +++ b/test/unit/file_source.cpp @@ -58,7 +58,7 @@ struct file_source_test { // passing a closed file { - file f; + capy::file f; file_source fsource(std::move(f)); char buf[16] = {}; auto rs = fsource.read( @@ -74,9 +74,9 @@ struct file_source_test { temp_path path; write_file(path, "Hello, World!"); - file f; + capy::file f; system::error_code ec; - f.open(path, file_mode::read, ec); + f.open(path, capy::file_mode::read, ec); BOOST_TEST(!ec); BOOST_TEST(f.is_open()); file_source fsource(std::move(f)); @@ -101,9 +101,9 @@ struct file_source_test { temp_path path; write_file(path, "Hello, World!"); - file f; + capy::file f; system::error_code ec; - f.open(path, file_mode::read, ec); + f.open(path, capy::file_mode::read, ec); file_source fsource( std::move(f), 6); // Bounded to 6 bytes diff --git a/test/unit/file_test.hpp b/test/unit/file_test.hpp deleted file mode 100644 index b4abb646..00000000 --- a/test/unit/file_test.hpp +++ /dev/null @@ -1,469 +0,0 @@ -// -// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// Official repository: https://github.com/cppalliance/http_proto -// - -#ifndef BOOST_HTTP_PROTO_FILE_TEST_HPP -#define BOOST_HTTP_PROTO_FILE_TEST_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test_suite.hpp" - -#if defined(BOOST_GCC) && BOOST_GCC >= 130000 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wself-move" -#endif - -namespace boost { -namespace http_proto { - -template -void -test_file() -{ - BOOST_STATIC_ASSERT( - ! std::is_copy_constructible::value); - BOOST_STATIC_ASSERT( - ! std::is_copy_assignable::value); - - namespace fs = boost::filesystem; - -#ifdef _WIN32 - static - constexpr - boost::winapi::WCHAR_ - unicode_suffix[] = { - 0xd83e, 0xdd84, 0x0000 }; // UTF-16-LE unicorn -#else - static - constexpr - char - unicode_suffix[] = { - '\xf0', '\x9f', '\xa6', '\x84', '\x00' }; // UTF-8 unicorn -#endif - - class temp_path - { - fs::path path_; - std::vector utf8_str_; - - public: - temp_path() - : path_(fs::unique_path()) - { - if (append_unicode_suffix) - path_ += unicode_suffix; -#ifdef _WIN32 - constexpr auto cp = boost::winapi::CP_UTF8_; - constexpr auto flags = boost::winapi::WC_ERR_INVALID_CHARS_; - auto sz = boost::winapi::WideCharToMultiByte( - cp, flags, path_.c_str(), -1, nullptr, 0, - nullptr, nullptr); - BOOST_TEST(sz != 0); - utf8_str_.resize(sz); - auto ret = boost::winapi::WideCharToMultiByte( - cp, flags, path_.c_str(), -1, - utf8_str_.data(), sz, - nullptr, nullptr); - BOOST_TEST(ret == sz); -#endif - } - - operator fs::path const&() - { - return path_; - } - - operator char const*() - { -#ifdef _WIN32 - return utf8_str_.data(); -#else - return path_.c_str(); -#endif - } - }; - - auto const create = - [](fs::path const& path, std::string const& data = "") - { - BOOST_TEST(! fs::exists(path)); - std::ofstream out(path.c_str()); - BOOST_TEST(out.is_open()); - if (data.size()) - out.write(data.c_str(), data.size()); - }; - - auto const remove = - [](fs::path const& path) - { - fs::remove(path); - BOOST_TEST(! fs::exists(path)); - }; - - auto const consume_file = - [](fs::path const& path) - { - // no exceptions - failure will result in an empty string - std::ifstream in(path.c_str()); - noskipws(in); - auto s = std::string( - std::istream_iterator(in), - std::istream_iterator()); - in.close(); - return s; - }; - - temp_path path; - - // bad file descriptor - { - File f; - char buf[1]; - BOOST_TEST(! f.is_open()); - BOOST_TEST(! fs::exists(path)); - { - system::error_code ec; - f.size(ec); - BOOST_TEST(ec == - system::errc::bad_file_descriptor); - } - { - system::error_code ec; - f.pos(ec); - BOOST_TEST(ec == - system::errc::bad_file_descriptor); - } - { - system::error_code ec; - f.seek(0, ec); - BOOST_TEST(ec == - system::errc::bad_file_descriptor); - } - { - system::error_code ec; - f.read(buf, 0, ec); - BOOST_TEST(ec == - system::errc::bad_file_descriptor); - } - { - system::error_code ec; - f.write(buf, 0, ec); - BOOST_TEST(ec == - system::errc::bad_file_descriptor); - } - } - - // file_mode::read - { - { - File f; - system::error_code ec; - create(path); - f.open(path, file_mode::read, ec); - BOOST_TEST(! ec); - } - remove(path); - } - - // file_mode::scan - { - { - File f; - system::error_code ec; - create(path); - f.open(path, file_mode::scan, ec); - BOOST_TEST(! ec); - } - remove(path); - } - - // file_mode::write - { - { - File f; - system::error_code ec; - BOOST_TEST(! fs::exists(path)); - f.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - BOOST_TEST(fs::exists(path)); - } - { - File f; - system::error_code ec; - BOOST_TEST(fs::exists(path)); - f.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - BOOST_TEST(fs::exists(path)); - } - remove(path); - } - - // file_mode::write_new - { - { - File f; - system::error_code ec; - BOOST_TEST(! fs::exists(path)); - f.open(path, file_mode::write_new, ec); - BOOST_TEST(! ec); - BOOST_TEST(fs::exists(path)); - } - { - File f; - system::error_code ec; - BOOST_TEST(fs::exists(path)); - f.open(path, file_mode::write_new, ec); - BOOST_TEST(ec); - } - remove(path); - } - - // file_mode::write_existing - { - { - File f; - system::error_code ec; - BOOST_TEST(! fs::exists(path)); - f.open(path, file_mode::write_existing, ec); - BOOST_TEST(ec); - BOOST_TEST(! fs::exists(path)); - } - { - File f; - system::error_code ec; - create(path); - BOOST_TEST(fs::exists(path)); - f.open(path, file_mode::write_existing, ec); - BOOST_TEST(! ec); - } - remove(path); - } - - // file_mode::append - { - { - File f; - system::error_code ec; - BOOST_TEST(! fs::exists(path)); - f.open(path, file_mode::append, ec); - BOOST_TEST(! ec); - BOOST_TEST(fs::exists(path)); - static const std::string extra = "the"; - f.write(extra.c_str(), extra.size(), ec); - BOOST_TEST(!ec); - f.close(ec); - auto s = consume_file(path); - BOOST_TEST(s == "the"); - } - - { - File f; - system::error_code ec; - BOOST_TEST(fs::exists(path)); - f.open(path, file_mode::append, ec); - BOOST_TEST(! ec); - BOOST_TEST(fs::exists(path)); - static const std::string extra = " cat"; - f.write(extra.c_str(), extra.size(), ec); - BOOST_TEST(!ec); - f.close(ec); - auto s = consume_file(path); - BOOST_TEST_EQ(s, "the cat"); - } - remove(path); - } - - // file_mode::append_existing - { - { - File f; - system::error_code ec; - BOOST_TEST(! fs::exists(path)); - f.open(path, file_mode::append_existing, ec); - BOOST_TEST(ec); - BOOST_TEST(! fs::exists(path)); - } - remove(path); - { - File f; - system::error_code ec; - create(path, "the cat"); - f.open(path, file_mode::append_existing, ec); - BOOST_TEST(! ec); - static std::string const extra = " sat"; - f.write(extra.c_str(), extra.size(), ec); - BOOST_TEST(!ec); - f.close(ec); - BOOST_TEST(!ec); - auto s = consume_file(path); - BOOST_TEST_EQ(s, "the cat sat"); - } - remove(path); - } - - // special members - { - { - File f1; - system::error_code ec; - f1.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - BOOST_TEST(f1.is_open()); - - // move constructor - File f2(std::move(f1)); - BOOST_TEST(! f1.is_open()); - BOOST_TEST(f2.is_open()); - - // move assignment - File f3; - f3 = std::move(f2); - BOOST_TEST(! f2.is_open()); - BOOST_TEST(f3.is_open()); - } - remove(path); - } - - // re-open - { - { - File f; - system::error_code ec; - f.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - f.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - } - remove(path); - } - - // re-assign - { - temp_path path2; - { - system::error_code ec; - - File f1; - f1.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - - File f2; - f2.open(path2, file_mode::write, ec); - BOOST_TEST(! ec); - - f2 = std::move(f1); - BOOST_TEST(! f1.is_open()); - BOOST_TEST(f2.is_open()); - } - remove(path); - remove(path2); - } - - // self-move - { - { - File f; - system::error_code ec; - f.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - auto& f_(f); - f_ = std::move(f); - BOOST_TEST(f.is_open()); - } - remove(path); - } - - // native_handle - { - { - File f; - auto none = f.native_handle(); - system::error_code ec; - f.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - auto fd = f.native_handle(); - BOOST_TEST(fd != none); - f.native_handle(none); - BOOST_TEST(! f.is_open()); - } - remove(path); - } - - // read and write - { - core::string_view const s = - "Hello, world!"; - - // write - { - File f; - system::error_code ec; - f.open(path, file_mode::write, ec); - BOOST_TEST(! ec); - - f.write(s.data(), s.size(), ec); - BOOST_TEST(! ec); - - auto size = f.size(ec); - BOOST_TEST(! ec); - BOOST_TEST(size == s.size()); - - auto pos = f.pos(ec); - BOOST_TEST(! ec); - BOOST_TEST(pos == size); - - f.close(ec); - BOOST_TEST(! ec); - } - - // read - { - File f; - system::error_code ec; - f.open(path, file_mode::read, ec); - BOOST_TEST(! ec); - - std::string buf; - buf.resize(s.size()); - f.read(&buf[0], buf.size(), ec); - BOOST_TEST(! ec); - BOOST_TEST(buf == s); - - f.seek(1, ec); - BOOST_TEST(! ec); - buf.resize(3); - f.read(&buf[0], buf.size(), ec); - BOOST_TEST(! ec); - BOOST_TEST(buf == "ell"); - - auto pos = f.pos(ec); - BOOST_TEST(! ec); - BOOST_TEST(pos == 4); - } - remove(path); - } - - BOOST_TEST(! fs::exists(path)); -} - -} // http_proto -} // boost - -#endif