HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
file.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2019-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
9#pragma once
10
11#include "../byte_string.hpp"
12#include "../utility/module.hpp"
13#include <mutex>
14#include <cstdint>
15#include <map>
16#include <span>
17#include <filesystem>
18
19namespace hi { inline namespace v1 {
20
24enum class seek_whence {
25 begin,
26 current,
27 end
28};
29
35enum class access_mode {
36 read = 0x1,
37 write = 0x2,
38 rename = 0x4,
39 read_lock = 0x10,
40 write_lock = 0x20,
41 open = 0x100,
42 create = 0x200,
43 truncate = 0x400,
44 random = 0x1000,
45 sequential = 0x2000,
46 no_reuse = 0x4000,
47 write_through = 0x8000,
48 create_directories = 0x10000,
49
52 truncate_or_create_for_write = create_directories | open | create | truncate | write
53};
54
55[[nodiscard]] constexpr access_mode operator|(access_mode const& lhs, access_mode const& rhs) noexcept
56{
57 return static_cast<access_mode>(to_underlying(lhs) | to_underlying(rhs));
58}
59
60[[nodiscard]] constexpr access_mode operator&(access_mode const& lhs, access_mode const& rhs) noexcept
61{
62 return static_cast<access_mode>(to_underlying(lhs) & to_underlying(rhs));
63}
64
65[[nodiscard]] constexpr bool to_bool(access_mode const& rhs) noexcept
66{
67 return to_bool(to_underlying(rhs));
68}
69
70namespace detail {
71
72class file_impl {
73public:
74 virtual ~file_impl() = default;
75 file_impl(file_impl const& other) = delete;
76 file_impl(file_impl&& other) = delete;
77 file_impl& operator=(file_impl const& other) = delete;
78 file_impl& operator=(file_impl&& other) = delete;
79
81
82 [[nodiscard]] hi::access_mode access_mode() const noexcept
83 {
84 return _access_mode;
85 }
86
87 [[nodiscard]] virtual bool closed() = 0;
88 virtual void close() = 0;
89 virtual void flush() = 0;
90 virtual void rename(std::filesystem::path const& destination, bool overwrite_existing) = 0;
91 [[nodiscard]] virtual std::size_t size() const = 0;
92 [[nodiscard]] virtual std::size_t seek(std::ptrdiff_t offset, seek_whence whence) = 0;
93 virtual void write(void const *data, std::size_t size) = 0;
94 [[nodiscard]] virtual std::size_t read(void *data, std::size_t size) = 0;
95
96protected:
97 hi::access_mode _access_mode;
98};
99
100} // namespace detail
101
105class file {
106public:
111 file(std::filesystem::path const& path, access_mode access_mode = access_mode::open_for_read);
112
113 ~file() = default;
114 file(file const& other) noexcept = default;
115 file(file&& other) noexcept = default;
116 file& operator=(file const& other) noexcept = default;
117 file& operator=(file&& other) noexcept = default;
118
119 [[nodiscard]] hi::access_mode access_mode() const noexcept
120 {
121 return _pimpl->access_mode();
122 }
123
126 void close()
127 {
128 return _pimpl->close();
129 }
130
135 void flush()
136 {
137 return _pimpl->flush();
138 }
139
147 void rename(std::filesystem::path const& destination, bool overwrite_existing = true)
148 {
149 return _pimpl->rename(destination, overwrite_existing);
150 }
151
154 [[nodiscard]] std::size_t size() const
155 {
156 return _pimpl->size();
157 }
158
165 {
166 return _pimpl->seek(offset, whence);
167 }
168
172 {
173 return seek(0, seek_whence::current);
174 }
175
182 void write(void const *data, std::size_t size)
183 {
184 return _pimpl->write(data, size);
185 }
186
194 [[nodiscard]] std::size_t read(void *data, std::size_t size)
195 {
196 return _pimpl->read(data, size);
197 }
198
204 void write(std::span<std::byte const> bytes)
205 {
206 return write(bytes.data(), ssize(bytes));
207 }
208
214 void write(bstring_view text)
215 {
216 return write(text.data(), ssize(text));
217 }
218
224 void write(bstring const& text)
225 {
226 return write(text.data(), ssize(text));
227 }
228
234 void write(std::string_view text)
235 {
236 return write(text.data(), ssize(text));
237 }
238
245 [[nodiscard]] bstring read_bstring(std::size_t max_size = 10'000'000)
246 {
247 hilet offset = get_seek();
248 hilet size_ = std::min(max_size, this->size() - offset);
249
250 auto r = bstring{};
251 // XXX c++23 resize_and_overwrite()
252 r.resize(size_);
253 hilet bytes_read = read(r.data(), size_);
254 r.resize(bytes_read);
255 return r;
256 }
257
268 [[nodiscard]] std::string read_string(std::size_t max_size = 10'000'000)
269 {
270 hi_assert(get_seek() == 0);
271
272 hilet size_ = size();
273 if (size_ > max_size) {
274 throw io_error("read_string() requires the file size to be smaler than max_size.");
275 }
276
277 auto r = std::string{};
278 // XXX c++23 resize_and_overwrite()
279 r.resize(size_);
280 hilet bytes_read = read(r.data(), size_);
281 r.resize(bytes_read);
282 return r;
283 }
284
285private:
287
288 friend class file_view;
289};
290
291}} // namespace hi::v1
#define hi_assert(expression,...)
Assert if expression is true.
Definition assert.hpp:199
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
seek_whence
The position in the file to seek from.
Definition file.hpp:24
access_mode
The mode in which way to open a file.
Definition file.hpp:35
@ current
Continue from the current position.
@ end
Start from the end of the file.
@ begin
Start from the beginning of the file.
@ truncate
After the file has been opened, truncate it.
@ read_lock
Lock the file for reading, i.e. shared-lock.
@ sequential
Hint that the data should be prefetched.
@ create
Create file if it does not exist, or fail.
@ open
Open file if it exist, or fail.
@ random
Hint the data should not be prefetched.
@ open_for_read_and_write
Default open a file for reading and writing.
@ open_for_read
Default open a file for reading.
@ write_through
Hint that writes should be send directly to disk.
@ write_lock
Lock the file for writing, i.e. exclusive-lock.
@ no_reuse
Hint that the data should not be cached.
@ rename
Allow renaming an open file.
@ read
Allow read access to a file.
@ write
Allow write access to a file.
@ create_directories
Create directory hierarchy, if the file could not be created.
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Definition file.hpp:72
A File object.
Definition file.hpp:105
void rename(std::filesystem::path const &destination, bool overwrite_existing=true)
Rename an open file.
Definition file.hpp:147
std::size_t read(void *data, std::size_t size)
Read data from a file.
Definition file.hpp:194
std::size_t get_seek()
Get the current seek location.
Definition file.hpp:171
std::string read_string(std::size_t max_size=10 '000 '000)
Read a UTF-8 string from the file.
Definition file.hpp:268
std::size_t seek(std::ptrdiff_t offset, seek_whence whence=seek_whence::begin)
Set the seek location.
Definition file.hpp:164
void write(bstring const &text)
Write data to a file.
Definition file.hpp:224
void write(std::span< std::byte const > bytes)
Write data to a file.
Definition file.hpp:204
void close()
Close the file.
Definition file.hpp:126
std::size_t size() const
Return the size of the file.
Definition file.hpp:154
void flush()
Flush and block until all data is physically written to disk.
Definition file.hpp:135
void write(bstring_view text)
Write data to a file.
Definition file.hpp:214
file(std::filesystem::path const &path, access_mode access_mode=access_mode::open_for_read)
Open a file at location.
bstring read_bstring(std::size_t max_size=10 '000 '000)
Read bytes from the file.
Definition file.hpp:245
void write(std::string_view text)
Write data to a file.
Definition file.hpp:234
void write(void const *data, std::size_t size)
Write data to a file.
Definition file.hpp:182
Map a file into virtual memory.
Definition file_view.hpp:97
Exception thrown during I/O on an error.
Definition exception.hpp:175
T data(T... args)
T min(T... args)
T resize(T... args)