3#include "../StringView.h"
5#include "../Logging/Logger.h"
17Cogs::FileHandle::~FileHandle() {
21Cogs::FileHandle::Ptr Cogs::FileHandle::open(std::string_view path, OpenMode openMode, AccessMode accessMode) {
22 Ptr handle = std::make_shared<FileHandle>();
28 if (openMode == OpenMode::OpenAlways) {
36 case OpenMode::Create: flags |= O_CREAT | O_EXCL;
break;
37 case OpenMode::CreateAlways: flags |= O_CREAT | O_TRUNC;
break;
38 case OpenMode::OpenAlways: flags |= O_CREAT;
break;
39 case OpenMode::Open:
break;
43 handle->fileDescriptor = ::open(std::string(path).c_str(), flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
45 if (handle->isOpen()) {
48 LOG_ERROR(logger,
"Failed to open %.*s. Error: %s.", StringViewFormat(path), strerror( errno ));
52void Cogs::FileHandle::close() {
54 ::close(fileDescriptor);
59bool Cogs::FileHandle::isOpen()
const {
60 return fileDescriptor != -1;
63size_t Cogs::FileHandle::getSize()
const {
66 int ret = ::fstat(fileDescriptor, &buf);
68 LOG_ERROR(logger,
"fstat error: %s.", strerror( errno ));
73 LOG_WARNING(logger,
"Tried to query size of closed file.");
77bool Cogs::FileHandle::write(
const void* ptr,
size_t size,
size_t& bytesWritten)
79 const uint8_t* src =
reinterpret_cast<const uint8_t*
>(ptr);
83 for (
constexpr size_t limit = 0x7ffff000; size > limit; ) {
84 ssize_t justWritten = ::write(fileDescriptor, src, limit);
86 if (justWritten >= 0) {
87 bytesWritten += justWritten;
92 LOG_ERROR(logger,
"Failed to write FileHandle %d. Error: %s.", fileDescriptor, strerror(errno));
97 ssize_t justWritten = ::write(fileDescriptor, src, size);
99 if (justWritten >= 0) {
100 bytesWritten += justWritten;
103 LOG_ERROR(logger,
"Failed to write FileHandle %d. Error: %s.", fileDescriptor, strerror(errno));
110bool Cogs::FileHandle::read(
void* buffer,
size_t size,
size_t& bytesRead)
112 uint8_t* dest =
reinterpret_cast<uint8_t*
>(buffer);
116 for (
constexpr size_t limit = 0x7ffff000; size > limit; ) {
117 ssize_t justRead = ::read(fileDescriptor, dest, limit);
122 bytesRead += justRead;
125 LOG_ERROR(logger,
"Failed to read FileHandle %d. Error: %s.", fileDescriptor, strerror(errno));
130 ssize_t justRead = ::read(fileDescriptor, dest, size);
133 bytesRead += justRead;
136 LOG_ERROR(logger,
"Failed to read FileHandle %d. Error: %s.", fileDescriptor, strerror(errno));
143void* Cogs::FileHandle::map(ProtectionMode ,
size_t offset,
size_t size) {
146 mappedMemory = ::mmap(
nullptr, size, PROT_READ, MAP_SHARED, fileDescriptor, offset);
153 LOG_ERROR(logger,
"Failed to map file into memory. Error: %s", strerror( errno ));
157 LOG_ERROR(logger,
"File handle cannot be mapped multiple times.");
161 LOG_ERROR(logger,
"Files must be opened before they can be memory mapped.");
166void Cogs::FileHandle::unmap() {
168 ::munmap(mappedMemory, mappedSize);
170 mappedMemory =
nullptr;
Log implementation class.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
@ Read
The buffer can be mapped and read from by the CPU after creation.