1#ifndef joedb_Buffered_File_declared
2#define joedb_Buffered_File_declared
24 size_t read_buffer_size;
27 bool buffer_has_write_data() const noexcept
30 return buffer.
index > 0 && !read_buffer_size;
34 bool buffer_has_read_data() const
37 return read_buffer_size;
49 if (read_buffer_size == 0)
64 void check_write_buffer()
150 throw Exception(
"Trying to read past the end of file");
179 template<
typename T>
void write(T x)
182 static_assert(
sizeof(T) <=
decltype(buffer)::extra_size);
184 check_write_buffer();
192 read_data(
reinterpret_cast<char *
>(&result),
sizeof(result));
201 check_write_buffer();
208 if (buffer.
index + 8 <= read_buffer_size)
211 const uint8_t first_byte = read<uint8_t>();
212 int extra_bytes = first_byte >> 5;
213 T result = first_byte & 0x1f;
214 while (--extra_bytes >= 0)
215 result = T((result << 8) | read<uint8_t>());
221 return T(
compact_read<
typename std::underlying_type<T>::type>());
241 compact_write<int64_t>(blob.
get_size());
246 const int64_t position = compact_read<int64_t>();
247 const int64_t size = compact_read<int64_t>();
248 return Blob(position, size);
259 std::memcpy(buffer.
data + buffer.
index, data, n);
261 check_write_buffer();
269 std::memcpy(buffer.
data + buffer.
index, data, n);
271 check_write_buffer();
288 if (buffer.
index + n <= read_buffer_size)
290 std::memcpy(data, buffer.
data + buffer.
index, n);
296 size_t n0 = read_buffer_size - buffer.
index;
297 std::memcpy(data, buffer.
data + buffer.
index, n0);
300 if (n <= buffer.
size)
304 while (n0 < n && buffer.
index < read_buffer_size)
305 data[n0++] = buffer.
data[buffer.
index++];
311 if (actually_read == 0)
327 if (buffer.
index + n <= read_buffer_size)
virtual void shared_lock(int64_t start, int64_t size)
Lock a range of bytes for reading (prevents writes, not reads)
virtual int64_t get_size() const
Get the size of the file, or -1 if it is unknown.
virtual void unlock(int64_t start, int64_t size) noexcept
Remove a lock. The range should match the range of a corresponding lock.
virtual void exclusive_lock(int64_t start, int64_t size)
Lock a range of bytes for writing (prevents both writes and reads)
int64_t get_position() const noexcept
int64_t get_size() const noexcept
static constexpr size_t extra_size
char data[size+extra_size]
static constexpr size_t size
Head_Exclusive_Lock(Buffered_File &file)
Head_Shared_Lock(Buffered_File &file)
void ignore(const int64_t n)
void exclusive_lock_tail()
void write_reference(Record_Id id)
void write_blob(Blob blob)
virtual void copy_to(Buffered_File &destination, int64_t start, int64_t size) const
void set_position(int64_t position)
bool is_shared() const noexcept
virtual bool equal_to(Buffered_File &destination, int64_t from, int64_t until) const
void unlock_head() noexcept
bool tail_is_locked() const noexcept
void exclusive_lock_head()
static constexpr int64_t last_position
size_t read_data(char *data, const size_t n)
void write_string(const std::string &s)
static void reading_past_end_of_file()
void copy_to(Buffered_File &destination) const
bool is_readonly() const noexcept
void unlock_tail() noexcept
std::string read_string()
void destructor_flush() noexcept
void write_data(const char *data, size_t n)
Record_Id read_reference()
std::string safe_read_string(int64_t max_size)
int64_t get_position() const noexcept
size_t sequential_read(char *data, size_t size)
void sequential_write(const char *data, size_t size)
int64_t get_position() const
#define JOEDB_DEBUG_ASSERT(x)
@ write_existing
fails if does not exist or locked, locks the file for writing
@ 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
constexpr std::underlying_type< Table_Id >::type to_underlying(Table_Id id)