forked from Dushistov/sdcv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmapfile.hpp
93 lines (84 loc) · 2.07 KB
/
mapfile.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#pragma once
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_MMAP
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
#ifdef _WIN32
#include <windows.h>
#endif
#include <glib.h>
class MapFile
{
public:
MapFile() {}
~MapFile();
MapFile(const MapFile &) = delete;
MapFile &operator=(const MapFile &) = delete;
bool open(const char *file_name, off_t file_size);
gchar *begin() { return data; }
private:
char *data = nullptr;
#ifdef HAVE_MMAP
size_t size = 0u;
int mmap_fd = -1;
#elif defined(_WIN32)
HANDLE hFile = 0;
HANDLE hFileMap = 0;
#endif
};
inline bool MapFile::open(const char *file_name, off_t file_size)
{
#ifdef HAVE_MMAP
if ((mmap_fd = ::open(file_name, O_RDONLY)) < 0) {
// g_print("Open file %s failed!\n",fullfilename);
return false;
}
struct stat st;
if (fstat(mmap_fd, &st) == -1 || st.st_size < 0 || (st.st_size == 0 && S_ISREG(st.st_mode))
|| st.st_size != file_size) {
close(mmap_fd);
return false;
}
size = static_cast<size_t>(st.st_size);
data = (gchar *)mmap(nullptr, size, PROT_READ, MAP_SHARED, mmap_fd, 0);
if ((void *)data == (void *)(-1)) {
// g_print("mmap file %s failed!\n",idxfilename);
size = 0u;
data = nullptr;
return false;
}
#elif defined(_WIN32)
hFile = CreateFile(file_name, GENERIC_READ, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
hFileMap = CreateFileMapping(hFile, nullptr, PAGE_READONLY, 0, file_size, nullptr);
data = (gchar *)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, file_size);
#else
gsize read_len;
if (!g_file_get_contents(file_name, &data, &read_len, nullptr))
return false;
if (read_len != file_size)
return false;
#endif
return true;
}
inline MapFile::~MapFile()
{
if (!data)
return;
#ifdef HAVE_MMAP
munmap(data, size);
close(mmap_fd);
#else
#ifdef _WIN32
UnmapViewOfFile(data);
CloseHandle(hFileMap);
CloseHandle(hFile);
#else
g_free(data);
#endif
#endif
}