-
Notifications
You must be signed in to change notification settings - Fork 3
/
file_helpers.hpp
97 lines (78 loc) · 2.31 KB
/
file_helpers.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
94
95
96
#pragma once
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
// A RAII class that encapsulates a unix file descriptor
class unixFile {
public:
unixFile (const char *fileName)
{
fd = ::open ( fileName, O_RDONLY );
if ( fd < 0 )
throw std::runtime_error("can't open");
}
unixFile(const unixFile &) = delete;
unixFile & operator=(const unixFile&) = delete;
unixFile(unixFile &&rhs) : fd(rhs.release ()) {}
unixFile & operator=(unixFile &&rhs) { fd = rhs.release(); return *this; }
~unixFile() { if (fd != -1 ) ::close(fd); }
int release() { int old = fd; fd = -1; return old; }
int getFD() const { return fd; }
private:
int fd;
};
// A RAII class that encapsulates a memory-mapped file
class MMFile {
public:
MMFile (const char *fileName) : f(fileName)
{
struct stat fileStat;
if ( ::fstat(f.getFD(), &fileStat) < 0 )
throw std::runtime_error("can't fstat");
fSize = fileStat.st_size;
fAddr = ::mmap(nullptr, fSize, PROT_READ, MAP_SHARED, f.getFD(), 0);
if (fAddr == MAP_FAILED)
throw std::runtime_error("can't mmap");
}
~MMFile() { if (fAddr != nullptr ) ::munmap(fAddr, fSize); }
MMFile(const MMFile &) = delete;
MMFile & operator=(const MMFile&) = delete;
MMFile(MMFile &&rhs) : f(std::move(rhs.f)), fSize(rhs.fSize), fAddr(rhs.fAddr)
{
rhs.fSize = 0;
rhs.fAddr = nullptr;
}
MMFile & operator=(MMFile &&rhs)
{
f = std::move(rhs.f);
fSize = rhs.fSize; rhs.fSize = 0;
fAddr = rhs.fAddr; rhs.fAddr = nullptr;
return *this;
}
size_t size() const { return fSize; }
const unsigned char * base() const { return (const unsigned char *) fAddr; }
private:
unixFile f;
size_t fSize;
void *fAddr;
};
// A RAII class that encapsulates a POSIX file descriptor
class posixFile {
public:
posixFile (const char *fileName, const char *mode)
{
fp = ::fopen ( fileName, mode );
if ( fp == nullptr )
throw std::runtime_error("can't open");
}
posixFile(const posixFile &) = delete;
posixFile & operator=(const posixFile&) = delete;
posixFile(posixFile &&rhs) : fp(rhs.release ()) {}
posixFile & operator=(posixFile &&rhs) { fp = rhs.release(); return *this; }
~posixFile() { if (fp != nullptr) ::fclose(fp); }
FILE * release() { FILE *old = fp; fp = nullptr; return old; }
operator FILE *() const { return fp; }
private:
FILE * fp;
};