Joedb 10.4.3
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Abstract_File.cpp
Go to the documentation of this file.
4
5#include <array>
6#include <cstring>
7
8namespace joedb
9{
10 using Default_Buffer = std::array<char, 1 << 12>;
11
12 ////////////////////////////////////////////////////////////////////////////
14 ////////////////////////////////////////////////////////////////////////////
15 (
16 char *data,
17 const size_t size,
18 const int64_t offset
19 ) const
20 {
21 size_t result = 0;
22
23 while (result < size)
24 {
25 const size_t read_count = pread
26 (
27 data + result,
28 size - result,
29 offset + int64_t(result)
30 );
31
32 if (read_count == 0)
33 reading_past_end_of_file();
34
35 result += read_count;
36 }
37 }
38
39 ////////////////////////////////////////////////////////////////////////////
41 ////////////////////////////////////////////////////////////////////////////
42 (
43 Abstract_File &destination,
44 const int64_t start,
45 const int64_t size
46 ) const
47 {
48 Default_Buffer buffer;
49
50 int64_t done = 0;
51
52 while (size < 0 || done < size)
53 {
54 const size_t asked = size < 0
55 ? buffer.size()
56 : size_t(std::min(int64_t(buffer.size()), size - done));
57 const size_t received = pread(buffer.data(), asked, start + done);
58
59 if (received == 0)
60 {
61 if (size < 0)
62 return;
63 else
64 reading_past_end_of_file();
65 }
66
67 destination.pwrite(buffer.data(), received, start + done);
68 done += int64_t(received);
69 }
70 }
71
72 ////////////////////////////////////////////////////////////////////////////
74 ////////////////////////////////////////////////////////////////////////////
75 (
76 const Abstract_File &destination,
77 const int64_t from,
78 const int64_t until
79 ) const
80 {
81 Default_Buffer buffer;
82 Default_Buffer destination_buffer;
83
84 for (int64_t current = from; current < until;)
85 {
86 const size_t n0 = pread
87 (
88 buffer.data(),
89 size_t(std::min(int64_t(buffer.size()), until - current)),
90 current
91 );
92
93 size_t n1 = 0;
94
95 while (n1 < n0)
96 {
97 const size_t n = destination.pread
98 (
99 destination_buffer.data() + n1,
100 n0 - n1,
101 current + int64_t(n1)
102 );
103
104 if (n == 0)
105 break;
106
107 n1 += n;
108 }
109
110 if (n1 != n0)
111 return false;
112
113 if (n0 == 0)
114 reading_past_end_of_file();
115
116 const int diff = std::memcmp
117 (
118 buffer.data(),
119 destination_buffer.data(),
120 n0
121 );
122
123 if (diff)
124 return false;
125
126 current += int64_t(n0);
127 }
128
129 return true;
130 }
131
132 //////////////////////////////////////////////////////////////////////////
134 //////////////////////////////////////////////////////////////////////////
135 {
136 throw Exception("Trying to read past the end of file");
137 }
138
139 ////////////////////////////////////////////////////////////////////////////
140 std::string Abstract_File::read_blob(Blob blob, int64_t max_size) const
141 ////////////////////////////////////////////////////////////////////////////
142 {
143 if
144 (
145 blob.get_position() < 0 ||
146 blob.get_size() < 0 ||
147 (max_size >= 0 && blob.get_size() > max_size)
148 )
149 {
150 reading_past_end_of_file();
151 }
152
153 Async_Reader reader(*this, blob.get_position(), blob.get_end());
154 std::string result(size_t(blob.get_size()), 0);
155 reader.read(result.data(), result.size());
156 if (reader.is_end_of_file())
157 reading_past_end_of_file();
158 return result;
159 }
160}
virtual void copy_to(Abstract_File &destination, int64_t start, int64_t size) const
void full_pread(char *data, size_t size, int64_t offset) const
Fill the buffer, or throw if the end of the file is reached.
static void reading_past_end_of_file()
std::string read_blob(Blob blob, int64_t max_size=-1) const
virtual bool equal_to(const Abstract_File &destination, int64_t from, int64_t until) const
size_t read(char *buffer, size_t capacity)
bool is_end_of_file() const
std::array< char, 1<< 12 > Default_Buffer