mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 13:27:33 +02:00
Add file_win32
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
Version 74:
|
Version 74:
|
||||||
|
|
||||||
* Add file_stdio and File concept
|
* Add file_stdio and File concept
|
||||||
|
* Add file_win32
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -180,6 +180,7 @@
|
|||||||
<bridgehead renderas="sect3"> </bridgehead>
|
<bridgehead renderas="sect3"> </bridgehead>
|
||||||
<simplelist type="vert" columns="1">
|
<simplelist type="vert" columns="1">
|
||||||
<member><link linkend="beast.ref.beast__file_stdio">file_stdio</link></member>
|
<member><link linkend="beast.ref.beast__file_stdio">file_stdio</link></member>
|
||||||
|
<member><link linkend="beast.ref.beast__file_win32">file_win32</link></member>
|
||||||
<member><link linkend="beast.ref.beast__flat_buffer">flat_buffer</link></member>
|
<member><link linkend="beast.ref.beast__flat_buffer">flat_buffer</link></member>
|
||||||
<member><link linkend="beast.ref.beast__handler_alloc">handler_alloc</link></member>
|
<member><link linkend="beast.ref.beast__handler_alloc">handler_alloc</link></member>
|
||||||
<member><link linkend="beast.ref.beast__handler_ptr">handler_ptr</link></member>
|
<member><link linkend="beast.ref.beast__handler_ptr">handler_ptr</link></member>
|
||||||
|
@ -285,7 +285,7 @@ INCLUDE_FILE_PATTERNS =
|
|||||||
|
|
||||||
PREDEFINED = \
|
PREDEFINED = \
|
||||||
BEAST_DOXYGEN \
|
BEAST_DOXYGEN \
|
||||||
BEAST_INITFN_RESULT_TYPE(t,a)=void_or_deduced
|
BEAST_USE_WIN32_FILE=1
|
||||||
|
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
SKIP_FUNCTION_MACROS = YES
|
SKIP_FUNCTION_MACROS = YES
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <beast/core/file_base.hpp>
|
#include <beast/core/file_base.hpp>
|
||||||
#include <beast/core/file_stdio.hpp>
|
#include <beast/core/file_stdio.hpp>
|
||||||
|
#include <beast/core/file_win32.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
@ -18,8 +20,14 @@ namespace beast {
|
|||||||
This alias is set to the best available implementation
|
This alias is set to the best available implementation
|
||||||
of @b File given the platform and build settings.
|
of @b File given the platform and build settings.
|
||||||
*/
|
*/
|
||||||
|
#if defined(BOOST_MSVC) && BEAST_USE_WIN32_FILE
|
||||||
|
using file = file_win32;
|
||||||
|
|
||||||
|
#else
|
||||||
using file = file_stdio;
|
using file = file_stdio;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // beast
|
} // beast
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
173
include/beast/core/file_win32.hpp
Normal file
173
include/beast/core/file_win32.hpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BEAST_CORE_FILE_WIN32_HPP
|
||||||
|
#define BEAST_CORE_FILE_WIN32_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if ! defined(BEAST_USE_WIN32_FILE)
|
||||||
|
# ifdef BOOST_MSVC
|
||||||
|
# define BEAST_USE_WIN32_FILE 1
|
||||||
|
# else
|
||||||
|
# define BEAST_USE_WIN32_FILE 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_USE_WIN32_FILE
|
||||||
|
|
||||||
|
#include <beast/core/error.hpp>
|
||||||
|
#include <beast/core/file_base.hpp>
|
||||||
|
#include <boost/detail/winapi/basic_types.hpp>
|
||||||
|
#include <boost/detail/winapi/handles.hpp>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
|
||||||
|
/** An implementation of File for Win32.
|
||||||
|
|
||||||
|
This class implements a @b File using Win32 native interfaces.
|
||||||
|
*/
|
||||||
|
class file_win32
|
||||||
|
{
|
||||||
|
boost::detail::winapi::HANDLE_ h_ =
|
||||||
|
boost::detail::winapi::INVALID_HANDLE_VALUE_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** The type of the underlying file handle.
|
||||||
|
|
||||||
|
This is platform-specific.
|
||||||
|
*/
|
||||||
|
#if BEAST_DOXYGEN
|
||||||
|
using native_handle_type = HANDLE;
|
||||||
|
#else
|
||||||
|
using native_handle_type = boost::detail::winapi::HANDLE_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Destructor
|
||||||
|
|
||||||
|
If the file is open it is first closed.
|
||||||
|
*/
|
||||||
|
~file_win32();
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
|
||||||
|
There is no open file initially.
|
||||||
|
*/
|
||||||
|
file_win32() = default;
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
|
||||||
|
The moved-from object behaves as if default constructed.
|
||||||
|
*/
|
||||||
|
file_win32(file_win32&& other);
|
||||||
|
|
||||||
|
/** Assignment
|
||||||
|
|
||||||
|
The moved-from object behaves as if default constructed.
|
||||||
|
*/
|
||||||
|
file_win32& operator=(file_win32&& other);
|
||||||
|
|
||||||
|
/// Returns the native handle associated with the file.
|
||||||
|
native_handle_type
|
||||||
|
native_handle() const
|
||||||
|
{
|
||||||
|
return h_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the native handle associated with the file.
|
||||||
|
|
||||||
|
If the file is open it is first closed.
|
||||||
|
|
||||||
|
@param h The native file handle to assign.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
native_handle(native_handle_type h);
|
||||||
|
|
||||||
|
/// Returns `true` if the file is open
|
||||||
|
bool
|
||||||
|
is_open() const
|
||||||
|
{
|
||||||
|
return h_ != boost::detail::winapi::INVALID_HANDLE_VALUE_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Close the file if open
|
||||||
|
|
||||||
|
@param ec Set to the error, if any occurred.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
close(error_code& 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
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
open(char const* path, file_mode mode, error_code& ec);
|
||||||
|
|
||||||
|
/** Return the size of the open file
|
||||||
|
|
||||||
|
@param ec Set to the error, if any occurred
|
||||||
|
|
||||||
|
@return The size in bytes
|
||||||
|
*/
|
||||||
|
std::uint64_t
|
||||||
|
size(error_code& ec) const;
|
||||||
|
|
||||||
|
/** Return the current position in the open file
|
||||||
|
|
||||||
|
@param ec Set to the error, if any occurred
|
||||||
|
|
||||||
|
@return The offset in bytes from the beginning of the file
|
||||||
|
*/
|
||||||
|
std::uint64_t
|
||||||
|
pos(error_code& ec) const;
|
||||||
|
|
||||||
|
/** Adjust the current position in the open file
|
||||||
|
|
||||||
|
@param offset The offset in bytes from the beginning of the file
|
||||||
|
|
||||||
|
@param ec Set to the error, if any occurred
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
seek(std::uint64_t offset, error_code& ec);
|
||||||
|
|
||||||
|
/** Read from the open file
|
||||||
|
|
||||||
|
@param buffer The buffer for storing the result of the read
|
||||||
|
|
||||||
|
@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, error_code& ec) const;
|
||||||
|
|
||||||
|
/** Write to the open file
|
||||||
|
|
||||||
|
@param buffer The buffer holding 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, error_code& ec);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // beast
|
||||||
|
|
||||||
|
#include <beast/core/impl/file_win32.ipp>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
356
include/beast/core/impl/file_win32.ipp
Normal file
356
include/beast/core/impl/file_win32.ipp
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BEAST_CORE_IMPL_FILE_WIN32_IPP
|
||||||
|
#define BEAST_CORE_IMPL_FILE_WIN32_IPP
|
||||||
|
|
||||||
|
#include <boost/detail/winapi/access_rights.hpp>
|
||||||
|
#include <boost/detail/winapi/error_codes.hpp>
|
||||||
|
#include <boost/detail/winapi/file_management.hpp>
|
||||||
|
#include <boost/detail/winapi/get_last_error.hpp>
|
||||||
|
#include <limits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
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::detail::winapi::BOOL_
|
||||||
|
set_file_pointer_ex(
|
||||||
|
boost::detail::winapi::HANDLE_ hFile,
|
||||||
|
boost::detail::winapi::LARGE_INTEGER_ lpDistanceToMove,
|
||||||
|
boost::detail::winapi::PLARGE_INTEGER_ lpNewFilePointer,
|
||||||
|
boost::detail::winapi::DWORD_ dwMoveMethod)
|
||||||
|
{
|
||||||
|
auto dwHighPart = lpDistanceToMove.u.HighPart;
|
||||||
|
auto dwLowPart = boost::detail::winapi::SetFilePointer(
|
||||||
|
hFile,
|
||||||
|
lpDistanceToMove.u.LowPart,
|
||||||
|
&dwHighPart,
|
||||||
|
dwMoveMethod);
|
||||||
|
if(dwLowPart == boost::detail::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::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
boost::detail::winapi::CloseHandle(h_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
file_win32::
|
||||||
|
file_win32(file_win32&& other)
|
||||||
|
: h_(other.h_)
|
||||||
|
{
|
||||||
|
other.h_ = boost::detail::winapi::INVALID_HANDLE_VALUE_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
file_win32&
|
||||||
|
file_win32::
|
||||||
|
operator=(file_win32&& other)
|
||||||
|
{
|
||||||
|
if(&other == this)
|
||||||
|
return *this;
|
||||||
|
if(h_)
|
||||||
|
boost::detail::winapi::CloseHandle(h_);
|
||||||
|
h_ = other.h_;
|
||||||
|
other.h_ = boost::detail::winapi::INVALID_HANDLE_VALUE_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
file_win32::
|
||||||
|
native_handle(native_handle_type h)
|
||||||
|
{
|
||||||
|
if(h_ != boost::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
boost::detail::winapi::CloseHandle(h_);
|
||||||
|
h_ = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
file_win32::
|
||||||
|
close(error_code& ec)
|
||||||
|
{
|
||||||
|
if(h_ != boost::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
{
|
||||||
|
if(! boost::detail::winapi::CloseHandle(h_))
|
||||||
|
ec.assign(boost::detail::winapi::GetLastError(),
|
||||||
|
system_category());
|
||||||
|
else
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
h_ = boost::detail::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::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
{
|
||||||
|
boost::detail::winapi::CloseHandle(h_);
|
||||||
|
h_ = boost::detail::winapi::INVALID_HANDLE_VALUE_;
|
||||||
|
}
|
||||||
|
boost::detail::winapi::DWORD_ dw1 = 0;
|
||||||
|
boost::detail::winapi::DWORD_ dw2 = 0;
|
||||||
|
boost::detail::winapi::DWORD_ dw3 = 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:
|
||||||
|
dw1 = boost::detail::winapi::GENERIC_READ_;
|
||||||
|
dw2 = boost::detail::winapi::OPEN_EXISTING_;
|
||||||
|
dw3 = 0x10000000; // FILE_FLAG_RANDOM_ACCESS
|
||||||
|
break;
|
||||||
|
|
||||||
|
case file_mode::scan:
|
||||||
|
dw1 = boost::detail::winapi::GENERIC_READ_;
|
||||||
|
dw2 = boost::detail::winapi::OPEN_EXISTING_;
|
||||||
|
dw3 = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN
|
||||||
|
break;
|
||||||
|
|
||||||
|
case file_mode::write:
|
||||||
|
dw1 = boost::detail::winapi::GENERIC_READ_ |
|
||||||
|
boost::detail::winapi::GENERIC_WRITE_;
|
||||||
|
dw2 = boost::detail::winapi::CREATE_ALWAYS_;
|
||||||
|
dw3 = 0x10000000; // FILE_FLAG_RANDOM_ACCESS
|
||||||
|
break;
|
||||||
|
|
||||||
|
case file_mode::write_new:
|
||||||
|
dw1 = boost::detail::winapi::GENERIC_READ_ |
|
||||||
|
boost::detail::winapi::GENERIC_WRITE_;
|
||||||
|
dw2 = boost::detail::winapi::CREATE_NEW_;
|
||||||
|
dw3 = 0x10000000; // FILE_FLAG_RANDOM_ACCESS
|
||||||
|
break;
|
||||||
|
|
||||||
|
case file_mode::write_existing:
|
||||||
|
dw1 = boost::detail::winapi::GENERIC_READ_ |
|
||||||
|
boost::detail::winapi::GENERIC_WRITE_;
|
||||||
|
dw2 = boost::detail::winapi::OPEN_EXISTING_;
|
||||||
|
dw3 = 0x10000000; // FILE_FLAG_RANDOM_ACCESS
|
||||||
|
break;
|
||||||
|
|
||||||
|
case file_mode::append:
|
||||||
|
dw1 = boost::detail::winapi::GENERIC_READ_ |
|
||||||
|
boost::detail::winapi::GENERIC_WRITE_;
|
||||||
|
dw2 = boost::detail::winapi::CREATE_ALWAYS_;
|
||||||
|
dw3 = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN
|
||||||
|
break;
|
||||||
|
|
||||||
|
case file_mode::append_new:
|
||||||
|
dw1 = boost::detail::winapi::GENERIC_READ_ |
|
||||||
|
boost::detail::winapi::GENERIC_WRITE_;
|
||||||
|
dw2 = boost::detail::winapi::CREATE_NEW_;
|
||||||
|
dw3 = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN
|
||||||
|
break;
|
||||||
|
|
||||||
|
case file_mode::append_existing:
|
||||||
|
dw1 = boost::detail::winapi::GENERIC_READ_ |
|
||||||
|
boost::detail::winapi::GENERIC_WRITE_;
|
||||||
|
dw2 = boost::detail::winapi::OPEN_EXISTING_;
|
||||||
|
dw3 = 0x08000000; // FILE_FLAG_SEQUENTIAL_SCAN
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
h_ = ::CreateFileA(
|
||||||
|
path,
|
||||||
|
dw1,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
dw2,
|
||||||
|
dw3,
|
||||||
|
NULL);
|
||||||
|
if(h_ == boost::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
ec.assign(boost::detail::winapi::GetLastError(),
|
||||||
|
system_category());
|
||||||
|
else
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::uint64_t
|
||||||
|
file_win32::
|
||||||
|
size(error_code& ec) const
|
||||||
|
{
|
||||||
|
if(h_ == boost::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
{
|
||||||
|
ec.assign(errc::invalid_argument, generic_category());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
boost::detail::winapi::LARGE_INTEGER_ fileSize;
|
||||||
|
if(! boost::detail::winapi::GetFileSizeEx(h_, &fileSize))
|
||||||
|
{
|
||||||
|
ec.assign(boost::detail::winapi::GetLastError(),
|
||||||
|
system_category());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
return fileSize.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::uint64_t
|
||||||
|
file_win32::
|
||||||
|
pos(error_code& ec) const
|
||||||
|
{
|
||||||
|
if(h_ == boost::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
{
|
||||||
|
ec.assign(errc::invalid_argument, generic_category());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
boost::detail::winapi::LARGE_INTEGER_ in;
|
||||||
|
boost::detail::winapi::LARGE_INTEGER_ out;
|
||||||
|
in.QuadPart = 0;
|
||||||
|
if(! detail::set_file_pointer_ex(h_, in, &out,
|
||||||
|
boost::detail::winapi::FILE_CURRENT_))
|
||||||
|
{
|
||||||
|
ec.assign(boost::detail::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::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
{
|
||||||
|
ec.assign(errc::invalid_argument, generic_category());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boost::detail::winapi::LARGE_INTEGER_ in;
|
||||||
|
in.QuadPart = offset;
|
||||||
|
if(! detail::set_file_pointer_ex(h_, in, 0,
|
||||||
|
boost::detail::winapi::FILE_BEGIN_))
|
||||||
|
{
|
||||||
|
ec.assign(boost::detail::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) const
|
||||||
|
{
|
||||||
|
if(h_ == boost::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
{
|
||||||
|
ec.assign(errc::invalid_argument, generic_category());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::size_t nread = 0;
|
||||||
|
while(n > 0)
|
||||||
|
{
|
||||||
|
boost::detail::winapi::DWORD_ amount;
|
||||||
|
if(n > (std::numeric_limits<
|
||||||
|
boost::detail::winapi::DWORD_>::max)())
|
||||||
|
amount = (std::numeric_limits<
|
||||||
|
boost::detail::winapi::DWORD_>::max)();
|
||||||
|
else
|
||||||
|
amount = static_cast<
|
||||||
|
boost::detail::winapi::DWORD_>(n);
|
||||||
|
boost::detail::winapi::DWORD_ bytesRead;
|
||||||
|
if(! ::ReadFile(h_, buffer, amount, &bytesRead, 0))
|
||||||
|
{
|
||||||
|
auto const dwError = ::GetLastError();
|
||||||
|
if(dwError != boost::detail::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::detail::winapi::INVALID_HANDLE_VALUE_)
|
||||||
|
{
|
||||||
|
ec.assign(errc::invalid_argument, generic_category());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::size_t nwritten = 0;
|
||||||
|
while(n > 0)
|
||||||
|
{
|
||||||
|
boost::detail::winapi::DWORD_ amount;
|
||||||
|
if(n > (std::numeric_limits<
|
||||||
|
boost::detail::winapi::DWORD_>::max)())
|
||||||
|
amount = (std::numeric_limits<
|
||||||
|
boost::detail::winapi::DWORD_>::max)();
|
||||||
|
else
|
||||||
|
amount = static_cast<
|
||||||
|
boost::detail::winapi::DWORD_>(n);
|
||||||
|
boost::detail::winapi::DWORD_ bytesWritten;
|
||||||
|
if(! ::WriteFile(h_, buffer, amount, &bytesWritten, 0))
|
||||||
|
{
|
||||||
|
auto const dwError = ::GetLastError();
|
||||||
|
if(dwError != boost::detail::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
|
||||||
|
|
||||||
|
#endif
|
@ -11,11 +11,12 @@ add_executable (core-tests
|
|||||||
${EXAMPLE_INCLUDES}
|
${EXAMPLE_INCLUDES}
|
||||||
${EXTRAS_INCLUDES}
|
${EXTRAS_INCLUDES}
|
||||||
../../extras/beast/unit_test/main.cpp
|
../../extras/beast/unit_test/main.cpp
|
||||||
|
buffer_test.hpp
|
||||||
|
file_test.hpp
|
||||||
async_result.cpp
|
async_result.cpp
|
||||||
bind_handler.cpp
|
bind_handler.cpp
|
||||||
buffer_cat.cpp
|
buffer_cat.cpp
|
||||||
buffer_prefix.cpp
|
buffer_prefix.cpp
|
||||||
buffer_test.hpp
|
|
||||||
buffered_read_stream.cpp
|
buffered_read_stream.cpp
|
||||||
buffers_adapter.cpp
|
buffers_adapter.cpp
|
||||||
clamp.cpp
|
clamp.cpp
|
||||||
@ -26,7 +27,7 @@ add_executable (core-tests
|
|||||||
error.cpp
|
error.cpp
|
||||||
file.cpp
|
file.cpp
|
||||||
file_stdio.cpp
|
file_stdio.cpp
|
||||||
file_test.hpp
|
file_win32.cpp
|
||||||
flat_buffer.cpp
|
flat_buffer.cpp
|
||||||
handler_alloc.cpp
|
handler_alloc.cpp
|
||||||
handler_ptr.cpp
|
handler_ptr.cpp
|
||||||
|
@ -21,6 +21,7 @@ unit-test core-tests :
|
|||||||
error.cpp
|
error.cpp
|
||||||
file.cpp
|
file.cpp
|
||||||
file_stdio.cpp
|
file_stdio.cpp
|
||||||
|
file_win32.cpp
|
||||||
flat_buffer.cpp
|
flat_buffer.cpp
|
||||||
handler_alloc.cpp
|
handler_alloc.cpp
|
||||||
handler_ptr.cpp
|
handler_ptr.cpp
|
||||||
|
35
test/core/file_win32.cpp
Normal file
35
test/core/file_win32.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2013-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)
|
||||||
|
//
|
||||||
|
|
||||||
|
// Test that header file is self-contained.
|
||||||
|
#include <beast/core/file_win32.hpp>
|
||||||
|
|
||||||
|
#if BEAST_USE_WIN32_FILE
|
||||||
|
|
||||||
|
#include "file_test.hpp"
|
||||||
|
|
||||||
|
#include <beast/core/type_traits.hpp>
|
||||||
|
#include <beast/unit_test/suite.hpp>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
|
||||||
|
class file_win32_test
|
||||||
|
: public beast::unit_test::suite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
run()
|
||||||
|
{
|
||||||
|
doTestFile<file_win32>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEAST_DEFINE_TESTSUITE(file_win32,core,beast);
|
||||||
|
|
||||||
|
} // beast
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user