From dd5e60445ba0852d99c6da5d4dde698db9ad0742 Mon Sep 17 00:00:00 2001 From: dev0 Date: Wed, 26 Nov 2025 16:39:14 +0530 Subject: [PATCH] MMFile --- Src/IACore/inc/IACore/File.hpp | 142 +++++++++++++++++++++++++++++++++ Src/IACore/inc/IACore/PCH.hpp | 3 + 2 files changed, 145 insertions(+) diff --git a/Src/IACore/inc/IACore/File.hpp b/Src/IACore/inc/IACore/File.hpp index efca1b6..256759f 100644 --- a/Src/IACore/inc/IACore/File.hpp +++ b/Src/IACore/inc/IACore/File.hpp @@ -212,4 +212,146 @@ namespace IACore private: std::fstream m_fs; }; + + class MMFile + { + public: + MMFile() = default; + + // RAII - Automatically unmap on destruction + ~MMFile() + { + Close(); + } + + // Disable copy (managing ownership of raw handles is messy) + MMFile(const MMFile &) = delete; + MMFile &operator=(const MMFile &) = delete; + + // Open and Map + bool Map(const std::string &filepath) + { + Close(); // Cleanup any existing map + +#if IA_PLATFORM_WINDOWS > 0 + // 1. Open File + hFile_ = ::CreateFileA(filepath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile_ == INVALID_HANDLE_VALUE) + return false; + + // 2. Get File Size + LARGE_INTEGER size; + if (!::GetFileSizeEx(hFile_, &size)) + { + Close(); + return false; + } + size_ = static_cast(size.QuadPart); + + // 3. Create Mapping Object + hMapping_ = ::CreateFileMappingA(hFile_, nullptr, PAGE_READONLY, 0, 0, nullptr); + if (!hMapping_) + { + Close(); + return false; + } + + // 4. Map View + data_ = ::MapViewOfFile(hMapping_, FILE_MAP_READ, 0, 0, 0); + if (!data_) + { + Close(); + return false; + } + +#else // LINUX / POSIX + // 1. Open File + fd_ = ::open(filepath.c_str(), O_RDONLY); + if (fd_ == -1) + return false; + + // 2. Get File Size + struct stat sb; + if (fstat(fd_, &sb) == -1) + { + Close(); + return false; + } + size_ = static_cast(sb.st_size); + + // 3. mmap + // PROT_READ: Read only + // MAP_PRIVATE: Copy-on-write (safe if you accidentally modify, though we return const) + data_ = ::mmap(nullptr, size_, PROT_READ, MAP_PRIVATE, fd_, 0); + if (data_ == MAP_FAILED) + { + data_ = nullptr; + Close(); + return false; + } +#endif + return true; + } + + void Close() + { +#ifdef _WIN32 + if (data_) + { + ::UnmapViewOfFile(data_); + data_ = nullptr; + } + if (hMapping_) + { + ::CloseHandle(hMapping_); + hMapping_ = nullptr; + } + if (hFile_ != INVALID_HANDLE_VALUE) + { + ::CloseHandle(hFile_); + hFile_ = INVALID_HANDLE_VALUE; + } +#else + if (data_) + { + ::munmap(data_, size_); + data_ = nullptr; + } + if (fd_ != -1) + { + ::close(fd_); + fd_ = -1; + } +#endif + size_ = 0; + } + + // Accessors + const void *GetData() const + { + return data_; + } + + size_t GetSize() const + { + return size_; + } + + bool IsValid() const + { + return data_ != nullptr; + } + + private: + void *data_ = nullptr; + size_t size_ = 0; + +#ifdef _WIN32 + HANDLE hFile_ = INVALID_HANDLE_VALUE; + HANDLE hMapping_ = nullptr; +#else + int fd_ = -1; +#endif + }; } // namespace IACore \ No newline at end of file diff --git a/Src/IACore/inc/IACore/PCH.hpp b/Src/IACore/inc/IACore/PCH.hpp index efadcb9..9375ebd 100644 --- a/Src/IACore/inc/IACore/PCH.hpp +++ b/Src/IACore/inc/IACore/PCH.hpp @@ -495,6 +495,9 @@ STATIC CONST FLOAT64 FLOAT64_EPSILON = DBL_EPSILON; #elif IA_PLATFORM_UNIX # include # include +# include +# include +# include # include #endif