]> git.sesse.net Git - nageru/blob - frame_on_disk.cpp
Allow symlinked frame files. Useful for testing.
[nageru] / frame_on_disk.cpp
1 #include <fcntl.h>
2 #include <unistd.h>
3
4 #include "frame_on_disk.h"
5
6 using namespace std;
7
8 FrameReader::~FrameReader()
9 {
10         if (fd != -1) {
11                 close(fd);
12         }
13 }
14
15 string FrameReader::read_frame(FrameOnDisk frame)
16 {
17         if (int(frame.filename_idx) != last_filename_idx) {
18                 if (fd != -1) {
19                         close(fd);  // Ignore errors.
20                 }
21
22                 string filename;
23                 {
24                         lock_guard<mutex> lock(frame_mu);
25                         filename = frame_filenames[frame.filename_idx];
26                 }
27
28                 fd = open(filename.c_str(), O_RDONLY);
29                 if (fd == -1) {
30                         perror(filename.c_str());
31                         exit(1);
32                 }
33
34                 // We want readahead. (Ignore errors.)
35                 posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
36
37                 last_filename_idx = frame.filename_idx;
38         }
39
40         string str;
41         str.resize(frame.size);
42         off_t offset = 0;
43         while (offset < frame.size) {
44                 int ret = pread(fd, &str[offset], frame.size - offset, frame.offset + offset);
45                 if (ret <= 0) {
46                         perror("pread");
47                         exit(1);
48                 }
49
50                 offset += ret;
51         }
52         return str;
53 }