/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2019 Danny Robson */ #include "file.hpp" #include "except.hpp" #include "../cast.hpp" using cruft::win32::file; /////////////////////////////////////////////////////////////////////////////// file::file () : m_handle (INVALID_HANDLE_VALUE) { ; } //----------------------------------------------------------------------------- file::file (std::filesystem::path const &src, DWORD access, DWORD share, DWORD create, DWORD flags) : m_handle ( error::try_call ( CreateFileW, src.c_str (), access, share, nullptr, // security create, flags, nullptr // template ) ) { ; } //----------------------------------------------------------------------------- file::file (file &&src) noexcept : m_handle (std::move (src.m_handle)) { ; } //----------------------------------------------------------------------------- file::file (handle &&src) noexcept : m_handle (std::move (src)) { ; } //----------------------------------------------------------------------------- file& file::operator= (file &&rhs) noexcept { std::swap (m_handle, rhs.m_handle); return *this; } //----------------------------------------------------------------------------- file::file (posix::fd &&src) : file (handle (std::move (src))) { ; } /////////////////////////////////////////////////////////////////////////////// DWORD file::read(void *buf, size_t available) { DWORD total_read; error::try_call (ReadFile, m_handle, buf, available, &total_read, nullptr); return total_read; } //----------------------------------------------------------------------------- DWORD file::write (void *buf, size_t available) { DWORD total_written; error::try_call (WriteFile, m_handle, buf, available, &total_written, nullptr); return total_written; } /////////////////////////////////////////////////////////////////////////////// DWORD file::read(void *buf, size_t available, OVERLAPPED &overlapped) { DWORD total_read; auto const res = ReadFile (m_handle, buf, available, &total_read, &overlapped); // If we're performing async IO then a value of FALSE is always returned. if (!overlapped.hEvent && res == FALSE) error::throw_code(); return total_read; } //----------------------------------------------------------------------------- DWORD file::write (void *buf, size_t available, OVERLAPPED &overlapped) { DWORD total_written; auto const res = WriteFile (m_handle, buf, available, &total_written, &overlapped); // If we're performing async IO then a value of FALSE is always returned. if (!overlapped.hEvent && res == FALSE) error::throw_code(); return total_written; } /////////////////////////////////////////////////////////////////////////////// u64 file::set_pointer(u64 request, DWORD method) { LONG const lo = request & 0xffffffff; LONG hi = request >> 32u; auto result = SetFilePointer (m_handle, lo, &hi, method); if (result == INVALID_SET_FILE_POINTER) error::throw_code(); u64 offset = cruft::cast::lossless (result) | cruft::cast::lossless (hi) << 32; return offset; }