1// [Blend2D]
2// 2D Vector Graphics Powered by a JIT Compiler.
3//
4// [License]
5// Zlib - See LICENSE.md file in the package.
6
7#ifndef BLEND2D_BLFILESYSTEM_P_H
8#define BLEND2D_BLFILESYSTEM_P_H
9
10#include "./blfilesystem.h"
11
12//! \cond INTERNAL
13//! \addtogroup blend2d_internal
14//! \{
15
16// ============================================================================
17// [BLFileMapping]
18// ============================================================================
19
20enum : uint32_t {
21 BL_FILE_SYSTEM_SMALL_FILE_SIZE_THRESHOLD = 16 * 1024
22};
23
24//! A thin abstraction over `mmap() / munmap()` (Posix) and `FileMapping` (Windows)
25//! to create a read-only file mapping for loading fonts and other resources.
26class BLFileMapping {
27public:
28 BL_NONCOPYABLE(BLFileMapping)
29
30 BLFileCore _file;
31#if defined(_WIN32)
32 HANDLE _fileMappingHandle;
33#endif
34
35 void* _data;
36 size_t _size;
37
38 // --------------------------------------------------------------------------
39 // [Construction / Destruction]
40 // --------------------------------------------------------------------------
41
42 BL_INLINE BLFileMapping() noexcept
43 : _file{-1},
44#if defined(_WIN32)
45 _fileMappingHandle(INVALID_HANDLE_VALUE),
46#endif
47 _data(nullptr),
48 _size(0) {}
49
50 BL_INLINE BLFileMapping(BLFileMapping&& other) noexcept {
51 BLFileCore file = other._file;
52 other._file.handle = -1;
53 this->_file.handle = file.handle;
54
55#if defined(_WIN32)
56 HANDLE fileMappingHandle = other._fileMappingHandle;
57 other._fileMappingHandle = INVALID_HANDLE_VALUE;
58 this->_fileMappingHandle = fileMappingHandle;
59#endif
60
61 void* data = other._data;
62 other._data = nullptr;
63 this->_data = data;
64
65 size_t size = other._size;
66 other._size = 0;
67 this->_size = size;
68 }
69
70 BL_INLINE ~BLFileMapping() noexcept { unmap(); }
71
72 // --------------------------------------------------------------------------
73 // [Accessors]
74 // --------------------------------------------------------------------------
75
76 //! Returns whether the mapping is empty (i.e. not fille has been mapped).
77 BL_INLINE bool empty() const noexcept { return _size == 0; }
78
79 //! Returns mapped data casted to `T`.
80 template<typename T = void>
81 BL_INLINE T* data() noexcept { return static_cast<T*>(_data); }
82 //! Returns mapped data casted to `T` (const).
83 template<typename T = void>
84 BL_INLINE const T* data() const noexcept { return static_cast<const T*>(_data); }
85
86 //! Returns the size of the mapped data.
87 BL_INLINE size_t size() const noexcept { return _size; }
88
89 //! Returns the associated file with the mapping.
90 BL_INLINE BLFile& file() noexcept { return blDownCast(_file); }
91
92#if defined(_WIN32)
93 //! Returns a Windows-specific HANDLE of file mapping.
94 BL_INLINE HANDLE fileMappingHandle() const noexcept { return _fileMappingHandle; }
95#endif
96
97 // --------------------------------------------------------------------------
98 // [Map / Unmap]
99 // --------------------------------------------------------------------------
100
101 //! Maps file `file` to memory. Takes ownership of `file` (moves) on success.
102 BL_HIDDEN BLResult map(BLFile& file, size_t size, uint32_t flags = 0) noexcept;
103
104 //! Unmaps previously mapped file or does nothing, if no file was mapped.
105 BL_HIDDEN BLResult unmap() noexcept;
106
107 // --------------------------------------------------------------------------
108 // [Operator Overload]
109 // --------------------------------------------------------------------------
110
111 BL_INLINE BLFileMapping& operator=(BLFileMapping&& other) noexcept {
112 BLFileCore file = other._file;
113 other._file.handle = -1;
114
115#if defined(_WIN32)
116 HANDLE fileMappingHandle = other._fileMappingHandle;
117 other._fileMappingHandle = INVALID_HANDLE_VALUE;
118#endif
119
120 void* data = other._data;
121 other._data = nullptr;
122
123 size_t size = other._size;
124 other._size = 0;
125
126 unmap();
127
128 this->_file.handle = file.handle;
129#if defined(_WIN32)
130 this->_fileMappingHandle = fileMappingHandle;
131#endif
132 this->_data = data;
133 this->_size = size;
134
135 return *this;
136 }
137};
138
139//! \}
140//! \endcond
141
142#endif // BLEND2D_BLFILESYSTEM_P_H
143