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 public:
101 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
102
103 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
104
105 sys_object& operator =(_In_ const sys_object& other)
106 {
107 if (this != std::addressof(other)) {
108 if (m_h != invalid_handle)
109 close(m_h);
110 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
111 }
112 return *this;
113 }
114
115 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
116 {
117 other.m_h = invalid_handle;
118 }
119
120 sys_object& operator =(_Inout_ sys_object&& other) noexcept
121 {
122 if (this != std::addressof(other)) {
123 if (m_h != invalid_handle)
124 close(m_h);
125 m_h = other.m_h;
126 other.m_h = invalid_handle;
127 }
128 return *this;
129 }
130
131 virtual ~sys_object() noexcept(false)
132 {
133 if (m_h != invalid_handle)
134 close(m_h);
135 }
136
140 virtual void close()
141 {
142 if (m_h != invalid_handle) {
143 close(m_h);
144 m_h = invalid_handle;
145 }
146 }
147
151 operator bool() const noexcept { return m_h != invalid_handle; }
152
156 sys_handle get() const noexcept { return m_h; }
157
158 protected:
162 static void close(_In_ sys_handle h)
163 {
164#ifdef _WIN32
165 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
166 return;
167 throw std::system_error(GetLastError(), std::system_category(), "CloseHandle failed");
168#else
169 if (::close(h) >= 0 || errno == EBADF)
170 return;
171 throw std::system_error(errno, std::system_category(), "close failed");
172#endif
173 }
174
178 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
179 {
180 sys_handle h_new;
181#ifdef _WIN32
182 HANDLE process = GetCurrentProcess();
183 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
184 return h_new;
185 throw std::system_error(GetLastError(), std::system_category(), "DuplicateHandle failed");
186#else
187 _Unreferenced_(inherit);
188 if ((h_new = dup(h)) >= 0)
189 return h_new;
190 throw std::system_error(errno, std::system_category(), "dup failed");
191#endif
192 }
193
194 protected:
195 sys_handle m_h;
196 };
197
198#ifdef _WIN32
199 template <class T>
200 class safearray_accessor
201 {
202 public:
203 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
204 {
205 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
206 if (FAILED(hr))
207 throw std::system_error(hr, std::system_category(), "SafeArrayAccessData failed");
208 }
209
210 ~safearray_accessor()
211 {
212 SafeArrayUnaccessData(m_sa);
213 }
214
215 T* data() const { return m_data; }
216
217 protected:
218 LPSAFEARRAY m_sa;
219 T* m_data;
220 };
221
225 struct SafeArrayDestroy_delete
226 {
230 void operator()(_In_ LPSAFEARRAY sa) const
231 {
232 SafeArrayDestroy(sa);
233 }
234 };
235
239 struct SysFreeString_delete
240 {
244 void operator()(_In_ BSTR sa) const
245 {
246 SysFreeString(sa);
247 }
248 };
249#endif
250}
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:99
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:156
virtual void close()
Closes object.
Definition system.hpp:140
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:178
static void close(sys_handle h)
Closes object.
Definition system.hpp:162