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