mpd/src/io/FileReader.cxx

119 lines
2.1 KiB
C++
Raw Normal View History

// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <max.kellermann@gmail.com>
2014-08-07 18:10:23 +02:00
#include "FileReader.hxx"
#include "lib/fmt/PathFormatter.hxx"
#include "fs/FileInfo.hxx"
2022-11-28 23:05:15 +01:00
#include "lib/fmt/SystemError.hxx"
2020-05-05 14:11:13 +02:00
#include "io/Open.hxx"
2014-08-07 18:10:23 +02:00
#include <cassert>
2016-08-16 07:58:44 +02:00
#ifdef _WIN32
2014-08-07 18:10:23 +02:00
FileReader::FileReader(Path _path)
2014-08-07 18:10:23 +02:00
:path(_path),
handle(CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
nullptr))
{
if (handle == INVALID_HANDLE_VALUE)
throw FmtLastError("Failed to open {}", path);
2014-08-07 18:10:23 +02:00
}
FileInfo
FileReader::GetFileInfo() const
{
assert(IsDefined());
return FileInfo{handle};
}
2021-12-08 19:39:50 +01:00
std::size_t
2023-10-05 10:25:16 +02:00
FileReader::Read(std::span<std::byte> dest)
2014-08-07 18:10:23 +02:00
{
assert(IsDefined());
DWORD nbytes;
2023-10-05 10:25:16 +02:00
if (!ReadFile(handle, dest.data(), dest.size(), &nbytes, nullptr))
throw FmtLastError("Failed to read from {}", path);
2014-08-07 18:10:23 +02:00
return nbytes;
}
void
FileReader::Seek(off_t offset)
2015-03-03 14:29:36 +01:00
{
assert(IsDefined());
auto result = SetFilePointer(handle, offset, nullptr, FILE_BEGIN);
if (result == INVALID_SET_FILE_POINTER)
throw MakeLastError("Failed to seek");
2015-03-03 14:29:36 +01:00
}
2016-02-19 18:18:25 +01:00
void
FileReader::Skip(off_t offset)
{
assert(IsDefined());
auto result = SetFilePointer(handle, offset, nullptr, FILE_CURRENT);
if (result == INVALID_SET_FILE_POINTER)
throw MakeLastError("Failed to seek");
}
2014-08-07 18:10:23 +02:00
#else
FileReader::FileReader(Path _path)
:path(_path), fd(OpenReadOnly(path.c_str()))
2014-08-07 18:10:23 +02:00
{
}
FileInfo
FileReader::GetFileInfo() const
{
assert(IsDefined());
FileInfo info;
const bool success = fstat(fd.Get(), &info.st) == 0;
if (!success)
throw FmtErrno("Failed to access {}", path);
return info;
}
2021-12-08 19:39:50 +01:00
std::size_t
2023-10-05 10:25:16 +02:00
FileReader::Read(std::span<std::byte> dest)
2014-08-07 18:10:23 +02:00
{
assert(IsDefined());
2023-10-05 10:25:16 +02:00
ssize_t nbytes = fd.Read(dest);
if (nbytes < 0)
throw FmtErrno("Failed to read from {}", path);
2014-08-07 18:10:23 +02:00
return nbytes;
}
void
FileReader::Seek(off_t offset)
2015-03-03 14:29:36 +01:00
{
assert(IsDefined());
auto result = fd.Seek(offset);
2015-03-03 14:29:36 +01:00
const bool success = result >= 0;
if (!success)
throw MakeErrno("Failed to seek");
2015-03-03 14:29:36 +01:00
}
2016-02-19 18:18:25 +01:00
void
FileReader::Skip(off_t offset)
{
assert(IsDefined());
auto result = fd.Skip(offset);
const bool success = result >= 0;
if (!success)
throw MakeErrno("Failed to seek");
}
2014-08-07 18:10:23 +02:00
#endif