Joedb 10.4.1
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 Abstract_File &destination,
17 const int64_t start,
18 const int64_t size
19 ) const
20 {
21 Default_Buffer buffer;
22
23 int64_t done = 0;
24
25 while (size < 0 || done < size)
26 {
27 const size_t asked = size < 0
28 ? buffer.size()
29 : size_t(std::min(int64_t(buffer.size()), size - done));
30 const size_t received = pread(buffer.data(), asked, start + done);
31
32 if (received == 0)
33 {
34 if (size < 0)
35 return;
36 else
37 reading_past_end_of_file();
38 }
39
40 destination.pwrite(buffer.data(), received, start + done);
41 done += int64_t(received);
42 }
43 }
44
45 ////////////////////////////////////////////////////////////////////////////
47 ////////////////////////////////////////////////////////////////////////////
48 (
49 const Abstract_File &destination,
50 const int64_t from,
51 const int64_t until
52 ) const
53 {
54 Default_Buffer buffer;
55 Default_Buffer destination_buffer;
56
57 for (int64_t current = from; current < until;)
58 {
59 const size_t n0 = pread
60 (
61 buffer.data(),
62 size_t(std::min(int64_t(buffer.size()), until - current)),
63 current
64 );
65
66 size_t n1 = 0;
67
68 while (n1 < n0)
69 {
70 const size_t n = destination.pread
71 (
72 destination_buffer.data() + n1,
73 n0 - n1,
74 current
75 );
76
77 if (n == 0)
78 break;
79
80 n1 += n;
81 }
82
83 if (n1 != n0)
84 return false;
85
86 if (n0 == 0)
87 reading_past_end_of_file();
88
89 const int diff = std::memcmp
90 (
91 buffer.data(),
92 destination_buffer.data(),
93 n0
94 );
95
96 if (diff)
97 return false;
98
99 current += int64_t(n0);
100 }
101
102 return true;
103 }
104
105 //////////////////////////////////////////////////////////////////////////
107 //////////////////////////////////////////////////////////////////////////
108 {
109 throw Exception("Trying to read past the end of file");
110 }
111
112 ////////////////////////////////////////////////////////////////////////////
113 std::string Abstract_File::read_blob(Blob blob) const
114 ////////////////////////////////////////////////////////////////////////////
115 {
116 {
117 const int64_t file_size = get_size();
118
119 if
120 (
121 blob.get_position() < 0 ||
122 blob.get_size() < 0 ||
123 (file_size >= 0 && blob.get_size() >= file_size)
124 )
125 {
126 reading_past_end_of_file();
127 }
128 }
129
130 Async_Reader reader(*this, blob.get_position(), blob.get_end());
131 std::string result(size_t(blob.get_size()), 0);
132 reader.read(result.data(), result.size());
133 if (reader.is_end_of_file())
134 reading_past_end_of_file();
135 return result;
136 }
137}
virtual void copy_to(Abstract_File &destination, int64_t start, int64_t size) const
static void reading_past_end_of_file()
std::string read_blob(Blob blob) 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