summaryrefslogtreecommitdiff
path: root/boost/beast/core/impl/file_win32.ipp
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:11:01 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:11:01 +0900
commit3fdc3e5ee96dca5b11d1694975a65200787eab86 (patch)
tree5c1733853892b8397d67706fa453a9bd978d2102 /boost/beast/core/impl/file_win32.ipp
parent88e602c57797660ebe0f9e15dbd64c1ff16dead3 (diff)
downloadboost-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.ipp364
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