Doxygen XLinks
by
V: 2511R0
Website: doxygen
Loading...
Searching...
No Matches
mappedfile.cpp
1//==================================================================================================
2// This implementation-file is part of DoxygenXLinks - A doxygen post-processor that allows to
3// define smarter <b>Doxygen</b>-links.
4//
5// \emoji :copyright: 2025-2026 A-Worx GmbH, Germany.
6// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8
9
10#include "mappedfile.hpp"
11
12#if !defined(_WIN32)
13 #include <fcntl.h>
14 #include <sys/stat.h>
15 #if defined(_POSIX_MAPPED_FILES) && _POSIX_MAPPED_FILES > 0
16 #include <sys/mman.h>
17 #endif
18#endif
19
20namespace dxl {
21
22MappedFile::Data MappedFile::Open(const char* path, std::size_t knownSize, bool disableMMap) {
23 Close();
24
25 if (knownSize == std::numeric_limits<std::size_t>::max()) {
26 #if defined(_WIN32)
27 std::ifstream in(path, std::ios::binary | std::ios::ate);
28 if (!in) throw std::runtime_error("open failed for size detection");
29 knownSize = static_cast<std::size_t>(in.tellg());
30 #else
31 struct stat st;
32 if (stat(path, &st) != 0) throw std::runtime_error("stat failed for size detection");
33 knownSize = static_cast<std::size_t>(st.st_size);
34 #endif
35 }
36
37 // Empty file is valid; keep backend as ReadAll with empty buffer.
38 if (knownSize == 0)
39 return Data(static_cast<std::byte*>(mapAddr= nullptr), size= 0);
40
41 #if defined(_POSIX_MAPPED_FILES) && _POSIX_MAPPED_FILES > 0
42 if (!disableMMap) {
43 int fd = ::open(path, O_RDONLY | O_CLOEXEC);
44 if (fd != -1) {
45 void* p = ::mmap(nullptr, knownSize, PROT_READ, MAP_PRIVATE, fd, 0);
46 int saved_errno = errno;
47 ::close(fd);
48
49 if (p == MAP_FAILED) {
50 // mmap failed; silently fall back to ReadAll.
51 (void)saved_errno;
52 } else {
53 mapAddr = p;
54 size = knownSize;
55
56 // Best-effort hint: sequential access.
57 // If madvise fails, we ignore it (still valid mapping).
58
59 // ::madvise(mapAddr, size, MADV_SEQUENTIAL);
60 ::madvise(mapAddr, size, MADV_WILLNEED);
61
62 // mmap success
63 return Data(static_cast<std::byte*>(mapAddr), size);
64 }
65 } // ::open failed
66 } // try mmap
67 #endif
68
69 // fallback read mode
70 #if defined(_WIN32)
71 // Portable std::ifstream read-all, size known.
72 // (Windows-specific CreateFile/ReadFile would be faster, but this is fine and clean)
73 std::ifstream in(path, std::ios::binary);
74 if (!in) throw std::runtime_error("open failed");
75
76 buffer.resize(knownSize);
77 in.read(reinterpret_cast<char*>(buffer.data()), static_cast<std::streamsize>(knownSize));
78 if (!in && !in.eof()) throw std::runtime_error("read failed");
79
80 // If file shrank, adjust
81 auto got = static_cast<std::size_t>(in.gcount());
82 if (got != knownSize) buffer.resize(got);
83
84 data = buffer.data();
85 size = buffer.size();
86 backend_ = Backend::ReadAll;
87 #else
88 mapAddr = nullptr;
89 size = knownSize;
90 int fd = ::open(path, O_RDONLY | O_CLOEXEC);
91 if (fd < 0) throw std::runtime_error("open failed");
92
93 noMMapBuf.reserve(size);
94
95 std::size_t off = 0;
96 while (off < size) {
97 ssize_t r = ::read(fd, noMMapBuf.data() + off, size - off);
98 if (r < 0) {
99 ::close(fd);
100 throw std::runtime_error("read failed");
101 }
102 if (r == 0) break; // file shrank or EOF
103 off += static_cast<std::size_t>(r);
104 }
105 ::close(fd);
106 return Data(noMMapBuf.data(), size);
107 #endif
108}
109
110void MappedFile::Close() noexcept {
111 #if defined(_POSIX_MAPPED_FILES) && _POSIX_MAPPED_FILES > 0
112 if (IsMMap() && size) {
113 ::munmap(mapAddr, size);
114 mapAddr = nullptr;
115 }
116 #endif
117 noMMapBuf.resize(size= 0);
118}
119
120
121
122} // namespace [dxl]
std::size_t size
Size of the loaded data.
std::vector< std::byte > noMMapBuf
Internal buffer used for fallback read mode.
Data Open(const char *path, std::size_t knownSize=std::numeric_limits< std::size_t >::max(), bool disableMMap=false)
void Close() noexcept
Release resources (unmap / free buffer).
bool IsMMap() const noexcept
todox
Definition doxyfile.cpp:20