diff options
author | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2014-06-03 18:07:13 +0200 |
---|---|---|
committer | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2014-06-03 18:07:13 +0200 |
commit | 5044feb835653ba98ee48cf243fe5d3ab184fa3c (patch) | |
tree | 42e2f214506c88a7be98bd016174effc2479610f /src | |
parent | 0243f128ddc7ee44db1a8b95f76eb726122ee1d5 (diff) |
Implementing MMap for Linux, and fixing a few details.
Diffstat (limited to 'src')
-rw-r--r-- | src/MMap.cc | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/src/MMap.cc b/src/MMap.cc index 18187b4..a984f00 100644 --- a/src/MMap.cc +++ b/src/MMap.cc @@ -2,6 +2,12 @@ #ifdef _WIN32 #include <windows.h> +#else +#include <sys/types.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> #endif namespace Balau { @@ -28,7 +34,7 @@ class MMapPlatform { if (m_handle == INVALID_HANDLE_VALUE) return std::tie(result, m_ptr, s); - ScopedLambda hc([&]() { if (!result) CloseHandle(m_handle); }); + ScopedLambda hc([&]() { if (!result) CloseHandle(m_handle); m_handle = INVALID_HANDLE_VALUE; }); LARGE_INTEGER fsize; if (!GetFileSizeEx(m_handle, (PLARGE_INTEGER) &fsize)) @@ -42,7 +48,7 @@ class MMapPlatform { return std::tie(result, m_ptr, s); // than getting the usual INVALID_HANDLE_VALUE (which is -1), // in order to make a sane and uniform API... { - ScopedLambda mc([&]() { if (!result) CloseHandle(m_mapObject); }); + ScopedLambda mc([&]() { if (!result) CloseHandle(m_mapObject); m_mapObject = (HANDLE) NULL; }); // and of course, CreateFileMapping takes the 64 bits size in high / low format, // whereas MapViewOfFile takes the 64 bits size in a single 64 bits size_t. Sure. Makes sense. @@ -69,17 +75,56 @@ class MMapPlatform { const uint8_t * m_ptr = NULL; }; +#else + +class MMapPlatform { + public: + std::tuple<bool, const uint8_t *, size_t> open(const String & fname) { + bool result = false; + m_size = 0; + m_fd = ::open(fname.to_charp(), O_RDONLY); + + if (m_fd < 0) + return std::tie(result, m_ptr, m_size); + + ScopedLambda hc([&]() { if (!result) ::close(m_fd); m_fd = -1; }); + + m_size = lseek(m_fd, 0, SEEK_END); + lseek(m_fd, 0, SEEK_SET); + + if (m_size < 0) + return std::tie(result, m_ptr, m_size); + + m_ptr = (uint8_t *) mmap(NULL, m_size, PROT_READ, MAP_PRIVATE, m_fd, 0); + + result = !!m_ptr; + + return std::tie(result, m_ptr, m_size); + } + void close() { + if (m_ptr) + munmap(m_ptr, m_size); + if (m_fd >= 0) + ::close(m_fd); + m_ptr = NULL; + m_fd = -1; + } + int m_fd = -1; + uint8_t * m_ptr = NULL; + ssize_t m_size; +}; + #endif }; Balau::MMap::MMap(const char * fname) { m_fname = fname; - m_name.set("mmap of %s", m_fname); + m_name.set("mmap of %s", m_fname.to_charp()); m_platform = new MMapPlatform(); } -void Balau::MMap::open() { +void Balau::MMap::open() throw (GeneralException) { bool result; const uint8_t * ptr; size_t s; @@ -90,11 +135,12 @@ void Balau::MMap::open() { borrow(ptr, s); } -void Balau::MMap::close() { +void Balau::MMap::close() throw (GeneralException) { m_platform->close(); Buffer::close(); } Balau::MMap::~MMap() { + m_platform->close(); delete m_platform; } |