From 7f66dc70958a26be704672712c085d19ee6abc36 Mon Sep 17 00:00:00 2001 From: Oleg Ozimok Date: Mon, 13 Apr 2026 13:25:11 +0300 Subject: [PATCH] fix: implement MappedFile on POSIX (mmap) --- src/common/mapped_file.cpp | 85 +++++++++++++++++++++++++++++++++++++- src/common/mapped_file.h | 18 +++++--- 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/src/common/mapped_file.cpp b/src/common/mapped_file.cpp index 1c3b2ec..3173669 100644 --- a/src/common/mapped_file.cpp +++ b/src/common/mapped_file.cpp @@ -1,5 +1,7 @@ #include "mapped_file.h" + #ifdef _WIN32 + #include "utils.h" // For DBG #include @@ -47,4 +49,85 @@ std::span MappedFile::get_data() const { return { static_cast(m_pMappedData), m_file_size }; } -#endif // _WIN32 \ No newline at end of file +#else // !_WIN32 + +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include + +MappedFile::MappedFile(const std::string& path) { + m_fd = ::open(path.c_str(), O_RDONLY); + if (m_fd < 0) { + std::cerr << "Error: Could not open file " << path << ": " << std::strerror(errno) << std::endl; + return; + } + + struct stat st {}; + if (::fstat(m_fd, &st) != 0) { + std::cerr << "Error: Could not stat file: " << std::strerror(errno) << std::endl; + ::close(m_fd); + m_fd = -1; + return; + } + + if (!S_ISREG(st.st_mode)) { + std::cerr << "Error: Not a regular file." << std::endl; + ::close(m_fd); + m_fd = -1; + return; + } + + m_file_size = static_cast(st.st_size); + DBG("[IO] File size: ", m_file_size, " bytes"); + + if (m_file_size == 0) { + m_pMappedData = nullptr; + DBG("[IO] Empty file; no mmap"); + return; + } + + m_pMappedData = ::mmap(nullptr, m_file_size, PROT_READ, MAP_PRIVATE, m_fd, 0); + if (m_pMappedData == MAP_FAILED) { + std::cerr << "Error: Could not mmap file: " << std::strerror(errno) << std::endl; + m_pMappedData = nullptr; + ::close(m_fd); + m_fd = -1; + return; + } + + DBG("[IO] Mapped view @ ", m_pMappedData, " size=", m_file_size, " bytes"); +} + +MappedFile::~MappedFile() { + if (m_pMappedData && m_pMappedData != MAP_FAILED && m_file_size > 0) { + ::munmap(m_pMappedData, m_file_size); + } + if (m_fd >= 0) { + ::close(m_fd); + } +} + +bool MappedFile::is_valid() const { + if (m_fd < 0) { + return false; + } + if (m_file_size == 0) { + return true; + } + return m_pMappedData != nullptr && m_pMappedData != MAP_FAILED; +} + +std::span MappedFile::get_data() const { + if (!is_valid() || m_file_size == 0) { + return {}; + } + return { static_cast(m_pMappedData), m_file_size }; +} + +#endif // _WIN32 diff --git a/src/common/mapped_file.h b/src/common/mapped_file.h index 3b3f9ef..8d441a4 100644 --- a/src/common/mapped_file.h +++ b/src/common/mapped_file.h @@ -1,16 +1,18 @@ #pragma once -#ifdef _WIN32 -#include -#include + #include +#include +#include + +#ifdef _WIN32 #include +#endif class MappedFile { public: MappedFile(const std::string& path); ~MappedFile(); - // Disable copy/move for simplicity MappedFile(const MappedFile&) = delete; MappedFile& operator=(const MappedFile&) = delete; @@ -18,10 +20,14 @@ class MappedFile { std::span get_data() const; private: +#ifdef _WIN32 HANDLE m_hFile = INVALID_HANDLE_VALUE; HANDLE m_hMapping = NULL; LPCVOID m_pMappedData = NULL; size_t m_file_size = 0; +#else + int m_fd = -1; + void* m_pMappedData = nullptr; + size_t m_file_size = 0; +#endif }; - -#endif // _WIN32 \ No newline at end of file