ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
mappedfile.cpp
1//##################################################################################################
2// ALib C++ Framework
3//
4// Copyright 2013-2026 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software lbicense, see LICENSE.txt)
6//##################################################################################################
7namespace alib::system {
8
9std::errc MappedFile::Open( const CPathString& path, std::size_t knownSize,
10 bool disableMMap, bool willNeed) {
11 Close();
12 std::errc errc= std::errc();
13 errno = 0;
14
15 if (knownSize == (std::numeric_limits<std::size_t>::max)()) {
16 #if !defined(_WIN32)
17 struct stat st;
18 auto result= stat(path, &st);
19 #else
20 struct _stat64 st;
21 auto result= _wstat64(path, &st);
22 #endif
23 if(result) {
24 errc= (errno != 0) ? std::errc(errno) : std::errc::io_error;
25 return errc;
26 }
27 knownSize = size_t(st.st_size);
28 }
29
30 // Empty file is valid; keep backend as ReadAll with empty buffer.
31 if (knownSize == 0)
32 return errc;
33
34 #if defined(_POSIX_MAPPED_FILES) && _POSIX_MAPPED_FILES > 0
35 if (!disableMMap) {
36 int fd = ::open(path, O_RDONLY | O_CLOEXEC);
37 if (fd != -1) {
38 void* p = ::mmap(nullptr, knownSize, PROT_READ, MAP_PRIVATE, fd, 0);
39 ::close(fd);
40 errno = 0;
41 if (p != MAP_FAILED) {
42 mapAddr = p;
43 size = knownSize;
44
45 // Best-effort hint: sequential access.
46 // If madvise fails, we ignore it (still valid mapping).
47 if(willNeed)
48 ::madvise(mapAddr, size, MADV_WILLNEED);
49 else
50 ::madvise(mapAddr, size, MADV_SEQUENTIAL);
51
52
53 // mmap success
54 return errc;
55 }
56 } // ::open failed
57 } // try mmap
58 #else
59 (void) willNeed;
60 #endif
61
62 // fallback read mode
63 #if !defined(_WIN32)
64 (void) disableMMap;
65 // Portable std::ifstream read-all, size known.
66 errno = 0;
67 std::ifstream in(path, std::ios::binary);
68 if (!in.is_open()) {
69 errc= (errno != 0) ? std::errc(errno) : std::errc::io_error;
70 return errc;
71 }
72
73 noMMapBuf.resize(knownSize / sizeof(std::max_align_t) + 1);
74 in.read(reinterpret_cast<char*>(noMMapBuf.data()), static_cast<std::streamsize>(knownSize));
75 if (!in && !in.eof()) {
76 errc= (errno != 0) ? std::errc(errno) : std::errc::io_error;
77 return errc;
78 }
79
80 // If file shrank, adjust
81 auto got = static_cast<std::size_t>(in.gcount());
82 if (got != knownSize) noMMapBuf.resize(got/sizeof(std::max_align_t) + 1);
83 size= got;
84 return errc;
85 #else
86 // Windows-specific CreateFile/ReadFile is faster
87 (void) disableMMap;
88 (void) willNeed;
89 errno = 0;
90 HANDLE h = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, nullptr,
91 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr );
92 if (h == INVALID_HANDLE_VALUE) {
93 errc = std::errc::io_error;
94 return errc;
95 }
96
97 noMMapBuf.resize(knownSize/sizeof(std::max_align_t) + 1);
98
99 std::size_t totalRead = 0;
100 while (totalRead < knownSize) {
101 DWORD chunk = static_cast<DWORD>(
102 std::min<std::size_t>(knownSize - totalRead, static_cast<std::size_t>(0x7fffffff)) );
103
104 DWORD bytesRead = 0;
105 BOOL ok = ReadFile( h, noMMapBuf.data() + totalRead, chunk, &bytesRead, nullptr );
106 if (!ok) {
107 CloseHandle(h);
108 errc = std::errc::io_error;
109 return errc;
110 }
111 if (bytesRead == 0)
112 break; // EOF / file shrank
113 totalRead += static_cast<std::size_t>(bytesRead);
114 }
115 CloseHandle(h);
116 if (totalRead != knownSize)
117 noMMapBuf.resize(totalRead/sizeof(std::max_align_t) + 1);
118 size = totalRead;
119 return errc;
120 #endif
121}
122
123void MappedFile::Close() noexcept {
124 #if defined(_POSIX_MAPPED_FILES) && _POSIX_MAPPED_FILES > 0
125 if (IsMMap() && size) {
126 ::munmap(mapAddr, size);
127 mapAddr = nullptr;
128 }
129 #endif
130 noMMapBuf.resize(size= 0);
131}
132
133
134
135} // namespace [dxl]
void Close() noexcept
Release resources (unmap / free buffer).
bool IsMMap() const noexcept
std::size_t size
Size of the loaded data.
std::vector< std::max_align_t > noMMapBuf
Internal buffer used for fallback read mode.
std::errc Open(const CPathString &path, std::size_t knownSize=(std::numeric_limits< std::size_t >::max)(), bool disableMMap=false, bool willNeed=true)
Definition mappedfile.cpp:9
strings::TCString< PathCharType > CPathString
The string-type used with this ALib Module.
Definition path.hpp:37