stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
system.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023 Amebis
4*/
5
6#pragma once
7
8#ifdef _WIN32
9#ifndef NOMINMAX
10#define NOMINMAX // Collides with std::min/max
11#endif
12#include <windows.h>
13#include <intsafe.h>
14#include <oaidl.h>
15#include <tchar.h>
16#else
17#define _LARGEFILE64_SOURCE
18#include <sys/types.h>
19#include <unistd.h>
20#endif
21#include "compat.hpp"
22#include <assert.h>
23#include <stdexcept>
24#include <string>
25
26// In case somebody #included <windows.h> before us and didn't #define NOMINMAX
27#ifdef _WIN32
28#ifdef min
29#undef min
30#endif
31#ifdef max
32#undef max
33#endif
34#endif
35
36#if defined(_WIN32)
37#define PATH_SEPARATOR '\\'
38#define PATH_SEPARATOR_STR "\\"
39#else
40#define PATH_SEPARATOR '/'
41#define PATH_SEPARATOR_STR "/"
42#endif
43
44namespace stdex
45{
49#if defined(_WIN32)
50 using sys_handle = HANDLE;
51 const sys_handle invalid_handle = INVALID_HANDLE_VALUE;
52#else
53 using sys_handle = int;
54 const sys_handle invalid_handle = (sys_handle)-1;
55#endif
56
60#if defined(_WIN32)
61 using schar_t = TCHAR;
62#else
63 using schar_t = char;
64#define _T(x) x
65#endif
66
71 using sys_char = schar_t;
72
76 using sstring = std::basic_string<stdex::schar_t>;
77
82 using sys_string = sstring;
83
88 {
89 public:
90 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
91
92 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
93
94 sys_object& operator =(_In_ const sys_object& other)
95 {
96 if (this != std::addressof(other)) {
97 if (m_h != invalid_handle)
98 close(m_h);
99 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
100 }
101 return *this;
102 }
103
104 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
105 {
106 other.m_h = invalid_handle;
107 }
108
109 sys_object& operator =(_Inout_ sys_object&& other) noexcept
110 {
111 if (this != std::addressof(other)) {
112 if (m_h != invalid_handle)
113 close(m_h);
114 m_h = other.m_h;
115 other.m_h = invalid_handle;
116 }
117 return *this;
118 }
119
120 virtual ~sys_object()
121 {
122 if (m_h != invalid_handle)
123 close(m_h);
124 }
125
129 virtual void close()
130 {
131 if (m_h != invalid_handle) {
132 close(m_h);
133 m_h = invalid_handle;
134 }
135 }
136
140 inline operator bool() const noexcept { return m_h != invalid_handle; }
141
145 inline sys_handle get() const noexcept { return m_h; }
146
147 protected:
151 static void close(_In_ sys_handle h)
152 {
153#ifdef _WIN32
154 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
155#else
156 if (::close(h) >= 0 || errno == EBADF)
157#endif
158 return;
159 throw std::runtime_error("failed to close handle");
160 }
161
165 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
166 {
167 sys_handle h_new;
168#ifdef _WIN32
169 HANDLE process = GetCurrentProcess();
170 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
171#else
172 _Unreferenced_(inherit);
173 if ((h_new = dup(h)) >= 0)
174#endif
175 return h_new;
176 throw std::runtime_error("failed to duplicate handle");
177 }
178
179 protected:
180 sys_handle m_h;
181 };
182
183#ifdef _WIN32
184 template <class T>
185 class safearray_accessor
186 {
187 public:
188 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
189 {
190 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
191 if (FAILED(hr))
192 throw std::invalid_argument("SafeArrayAccessData failed");
193 }
194
195 ~safearray_accessor()
196 {
197 SafeArrayUnaccessData(m_sa);
198 }
199
200 T* data() const { return m_data; }
201
202 protected:
203 LPSAFEARRAY m_sa;
204 T* m_data;
205 };
206
210 struct SafeArrayDestroy_delete
211 {
215 void operator()(_In_ LPSAFEARRAY sa) const
216 {
217 SafeArrayDestroy(sa);
218 }
219 };
220
224 struct SysFreeString_delete
225 {
229 void operator()(_In_ BSTR sa) const
230 {
231 SysFreeString(sa);
232 }
233 };
234#endif
235}
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:88
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:145
virtual void close()
Closes object.
Definition system.hpp:129
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:165
static void close(sys_handle h)
Closes object.
Definition system.hpp:151