Joedb 10.0.1
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Buffered_File.cpp
Go to the documentation of this file.
4
5#include <algorithm>
6
7namespace joedb
8{
9 //////////////////////////////////////////////////////////////////////////
11 //////////////////////////////////////////////////////////////////////////
12 mode(mode),
13 locked_tail
14 (
15 mode != Open_Mode::shared_write &&
17 )
18 {
19 read_buffer_size = 0;
20 buffer.index = 0;
21 }
22
23 ////////////////////////////////////////////////////////////////////////////
25 ////////////////////////////////////////////////////////////////////////////
26 {
27 if (buffer_has_write_data())
28 write_buffer();
29 read_buffer_size = 0;
30 buffer.index = 0;
31 }
32
33 ////////////////////////////////////////////////////////////////////////////
35 ////////////////////////////////////////////////////////////////////////////
36 {
38 }
39
40 ////////////////////////////////////////////////////////////////////////////
41 void Buffered_File::set_position(int64_t new_position)
42 ////////////////////////////////////////////////////////////////////////////
43 {
44 flush();
45 sequential_seek(new_position);
46 }
47
48 ////////////////////////////////////////////////////////////////////////////
50 ////////////////////////////////////////////////////////////////////////////
51 (
52 Buffered_File &destination,
53 const int64_t start,
54 const int64_t size
55 ) const
56 {
57 int64_t done = 0;
58
59 while (done < size)
60 {
61 const size_t asked = size_t(std::min(int64_t(destination.buffer.size), size - done));
62 const size_t received = pread(destination.buffer.data, asked, start + done);
63
64 if (received == 0)
65 reading_past_end_of_file();
66
67 destination.pwrite(destination.buffer.data, received, start + done);
68 done += int64_t(received);
69 }
70 }
71
72 ////////////////////////////////////////////////////////////////////////////
74 ////////////////////////////////////////////////////////////////////////////
75 (
76 Buffered_File &destination,
77 const int64_t from,
78 const int64_t until
79 ) const
80 {
81 destination.flush();
82
83 for (int64_t current = from; current < until;)
84 {
85 const int64_t half_buffer_size = Buffered_File::buffer.ssize / 2;
86
87 const size_t n0 = pread
88 (
89 destination.buffer.data,
90 size_t(std::min(half_buffer_size, until - current)),
91 current
92 );
93
94 size_t n1 = 0;
95
96 while (n1 < n0)
97 {
98 const size_t n = destination.pread
99 (
100 destination.buffer.data + half_buffer_size + n1,
101 n0 - n1,
102 current
103 );
104
105 if (n == 0)
106 break;
107
108 n1 += n;
109 }
110
111 if (n1 != n0)
112 return false;
113
114 if (n0 == 0)
115 reading_past_end_of_file();
116
117 const int diff = std::memcmp
118 (
119 destination.buffer.data,
120 destination.buffer.data + half_buffer_size,
121 n0
122 );
123
124 if (diff)
125 return false;
126
127 current += int64_t(n0);
128 }
129
130 return true;
131 }
132
133 ////////////////////////////////////////////////////////////////////////////
134 void Buffered_File::write_string(const std::string &s)
135 ////////////////////////////////////////////////////////////////////////////
136 {
137 compact_write<size_t>(s.size());
138 write_data(s.data(), s.size());
139 }
140
141 ////////////////////////////////////////////////////////////////////////////
143 ////////////////////////////////////////////////////////////////////////////
144 {
145 const size_t size = compact_read<size_t>();
146 std::string s(size, 0);
147 read_data(s.data(), size);
148 return s;
149 }
150
151 ////////////////////////////////////////////////////////////////////////////
152 std::string Buffered_File::safe_read_string(int64_t max_size)
153 ////////////////////////////////////////////////////////////////////////////
154 {
155 std::string s;
156 const int64_t size = compact_read<int64_t>();
157 if (size > 0 && size < max_size)
158 {
159 s.resize(size_t(size));
160 read_data(s.data(), size_t(size));
161 }
162 return s;
163 }
164
165 ////////////////////////////////////////////////////////////////////////////
167 ////////////////////////////////////////////////////////////////////////////
168 {
169 if (buffer_has_write_data())
170 {
171 Destructor_Logger::write("warning: an unflushed file is being destroyed");
172 try { write_buffer(); } catch (...) {}
173 }
174 }
175
176 ////////////////////////////////////////////////////////////////////////////
177 std::string Buffered_File::read_blob(Blob blob) const
178 ////////////////////////////////////////////////////////////////////////////
179 {
180 Async_Reader reader(*this, blob.get_position(), blob.get_end());
181 std::string result(size_t(blob.get_size()), 0);
182 reader.read(result.data(), result.size());
183 if (reader.is_end_of_file())
184 reading_past_end_of_file();
185 return result;
186 }
187}
size_t read(char *buffer, size_t capacity)
bool is_end_of_file() const
size_t index
Definition Buffer.h:20
virtual void copy_to(Buffered_File &destination, int64_t start, int64_t size) const
void set_position(int64_t position)
virtual bool equal_to(Buffered_File &destination, int64_t from, int64_t until) const
size_t read_data(char *data, const size_t n)
void write_string(const std::string &s)
std::string read_string()
void destructor_flush() noexcept
void write_data(const char *data, size_t n)
std::string safe_read_string(int64_t max_size)
int64_t get_position() const noexcept
Buffered_File(Open_Mode mode)
static void write(const char *message) noexcept
void sequential_seek(int64_t new_position)
Open_Mode
Definition Open_Mode.h:8
@ shared_write
like write_existing_or_create_new, but does not lock the file, and does not fail if locked
@ read_existing
fails if does not exist
Definition Blob.h:7