diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:11:01 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:11:01 +0900 |
commit | 3fdc3e5ee96dca5b11d1694975a65200787eab86 (patch) | |
tree | 5c1733853892b8397d67706fa453a9bd978d2102 /boost/beast/core/impl/file_win32.ipp | |
parent | 88e602c57797660ebe0f9e15dbd64c1ff16dead3 (diff) | |
download | boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.gz boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.bz2 boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.zip |
Imported Upstream version 1.66.0upstream/1.66.0
Diffstat (limited to 'boost/beast/core/impl/file_win32.ipp')
-rw-r--r-- | boost/beast/core/impl/file_win32.ipp | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/boost/beast/core/impl/file_win32.ipp b/boost/beast/core/impl/file_win32.ipp new file mode 100644 index 0000000000..de4abae41f --- /dev/null +++ b/boost/beast/core/impl/file_win32.ipp @@ -0,0 +1,364 @@ +// +// Copyright (c) 2015-2016 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/boostorg/beast +// + +#ifndef BOOST_BEAST_CORE_IMPL_FILE_WIN32_IPP +#define BOOST_BEAST_CORE_IMPL_FILE_WIN32_IPP + +#include <boost/winapi/access_rights.hpp> +#include <boost/winapi/error_codes.hpp> +#include <boost/winapi/file_management.hpp> +#include <boost/winapi/get_last_error.hpp> +#include <limits> +#include <utility> + +namespace boost { +namespace beast { + +namespace detail { + +// VFALCO Can't seem to get boost/detail/winapi to work with +// this so use the non-Ex version for now. +inline +boost::winapi::BOOL_ +set_file_pointer_ex( + boost::winapi::HANDLE_ hFile, + boost::winapi::LARGE_INTEGER_ lpDistanceToMove, + boost::winapi::PLARGE_INTEGER_ lpNewFilePointer, + boost::winapi::DWORD_ dwMoveMethod) +{ + auto dwHighPart = lpDistanceToMove.u.HighPart; + auto dwLowPart = boost::winapi::SetFilePointer( + hFile, + lpDistanceToMove.u.LowPart, + &dwHighPart, + dwMoveMethod); + if(dwLowPart == boost::winapi::INVALID_SET_FILE_POINTER_) + return 0; + if(lpNewFilePointer) + { + lpNewFilePointer->u.LowPart = dwLowPart; + lpNewFilePointer->u.HighPart = dwHighPart; + } + return 1; +} + +} // detail + +inline +file_win32:: +~file_win32() +{ + if(h_ != boost::winapi::INVALID_HANDLE_VALUE_) + boost::winapi::CloseHandle(h_); +} + +inline +file_win32:: +file_win32(file_win32&& other) + : h_(other.h_) +{ + other.h_ = boost::winapi::INVALID_HANDLE_VALUE_; +} + +inline +file_win32& +file_win32:: +operator=(file_win32&& other) +{ + if(&other == this) + return *this; + if(h_) + boost::winapi::CloseHandle(h_); + h_ = other.h_; + other.h_ = boost::winapi::INVALID_HANDLE_VALUE_; + return *this; +} + +inline +void +file_win32:: +native_handle(native_handle_type h) +{ + if(h_ != boost::winapi::INVALID_HANDLE_VALUE_) + boost::winapi::CloseHandle(h_); + h_ = h; +} + +inline +void +file_win32:: +close(error_code& ec) +{ + if(h_ != boost::winapi::INVALID_HANDLE_VALUE_) + { + if(! boost::winapi::CloseHandle(h_)) + ec.assign(boost::winapi::GetLastError(), + system_category()); + else + ec.assign(0, ec.category()); + h_ = boost::winapi::INVALID_HANDLE_VALUE_; + } + else + { + ec.assign(0, ec.category()); + } +} + +inline +void +file_win32:: +open(char const* path, file_mode mode, error_code& ec) +{ + if(h_ != boost::winapi::INVALID_HANDLE_VALUE_) + { + boost::winapi::CloseHandle(h_); + h_ = boost::winapi::INVALID_HANDLE_VALUE_; + } + boost::winapi::DWORD_ share_mode = 0; + boost::winapi::DWORD_ desired_access = 0; + boost::winapi::DWORD_ creation_disposition = 0; + boost::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 = boost::winapi::GENERIC_READ_; + share_mode = boost::winapi::FILE_SHARE_READ_; + creation_disposition = boost::winapi::OPEN_EXISTING_; + flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS + break; + + case file_mode::scan: + desired_access = boost::winapi::GENERIC_READ_; + share_mode = boost::winapi::FILE_SHARE_READ_; + creation_disposition = boost::winapi::OPEN_EXISTING_; + flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN + break; + + case file_mode::write: + desired_access = boost::winapi::GENERIC_READ_ | + boost::winapi::GENERIC_WRITE_; + creation_disposition = boost::winapi::CREATE_ALWAYS_; + flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS + break; + + case file_mode::write_new: + desired_access = boost::winapi::GENERIC_READ_ | + boost::winapi::GENERIC_WRITE_; + creation_disposition = boost::winapi::CREATE_NEW_; + flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS + break; + + case file_mode::write_existing: + desired_access = boost::winapi::GENERIC_READ_ | + boost::winapi::GENERIC_WRITE_; + creation_disposition = boost::winapi::OPEN_EXISTING_; + flags_and_attributes = 0x10000000; // FILE_FLAG_RANDOM_ACCESS + break; + + case file_mode::append: + desired_access = boost::winapi::GENERIC_READ_ | + boost::winapi::GENERIC_WRITE_; + + creation_disposition = boost::winapi::CREATE_ALWAYS_; + flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN + break; + + case file_mode::append_new: + desired_access = boost::winapi::GENERIC_READ_ | + boost::winapi::GENERIC_WRITE_; + creation_disposition = boost::winapi::CREATE_NEW_; + flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN + break; + + case file_mode::append_existing: + desired_access = boost::winapi::GENERIC_READ_ | + boost::winapi::GENERIC_WRITE_; + creation_disposition = boost::winapi::OPEN_EXISTING_; + flags_and_attributes = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN + break; + } + h_ = ::CreateFileA( + path, + desired_access, + share_mode, + NULL, + creation_disposition, + flags_and_attributes, + NULL); + if(h_ == boost::winapi::INVALID_HANDLE_VALUE_) + ec.assign(boost::winapi::GetLastError(), + system_category()); + else + ec.assign(0, ec.category()); +} + +inline +std::uint64_t +file_win32:: +size(error_code& ec) const +{ + if(h_ == boost::winapi::INVALID_HANDLE_VALUE_) + { + ec.assign(errc::invalid_argument, generic_category()); + return 0; + } + boost::winapi::LARGE_INTEGER_ fileSize; + if(! boost::winapi::GetFileSizeEx(h_, &fileSize)) + { + ec.assign(boost::winapi::GetLastError(), + system_category()); + return 0; + } + ec.assign(0, ec.category()); + return fileSize.QuadPart; +} + +inline +std::uint64_t +file_win32:: +pos(error_code& ec) +{ + if(h_ == boost::winapi::INVALID_HANDLE_VALUE_) + { + ec.assign(errc::invalid_argument, generic_category()); + return 0; + } + boost::winapi::LARGE_INTEGER_ in; + boost::winapi::LARGE_INTEGER_ out; + in.QuadPart = 0; + if(! detail::set_file_pointer_ex(h_, in, &out, + boost::winapi::FILE_CURRENT_)) + { + ec.assign(boost::winapi::GetLastError(), + system_category()); + return 0; + } + ec.assign(0, ec.category()); + return out.QuadPart; +} + +inline +void +file_win32:: +seek(std::uint64_t offset, error_code& ec) +{ + if(h_ == boost::winapi::INVALID_HANDLE_VALUE_) + { + ec.assign(errc::invalid_argument, generic_category()); + return; + } + boost::winapi::LARGE_INTEGER_ in; + in.QuadPart = offset; + if(! detail::set_file_pointer_ex(h_, in, 0, + boost::winapi::FILE_BEGIN_)) + { + ec.assign(boost::winapi::GetLastError(), + system_category()); + return; + } + ec.assign(0, ec.category()); +} + +inline +std::size_t +file_win32:: +read(void* buffer, std::size_t n, error_code& ec) +{ + if(h_ == boost::winapi::INVALID_HANDLE_VALUE_) + { + ec.assign(errc::invalid_argument, generic_category()); + return 0; + } + std::size_t nread = 0; + while(n > 0) + { + boost::winapi::DWORD_ amount; + if(n > (std::numeric_limits< + boost::winapi::DWORD_>::max)()) + amount = (std::numeric_limits< + boost::winapi::DWORD_>::max)(); + else + amount = static_cast< + boost::winapi::DWORD_>(n); + boost::winapi::DWORD_ bytesRead; + if(! ::ReadFile(h_, buffer, amount, &bytesRead, 0)) + { + auto const dwError = ::GetLastError(); + if(dwError != boost::winapi::ERROR_HANDLE_EOF_) + ec.assign(::GetLastError(), system_category()); + else + ec.assign(0, ec.category()); + return nread; + } + if(bytesRead == 0) + return nread; + n -= bytesRead; + nread += bytesRead; + buffer = reinterpret_cast<char*>(buffer) + bytesRead; + } + ec.assign(0, ec.category()); + return nread; +} + +inline +std::size_t +file_win32:: +write(void const* buffer, std::size_t n, error_code& ec) +{ + if(h_ == boost::winapi::INVALID_HANDLE_VALUE_) + { + ec.assign(errc::invalid_argument, generic_category()); + return 0; + } + std::size_t nwritten = 0; + while(n > 0) + { + boost::winapi::DWORD_ amount; + if(n > (std::numeric_limits< + boost::winapi::DWORD_>::max)()) + amount = (std::numeric_limits< + boost::winapi::DWORD_>::max)(); + else + amount = static_cast< + boost::winapi::DWORD_>(n); + boost::winapi::DWORD_ bytesWritten; + if(! ::WriteFile(h_, buffer, amount, &bytesWritten, 0)) + { + auto const dwError = ::GetLastError(); + if(dwError != boost::winapi::ERROR_HANDLE_EOF_) + ec.assign(::GetLastError(), system_category()); + else + ec.assign(0, ec.category()); + return nwritten; + } + if(bytesWritten == 0) + return nwritten; + n -= bytesWritten; + nwritten += bytesWritten; + buffer = reinterpret_cast<char const*>(buffer) + bytesWritten; + } + ec.assign(0, ec.category()); + return nwritten; +} + +} // beast +} // boost + +#endif |