-
Notifications
You must be signed in to change notification settings - Fork 7
/
HandleWrapper.cpp
88 lines (73 loc) · 1.88 KB
/
HandleWrapper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "stdafx.h"
#include "HandleWrapper.h"
#include "SystemError.h"
using namespace Linter;
HandleWrapper::HandleWrapper(HANDLE h) : m_handle(h)
{
if (h == INVALID_HANDLE_VALUE)
{
throw SystemError();
}
}
HandleWrapper::HandleWrapper(HandleWrapper &&other) noexcept : m_handle(std::exchange(other.m_handle, INVALID_HANDLE_VALUE))
{
}
void HandleWrapper::close() const
{
if (m_handle != INVALID_HANDLE_VALUE)
{
HANDLE h{std::exchange(m_handle, INVALID_HANDLE_VALUE)};
CloseHandle(h);
}
}
HandleWrapper::operator HANDLE() const noexcept
{
return m_handle;
}
HandleWrapper::~HandleWrapper()
{
close();
}
void HandleWrapper::writeFile(std::string const &str) const
{
static_assert(sizeof(str[0]) == 1, "Invalid byte size");
char const *start = str.c_str();
char const *end = start + str.size();
while (start != end)
{
const auto toWrite = static_cast<DWORD>(end - start);
DWORD written;
if (!WriteFile(m_handle, start, toWrite, &written, nullptr))
{
const DWORD err = GetLastError();
throw SystemError(err);
}
start += written;
}
}
std::string HandleWrapper::readFile() const
{
std::string result;
std::string buffer;
buffer.resize(0x4000);
for (;;)
{
DWORD readBytes;
//The API suggests when the other end closes the pipe, you should get 0. What appears to happen
//is that you get broken pipe.
if (!ReadFile(m_handle, &buffer[0], static_cast<DWORD>(buffer.size()), &readBytes, nullptr))
{
DWORD err = GetLastError();
if (err != ERROR_BROKEN_PIPE)
{
throw SystemError(err);
}
}
if (readBytes == 0)
{
break;
}
result += std::string(&buffer[0], readBytes);
}
return result;
}