GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 71.0% 71 / 0 / 100
Functions: 93.3% 14 / 0 / 15
Branches: 51.6% 32 / 0 / 62

src/win_file_stream.cpp
Line Branch Exec Source
1 #include "DetourModKit/win_file_stream.hpp"
2
3 #include <windows.h>
4 #include <algorithm>
5 #include <cassert>
6 #include <climits>
7 #include <cstring>
8
9 namespace DetourModKit
10 {
11 // --- WinFileStreamBuf ---
12
13 40 WinFileStreamBuf::WinFileStreamBuf() noexcept
14 40 : handle_(INVALID_HANDLE_VALUE)
15 {
16 120 setp(buffer_.data(), buffer_.data() + BUFFER_SIZE);
17 40 }
18
19 40 WinFileStreamBuf::~WinFileStreamBuf() noexcept
20 {
21 40 close();
22 40 }
23
24 238 bool WinFileStreamBuf::open(const std::string &path, std::ios_base::openmode mode)
25 {
26
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 238 times.
238 if (is_open())
27 {
28 close();
29 }
30
31 238 DWORD creation = CREATE_ALWAYS;
32
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 238 times.
238 if (mode & std::ios_base::app)
33 {
34 creation = OPEN_ALWAYS;
35 }
36
37 238 handle_ = CreateFileA(
38 path.c_str(),
39 GENERIC_WRITE,
40 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
41 nullptr,
42 creation,
43 FILE_ATTRIBUTE_NORMAL,
44 nullptr);
45
46
2/2
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 237 times.
238 if (handle_ == INVALID_HANDLE_VALUE)
47 {
48 1 return false;
49 }
50
51
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 23 taken 237 times.
237 if (mode & std::ios_base::app)
52 {
53 if (SetFilePointer(static_cast<HANDLE>(handle_), 0, nullptr, FILE_END) ==
54 INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
55 {
56 CloseHandle(static_cast<HANDLE>(handle_));
57 handle_ = INVALID_HANDLE_VALUE;
58 return false;
59 }
60 }
61
62 711 setp(buffer_.data(), buffer_.data() + BUFFER_SIZE);
63 237 return true;
64 }
65
66 46413 bool WinFileStreamBuf::is_open() const noexcept
67 {
68 46413 return handle_ != INVALID_HANDLE_VALUE;
69 }
70
71 248 void WinFileStreamBuf::close()
72 {
73
2/2
✓ Branch 3 → 4 taken 11 times.
✓ Branch 3 → 5 taken 237 times.
248 if (!is_open())
74 {
75 11 return;
76 }
77
78 237 flush_buffer();
79 237 CloseHandle(static_cast<HANDLE>(handle_));
80 237 handle_ = INVALID_HANDLE_VALUE;
81 237 setp(nullptr, nullptr);
82 }
83
84 WinFileStreamBuf::int_type WinFileStreamBuf::overflow(int_type ch)
85 {
86 if (!is_open())
87 {
88 return traits_type::eof();
89 }
90
91 if (!flush_buffer())
92 {
93 return traits_type::eof();
94 }
95
96 if (!traits_type::eq_int_type(ch, traits_type::eof()))
97 {
98 *pptr() = traits_type::to_char_type(ch);
99 pbump(1);
100 }
101
102 return traits_type::not_eof(ch);
103 }
104
105 709 int WinFileStreamBuf::sync()
106 {
107
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 709 times.
709 if (!is_open())
108 {
109 return -1;
110 }
111
112
1/2
✓ Branch 6 → 7 taken 709 times.
✗ Branch 6 → 8 not taken.
709 return flush_buffer() ? 0 : -1;
113 }
114
115 43428 std::streamsize WinFileStreamBuf::xsputn(const char *s, std::streamsize count)
116 {
117
5/6
✓ Branch 3 → 4 taken 43428 times.
✗ Branch 3 → 5 not taken.
✓ Branch 4 → 5 taken 4 times.
✓ Branch 4 → 6 taken 43424 times.
✓ Branch 7 → 8 taken 4 times.
✓ Branch 7 → 9 taken 43424 times.
43428 if (!is_open() || count <= 0)
118 {
119 4 return 0;
120 }
121
122 43424 std::streamsize written = 0;
123
124
2/2
✓ Branch 27 → 10 taken 43426 times.
✓ Branch 27 → 28 taken 43424 times.
86850 while (written < count)
125 {
126 43426 const auto available = static_cast<std::streamsize>(epptr() - pptr());
127 43426 const auto to_copy = std::min(count - written, available);
128
129
1/2
✓ Branch 13 → 14 taken 43426 times.
✗ Branch 13 → 20 not taken.
43426 if (to_copy > 0)
130 {
131 43426 std::memcpy(pptr(), s + written, static_cast<size_t>(to_copy));
132
1/2
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 43426 times.
43426 assert(to_copy <= INT_MAX);
133 43426 pbump(static_cast<int>(to_copy));
134 43426 written += to_copy;
135 }
136
137
2/2
✓ Branch 22 → 23 taken 2 times.
✓ Branch 22 → 26 taken 43424 times.
43426 if (pptr() == epptr())
138 {
139
2/4
✓ Branch 23 → 24 taken 2 times.
✗ Branch 23 → 30 not taken.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 2 times.
2 if (!flush_buffer())
140 {
141 break;
142 }
143 }
144 }
145
146 43424 return written;
147 }
148
149 948 bool WinFileStreamBuf::flush_buffer()
150 {
151 948 const auto count = static_cast<DWORD>(pptr() - pbase());
152
2/2
✓ Branch 4 → 5 taken 304 times.
✓ Branch 4 → 6 taken 644 times.
948 if (count == 0)
153 {
154 304 return true;
155 }
156
157 644 DWORD bytes_written = 0;
158 1288 const BOOL result = WriteFile(
159
1/2
✓ Branch 7 → 8 taken 644 times.
✗ Branch 7 → 20 not taken.
644 static_cast<HANDLE>(handle_), pbase(), count, &bytes_written, nullptr);
160 1932 setp(buffer_.data(), buffer_.data() + BUFFER_SIZE);
161
162
2/4
✓ Branch 13 → 14 taken 644 times.
✗ Branch 13 → 16 not taken.
✓ Branch 14 → 15 taken 644 times.
✗ Branch 14 → 16 not taken.
644 return result != 0 && bytes_written == count;
163 }
164
165 // --- WinFileStream ---
166
167 3 WinFileStream::WinFileStream()
168
1/2
✓ Branch 3 → 4 taken 3 times.
✗ Branch 3 → 6 not taken.
3 : std::ostream(&buf_)
169 {
170 3 }
171
172 37 WinFileStream::WinFileStream(const std::string &path, std::ios_base::openmode mode)
173
1/2
✓ Branch 3 → 4 taken 37 times.
✗ Branch 3 → 11 not taken.
37 : std::ostream(&buf_)
174 {
175
1/4
DetourModKit::WinFileStream::WinFileStream(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode):
✓ Branch 5 → 6 taken 37 times.
✗ Branch 5 → 7 not taken.
DetourModKit::WinFileStream::WinFileStream(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
37 open(path, mode);
176 37 }
177
178 40 WinFileStream::~WinFileStream() noexcept = default;
179
180 238 void WinFileStream::open(const std::string &path, std::ios_base::openmode mode)
181 {
182 238 clear();
183
2/2
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 237 times.
238 if (!buf_.open(path, mode))
184 {
185 1 setstate(std::ios_base::failbit);
186 }
187 238 }
188
189 1790 bool WinFileStream::is_open() const noexcept
190 {
191 1790 return buf_.is_open();
192 }
193
194 208 void WinFileStream::close()
195 {
196 208 buf_.close();
197 208 }
198
199 } // namespace DetourModKit
200