1#include "duckdb/common/serializer/buffered_file_reader.hpp"
2#include "duckdb/common/serializer/buffered_file_writer.hpp"
3#include "duckdb/common/exception.hpp"
4
5#include <cstring>
6
7using namespace duckdb;
8using namespace std;
9
10BufferedFileReader::BufferedFileReader(FileSystem &fs, const char *path)
11 : fs(fs), data(unique_ptr<data_t[]>(new data_t[FILE_BUFFER_SIZE])), offset(0), read_data(0), total_read(0) {
12 handle = fs.OpenFile(path, FileFlags::READ, FileLockType::READ_LOCK);
13 file_size = fs.GetFileSize(*handle);
14}
15
16void BufferedFileReader::ReadData(data_ptr_t target_buffer, uint64_t read_size) {
17 // first copy anything we can from the buffer
18 data_ptr_t end_ptr = target_buffer + read_size;
19 while (true) {
20 idx_t to_read = std::min((idx_t)(end_ptr - target_buffer), read_data - offset);
21 if (to_read > 0) {
22 memcpy(target_buffer, data.get() + offset, to_read);
23 offset += to_read;
24 target_buffer += to_read;
25 }
26 if (target_buffer < end_ptr) {
27 assert(offset == read_data);
28 total_read += read_data;
29 // did not finish reading yet but exhausted buffer
30 // read data into buffer
31 offset = 0;
32 read_data = fs.Read(*handle, data.get(), FILE_BUFFER_SIZE);
33 if (read_data == 0) {
34 throw SerializationException("not enough data in file to deserialize result");
35 }
36 } else {
37 return;
38 }
39 }
40}
41
42bool BufferedFileReader::Finished() {
43 return total_read + offset == file_size;
44}
45