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 "../architecture.hpp"
13#include "../cast.hpp"
14#include <mutex>
15#include <cstdint>
16#include <map>
17#include <span>
18#include <filesystem>
19
20namespace hi { inline namespace v1 {
21
25enum class seek_whence {
26 begin,
27 current,
28 end
29};
30
36enum class access_mode {
37 read = 0x1,
38 write = 0x2,
39 rename = 0x4,
40 read_lock = 0x10,
41 write_lock = 0x20,
42 open = 0x100,
43 create = 0x200,
44 truncate = 0x400,
45 random = 0x1000,
46 sequential = 0x2000,
47 no_reuse = 0x4000,
48 write_through = 0x8000,
49 create_directories = 0x10000,
50
53 truncate_or_create_for_write = create_directories | open | create | truncate | write
54};
55
56[[nodiscard]] constexpr access_mode operator|(access_mode const& lhs, access_mode const& rhs) noexcept
57{
58 return static_cast<access_mode>(to_underlying(lhs) | to_underlying(rhs));
59}
60
61[[nodiscard]] constexpr access_mode operator&(access_mode const& lhs, access_mode const& rhs) noexcept
62{
63 return static_cast<access_mode>(to_underlying(lhs) & to_underlying(rhs));
64}
65
66[[nodiscard]] constexpr bool to_bool(access_mode const& rhs) noexcept
67{
68 return to_bool(to_underlying(rhs));
69}
70
71namespace detail {
72
73class file_impl {
74public:
75 virtual ~file_impl() = default;
76 file_impl(file_impl const& other) = delete;
77 file_impl(file_impl&& other) = delete;
78 file_impl& operator=(file_impl const& other) = delete;
79 file_impl& operator=(file_impl&& other) = delete;
80
82
83 [[nodiscard]] hi::access_mode access_mode() const noexcept
84 {
85 return _access_mode;
86 }
87
88 [[nodiscard]] virtual bool closed() = 0;
89 virtual void close() = 0;
90 virtual void flush() = 0;
91 virtual void rename(std::filesystem::path const& destination, bool overwrite_existing) = 0;
92 [[nodiscard]] virtual std::size_t size() const = 0;
93 [[nodiscard]] virtual std::size_t seek(std::ptrdiff_t offset, seek_whence whence) = 0;
94 virtual void write(void const *data, std::size_t size) = 0;
95 [[nodiscard]] virtual std::size_t read(void *data, std::size_t size) = 0;
96
97protected:
98 hi::access_mode _access_mode;
99};
100
101} // namespace detail
102
106class file {
107public:
112 file(std::filesystem::path const& path, access_mode access_mode = access_mode::open_for_read);
113
114 ~file() = default;
115 file(file const& other) noexcept = default;
116 file(file&& other) noexcept = default;
117 file& operator=(file const& other) noexcept = default;
118 file& operator=(file&& other) noexcept = default;
119
120 [[nodiscard]] hi::access_mode access_mode() const noexcept
121 {
122 return _pimpl->access_mode();
123 }
124
127 void close()
128 {
129 return _pimpl->close();
130 }
131
136 void flush()
137 {
138 return _pimpl->flush();
139 }
140
148 void rename(std::filesystem::path const& destination, bool overwrite_existing = true)
149 {
150 return _pimpl->rename(destination, overwrite_existing);
151 }
152
155 [[nodiscard]] std::size_t size() const
156 {
157 return _pimpl->size();
158 }
159
166 {
167 return _pimpl->seek(offset, whence);
168 }
169
173 {
174 return seek(0, seek_whence::current);
175 }
176
183 void write(void const *data, std::size_t size)
184 {
185 return _pimpl->write(data, size);
186 }
187
195 [[nodiscard]] std::size_t read(void *data, std::size_t size)
196 {
197 return _pimpl->read(data, size);
198 }
199
205 void write(std::span<std::byte const> bytes)
206 {
207 return write(bytes.data(), ssize(bytes));
208 }
209
215 void write(bstring_view text)
216 {
217 return write(text.data(), ssize(text));
218 }
219
225 void write(bstring const& text)
226 {
227 return write(text.data(), ssize(text));
228 }
229
235 void write(std::string_view text)
236 {
237 return write(text.data(), ssize(text));
238 }
239
246 [[nodiscard]] bstring read_bstring(std::size_t max_size = 10'000'000)
247 {
248 hilet offset = get_seek();
249 hilet size_ = std::min(max_size, this->size() - offset);
250
251 auto r = bstring{};
252 // XXX c++23 resize_and_overwrite()
253 r.resize(size_);
254 hilet bytes_read = read(r.data(), size_);
255 r.resize(bytes_read);
256 return r;
257 }
258
269 [[nodiscard]] std::string read_string(std::size_t max_size = 10'000'000)
270 {
271 hi_assert(get_seek() == 0);
272
273 hilet size_ = size();
274 if (size_ > max_size) {
275 throw io_error("read_string() requires the file size to be smaler than max_size.");
276 }
277
278 auto r = std::string{};
279 // XXX c++23 resize_and_overwrite()
280 r.resize(size_);
281 hilet bytes_read = read(r.data(), size_);
282 r.resize(bytes_read);
283 return r;
284 }
285
286private:
288
289 friend class file_view;
290};
291
292}} // namespace hi::v1
#define hi_assert(expression,...)
Assert if expression is true.
Definition assert.hpp:87
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
seek_whence
The position in the file to seek from.
Definition file.hpp:25
access_mode
The mode in which way to open a file.
Definition file.hpp:36
@ 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:15
geometry/margins.hpp
Definition assert.hpp:18
Exception thrown during I/O on an error.
Definition exception.hpp:85
Definition file.hpp:73
A File object.
Definition file.hpp:106
void rename(std::filesystem::path const &destination, bool overwrite_existing=true)
Rename an open file.
Definition file.hpp:148
std::size_t read(void *data, std::size_t size)
Read data from a file.
Definition file.hpp:195
std::size_t get_seek()
Get the current seek location.
Definition file.hpp:172
std::string read_string(std::size_t max_size=10 '000 '000)
Read a UTF-8 string from the file.
Definition file.hpp:269
std::size_t seek(std::ptrdiff_t offset, seek_whence whence=seek_whence::begin)
Set the seek location.
Definition file.hpp:165
void write(bstring const &text)
Write data to a file.
Definition file.hpp:225
void write(std::span< std::byte const > bytes)
Write data to a file.
Definition file.hpp:205
void close()
Close the file.
Definition file.hpp:127
std::size_t size() const
Return the size of the file.
Definition file.hpp:155
void flush()
Flush and block until all data is physically written to disk.
Definition file.hpp:136
void write(bstring_view text)
Write data to a file.
Definition file.hpp:215
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:246
void write(std::string_view text)
Write data to a file.
Definition file.hpp:235
void write(void const *data, std::size_t size)
Write data to a file.
Definition file.hpp:183
Map a file into virtual memory.
Definition file_view.hpp:97
T min(T... args)
T resize(T... args)