stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
system.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023-2024 Amebis
4*/
5
6#pragma once
7
8#include "compat.hpp"
9#if defined(_WIN32)
10#include "windows.h"
11#include <oaidl.h>
12#include <tchar.h>
13#else
14#ifndef _LARGEFILE64_SOURCE
15#define _LARGEFILE64_SOURCE // TODO: Make this -D compile-time project setting
16#endif
17#include <grp.h>
18#include <pwd.h>
19#include <string.h>
20#include <sys/types.h>
21#include <unistd.h>
22#endif
23#include <regex>
24#include <stdexcept>
25#include <string_view>
26#include <string>
27
28#if defined(_WIN32)
29#define PATH_SEPARATOR '\\'
30#define PATH_SEPARATOR_STR "\\"
31#else
32#define PATH_SEPARATOR '/'
33#define PATH_SEPARATOR_STR "/"
34#endif
35
36namespace stdex
37{
41#if defined(_WIN32)
42 using sys_handle = HANDLE;
43 const sys_handle invalid_handle = INVALID_HANDLE_VALUE;
44#else
45 using sys_handle = int;
46 const sys_handle invalid_handle = (sys_handle)-1;
47#endif
48
52#if defined(_WIN32)
53 inline DWORD sys_error() { return GetLastError(); }
54#else
55 inline int sys_error() { return errno; }
56#endif
57
61#if defined(_WIN32)
62 using schar_t = TCHAR;
63#else
64 using schar_t = char;
65#define _T(x) x
66#endif
67
72 using sys_char = schar_t;
73
77 using sstring = std::basic_string<stdex::schar_t>;
78
83 using sys_string = sstring;
84
88 using sstring_view = std::basic_string_view<stdex::schar_t, std::char_traits<stdex::schar_t>>;
89
93 using sregex = std::basic_regex<stdex::schar_t>;
94
99 {
100 static inline const sys_handle invalid_handle = stdex::invalid_handle;
101
105 static void close(_In_ sys_handle h)
106 {
107#if defined(_WIN32)
108 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
109 return;
110 throw std::system_error(GetLastError(), std::system_category(), "CloseHandle failed");
111#else
112 if (::close(h) >= 0 || errno == EBADF)
113 return;
114 throw std::system_error(errno, std::system_category(), "close failed");
115#endif
116 }
117
121 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit = false)
122 {
123 sys_handle h_new;
124#if defined(_WIN32)
125 HANDLE process = GetCurrentProcess();
126 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
127 return h_new;
128 throw std::system_error(GetLastError(), std::system_category(), "DuplicateHandle failed");
129#else
130 _Unreferenced_(inherit);
131 if ((h_new = dup(h)) >= 0)
132 return h_new;
133 throw std::system_error(errno, std::system_category(), "dup failed");
134#endif
135 }
136 };
137
141 template <class T = sys_handle, class TR = sys_object_traits>
143 {
144 public:
145 basic_sys_object(_In_opt_ T h = TR::invalid_handle) : m_h(h) {}
146
147 basic_sys_object(_In_ const basic_sys_object<T, TR>& other) : m_h(other.m_h != TR::invalid_handle ? TR::duplicate(other.m_h) : TR::invalid_handle) {}
148
149 basic_sys_object& operator =(_In_ const basic_sys_object<T, TR>& other)
150 {
151 if (this != std::addressof(other)) {
152 if (m_h != TR::invalid_handle)
153 TR::close(m_h);
154 m_h = other.m_h != TR::invalid_handle ? TR::duplicate(other.m_h) : TR::invalid_handle;
155 }
156 return *this;
157 }
158
159 basic_sys_object(_Inout_ basic_sys_object<T, TR>&& other) noexcept : m_h(other.m_h)
160 {
161 other.m_h = TR::invalid_handle;
162 }
163
164 basic_sys_object& operator =(_Inout_ basic_sys_object<T, TR>&& other) noexcept
165 {
166 if (this != std::addressof(other)) {
167 if (m_h != TR::invalid_handle)
168 TR::close(m_h);
169 m_h = other.m_h;
170 other.m_h = TR::invalid_handle;
171 }
172 return *this;
173 }
174
175 virtual ~basic_sys_object() noexcept(false)
176 {
177 if (m_h != TR::invalid_handle)
178 TR::close(m_h);
179 }
180
184 virtual void close()
185 {
186 if (m_h != TR::invalid_handle) {
187 TR::close(m_h);
188 m_h = TR::invalid_handle;
189 }
190 }
191
195 operator bool() const noexcept { return m_h != TR::invalid_handle; }
196
200 T get() const noexcept { return m_h; }
201
202 protected:
203 T m_h;
204 };
205
209 using sys_object = basic_sys_object<sys_handle, sys_object_traits>;
210
211#ifdef _WIN32
212 template <class T>
213 class safearray_accessor
214 {
215 public:
216 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
217 {
218 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
219 if (FAILED(hr))
220 throw std::system_error(hr, std::system_category(), "SafeArrayAccessData failed");
221 }
222
223 ~safearray_accessor()
224 {
225 SafeArrayUnaccessData(m_sa);
226 }
227
228 T* data() const { return m_data; }
229
230 protected:
231 LPSAFEARRAY m_sa;
232 T* m_data;
233 };
234
238 struct SafeArrayDestroy_delete
239 {
243 void operator()(_In_ LPSAFEARRAY sa) const
244 {
245 SafeArrayDestroy(sa);
246 }
247 };
248
252 struct SysFreeString_delete
253 {
257 void operator()(_In_ BSTR sa) const
258 {
259 SysFreeString(sa);
260 }
261 };
262#endif
263}
Operating system object base class.
Definition system.hpp:143
virtual void close()
Closes object.
Definition system.hpp:184
T get() const noexcept
Returns object handle.
Definition system.hpp:200
System object operations.
Definition system.hpp:99
static sys_handle duplicate(sys_handle h, bool inherit=false)
Duplicates given object.
Definition system.hpp:121
static void close(sys_handle h)
Closes object.
Definition system.hpp:105