HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
file_view_posix_impl.hpp
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
5#pragma once
6
7#include "file_view.hpp"
8#include "../utility/utility.hpp"
9#include "../macros.hpp"
10#include <mutex>
11#include <sys/mman.h>
12
13hi_export_module(hikogui.file.file_view : impl);
14
15hi_export namespace hi::inline v1 {
16
17file_view::file_view(std::shared_ptr<file_mapping> const &_file_mapping_object, std::size_t offset, std::size_t size) :
18 _file_mapping_object(_file_mapping_object), _offset(offset)
19{
20 if (size == 0) {
21 size = _file_mapping_object->size - _offset;
22 }
23 hi_assert(_offset + size <= _file_mapping_object->size);
24
25 int prot;
26 if (accessMode() >= (AccessMode::Read | AccessMode::Write)) {
27 prot = PROT_WRITE | PROT_READ;
28 } else if (accessMode() >= AccessMode::Read) {
29 prot = PROT_READ;
30 } else {
31 throw io_error("{}: Illegal access mode write-only when viewing file.", location());
32 }
33
34 int flags = MAP_SHARED;
35
36 void *data;
37 if ((data = ::mmap(0, size, prot, flags, _file_mapping_object->file->fileHandle, _offset)) == MAP_FAILED) {
38 throw io_error("{}: Could not map view of file. '{}'", location(), get_last_error_message());
39 }
40
41 auto *bytes_ptr = new void_span(data, size);
42 _bytes = std::shared_ptr<void_span>(bytes_ptr, file_view::unmap);
43}
44
45file_view::file_view(std::filesystem::path const &path, AccessMode accessMode, std::size_t offset, std::size_t size) :
46 file_view(findOrCreateFileMappingObject(path, accessMode, offset + size), offset, size)
47{
48}
49
50file_view::file_view(file_view const &other) noexcept :
51 _file_mapping_object(other._file_mapping_object), _bytes(other._bytes), _offset(other._offset)
52{
53 hi_assert(&other != this);
54}
55
56file_view &file_view::operator=(file_view const &other) noexcept
57{
58 hi_return_on_self_assignment(other);
59 _file_mapping_object = other._file_mapping_object;
60 _offset = other._offset;
61 _bytes = other._bytes;
62 return *this;
63}
64
65file_view::file_view(file_view &&other) noexcept :
66 _file_mapping_object(std::move(other._file_mapping_object)), _bytes(std::move(other._bytes)), _offset(other._offset)
67{
68 hi_assert(&other != this);
69}
70
71file_view &file_view::operator=(file_view &&other) noexcept
72{
73 hi_return_on_self_assignment(other);
74 _file_mapping_object = std::move(other._file_mapping_object);
75 _offset = other._offset;
76 _bytes = std::move(other._bytes);
77 return *this;
78}
79
80void file_view::unmap(void_span *bytes) noexcept
81{
82 if (bytes != nullptr) {
83 if (!bytes->empty()) {
84 if (!munmap(bytes->data(), bytes->size())) {
85 hi_log_error("Could not munmap view on file '{}'", get_last_error_message());
86 }
87 }
88 delete bytes;
89 }
90}
91
92void file_view::flush(void *base, std::size_t size)
93{
94 int flags = MS_SYNC;
95 if (!msync(base, size, flags)) {
96 throw io_error("{}: Could not flush file '{}'", location(), get_last_error_message());
97 }
98}
99
100} // namespace hi::inline v1
Defines the file_view class.
@ other
The gui_event does not have associated data.
hi_export std::string get_last_error_message(uint32_t error_code)
Get the error message from an error code.
Definition exception_win32_impl.hpp:21
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
T move(T... args)