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 <intrin.h>
14#include <intsafe.h>
15#include <oaidl.h>
16#include <tchar.h>
17#else
18#define _LARGEFILE64_SOURCE
19#include <sys/types.h>
20#include <unistd.h>
21#endif
22#include "compat.hpp"
23#include <assert.h>
24#include <stdexcept>
25#include <string>
26
27// In case somebody #included <windows.h> before us and didn't #define NOMINMAX
28#ifdef _WIN32
29#ifdef min
30#undef min
31#endif
32#ifdef max
33#undef max
34#endif
35#endif
36
37#if defined(_WIN32)
38#define PATH_SEPARATOR '\\'
39#define PATH_SEPARATOR_STR "\\"
40#else
41#define PATH_SEPARATOR '/'
42#define PATH_SEPARATOR_STR "/"
43#endif
44
45namespace stdex
46{
50#if defined(_WIN32)
51 using sys_handle = HANDLE;
52 const sys_handle invalid_handle = INVALID_HANDLE_VALUE;
53#else
54 using sys_handle = int;
55 const sys_handle invalid_handle = (sys_handle)-1;
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
89 {
90 public:
91 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
92
93 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
94
95 sys_object& operator =(_In_ const sys_object& other)
96 {
97 if (this != std::addressof(other)) {
98 if (m_h != invalid_handle)
99 close(m_h);
100 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
101 }
102 return *this;
103 }
104
105 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
106 {
107 other.m_h = invalid_handle;
108 }
109
110 sys_object& operator =(_Inout_ sys_object&& other) noexcept
111 {
112 if (this != std::addressof(other)) {
113 if (m_h != invalid_handle)
114 close(m_h);
115 m_h = other.m_h;
116 other.m_h = invalid_handle;
117 }
118 return *this;
119 }
120
121 virtual ~sys_object() noexcept(false)
122 {
123 if (m_h != invalid_handle)
124 close(m_h);
125 }
126
130 virtual void close()
131 {
132 if (m_h != invalid_handle) {
133 close(m_h);
134 m_h = invalid_handle;
135 }
136 }
137
141 inline operator bool() const noexcept { return m_h != invalid_handle; }
142
146 inline sys_handle get() const noexcept { return m_h; }
147
148 protected:
152 static void close(_In_ sys_handle h)
153 {
154#ifdef _WIN32
155 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
156#else
157 if (::close(h) >= 0 || errno == EBADF)
158#endif
159 return;
160 throw std::runtime_error("failed to close handle");
161 }
162
166 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
167 {
168 sys_handle h_new;
169#ifdef _WIN32
170 HANDLE process = GetCurrentProcess();
171 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
172#else
173 _Unreferenced_(inherit);
174 if ((h_new = dup(h)) >= 0)
175#endif
176 return h_new;
177 throw std::runtime_error("failed to duplicate handle");
178 }
179
180 protected:
181 sys_handle m_h;
182 };
183
184#ifdef _WIN32
185 template <class T>
186 class safearray_accessor
187 {
188 public:
189 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
190 {
191 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
192 if (FAILED(hr))
193 throw std::invalid_argument("SafeArrayAccessData failed");
194 }
195
196 ~safearray_accessor()
197 {
198 SafeArrayUnaccessData(m_sa);
199 }
200
201 T* data() const { return m_data; }
202
203 protected:
204 LPSAFEARRAY m_sa;
205 T* m_data;
206 };
207
211 struct SafeArrayDestroy_delete
212 {
216 void operator()(_In_ LPSAFEARRAY sa) const
217 {
218 SafeArrayDestroy(sa);
219 }
220 };
221
225 struct SysFreeString_delete
226 {
230 void operator()(_In_ BSTR sa) const
231 {
232 SysFreeString(sa);
233 }
234 };
235#endif
236}
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:89
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:146
virtual void close()
Closes object.
Definition system.hpp:130
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:166
static void close(sys_handle h)
Closes object.
Definition system.hpp:152