CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
stream.cpp
Go to the documentation of this file.
1
9#include "system/stream.h"
10
11#include "errors/fatal.h"
13
14#include <cassert>
15
16#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
17#include <stdio.h>
18#elif defined(_WIN32) || defined(_WIN64)
19#include <windows.h>
20#endif
21
22namespace CppCommon {
23
25
26class StdInput::Impl
27{
28public:
29 Impl()
30 {
31#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
32 _stream = stdin;
33 if (_stream == nullptr)
34 throwex SystemException("Failed to get a valid standard input stream!");
35#elif defined(_WIN32) || defined(_WIN64)
36 _stream = GetStdHandle(STD_INPUT_HANDLE);
37 if (_stream == INVALID_HANDLE_VALUE)
38 throwex SystemException("Failed to get a valid standard input stream!");
39#endif
40 }
41
42 ~Impl() = default;
43
44 void* stream() const noexcept
45 {
46 return _stream;
47 }
48
49 bool IsValid() const noexcept
50 {
51#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
52 return (_stream != nullptr);
53#elif defined(_WIN32) || defined(_WIN64)
54 return (_stream != INVALID_HANDLE_VALUE);
55#endif
56 }
57
58 size_t Read(void* buffer, size_t size)
59 {
60 if ((buffer == nullptr) || (size == 0))
61 return 0;
62
63 assert(IsValid() && "Standard input stream is not valid!");
64 if (!IsValid())
65 throwex SystemException("Cannot read from the invalid standard input stream!");
66#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
67 size_t result = fread(buffer, 1, size, _stream);
68 if (ferror(_stream) != 0)
69 throwex SystemException("Cannot read from the standard input stream!");
70 return result;
71#elif defined(_WIN32) || defined(_WIN64)
72 DWORD result;
73 if (!ReadFile(_stream, buffer, (DWORD)size, &result, nullptr))
74 throwex SystemException("Cannot read from the standard input stream!");
75 return (size_t)result;
76#endif
77 }
78
79private:
80#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
81 FILE* _stream;
82#elif defined(_WIN32) || defined(_WIN64)
83 HANDLE _stream;
84#endif
85};
86
87class StdOutput::Impl
88{
89public:
90 Impl()
91 {
92#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
93 _stream = stdout;
94 if (_stream == nullptr)
95 throwex SystemException("Failed to get a valid standard output stream!");
96#elif defined(_WIN32) || defined(_WIN64)
97 _stream = GetStdHandle(STD_OUTPUT_HANDLE);
98 if (_stream == INVALID_HANDLE_VALUE)
99 throwex SystemException("Failed to get a valid standard output stream!");
100#endif
101 }
102
103 ~Impl() = default;
104
105 void* stream() const noexcept
106 {
107 return _stream;
108 }
109
110 bool IsValid() const noexcept
111 {
112#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
113 return (_stream != nullptr);
114#elif defined(_WIN32) || defined(_WIN64)
115 return (_stream != INVALID_HANDLE_VALUE);
116#endif
117 }
118
119 size_t Write(const void* buffer, size_t size)
120 {
121 if ((buffer == nullptr) || (size == 0))
122 return 0;
123
124 assert(IsValid() && "Standard output stream is not valid!");
125 if (!IsValid())
126 throwex SystemException("Cannot write into the invalid standard output stream!");
127#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
128 size_t result = fwrite(buffer, 1, size, _stream);
129 if (ferror(_stream) != 0)
130 throwex SystemException("Cannot write into the standard output stream!");
131 return result;
132#elif defined(_WIN32) || defined(_WIN64)
133 DWORD result;
134 if (!WriteFile(_stream, buffer, (DWORD)size, &result, nullptr))
135 throwex SystemException("Cannot write into the standard output stream!");
136 return (size_t)result;
137#endif
138 }
139
140 void Flush()
141 {
142#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
143 int result = fflush(_stream);
144 if (result != 0)
145 throwex SystemException("Cannot flush the standard output stream!");
146#elif defined(_WIN32) || defined(_WIN64)
147 if (!FlushFileBuffers(_stream))
148 throwex SystemException("Cannot flush the standard output stream!");
149#endif
150 }
151
152private:
153#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
154 FILE* _stream;
155#elif defined(_WIN32) || defined(_WIN64)
156 HANDLE _stream;
157#endif
158};
159
160class StdError::Impl
161{
162public:
163 Impl()
164 {
165#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
166 _stream = stderr;
167 if (_stream == nullptr)
168 throwex SystemException("Failed to get a valid standard error stream!");
169#elif defined(_WIN32) || defined(_WIN64)
170 _stream = GetStdHandle(STD_ERROR_HANDLE);
171 if (_stream == INVALID_HANDLE_VALUE)
172 throwex SystemException("Failed to get a valid standard error stream!");
173#endif
174 }
175
176 ~Impl() = default;
177
178 void* stream() const noexcept
179 {
180 return _stream;
181 }
182
183 bool IsValid() const noexcept
184 {
185#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
186 return (_stream != nullptr);
187#elif defined(_WIN32) || defined(_WIN64)
188 return (_stream != INVALID_HANDLE_VALUE);
189#endif
190 }
191
192 size_t Write(const void* buffer, size_t size)
193 {
194 if ((buffer == nullptr) || (size == 0))
195 return 0;
196
197 assert(IsValid() && "Standard error stream is not valid!");
198 if (!IsValid())
199 throwex SystemException("Cannot write into the invalid standard error stream!");
200#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
201 size_t result = fwrite(buffer, 1, size, _stream);
202 if (ferror(_stream) != 0)
203 throwex SystemException("Cannot write into the standard error stream!");
204 return result;
205#elif defined(_WIN32) || defined(_WIN64)
206 DWORD result;
207 if (!WriteFile(_stream, buffer, (DWORD)size, &result, nullptr))
208 throwex SystemException("Cannot write into the standard error stream!");
209 return (size_t)result;
210#endif
211 }
212
213 void Flush()
214 {
215#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
216 int result = fflush(_stream);
217 if (result != 0)
218 throwex SystemException("Cannot flush the standard error stream!");
219#elif defined(_WIN32) || defined(_WIN64)
220 if (!FlushFileBuffers(_stream))
221 throwex SystemException("Cannot flush the standard error stream!");
222#endif
223 }
224
225private:
226#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
227 FILE* _stream;
228#elif defined(_WIN32) || defined(_WIN64)
229 HANDLE _stream;
230#endif
231};
232
234
236{
237 // Check implementation storage parameters
238 [[maybe_unused]] ValidateAlignedStorage<sizeof(Impl), alignof(Impl), StorageSize, StorageAlign> _;
239 static_assert((StorageSize >= sizeof(Impl)), "StdInput::StorageSize must be increased!");
240 static_assert(((StorageAlign % alignof(Impl)) == 0), "StdInput::StorageAlign must be adjusted!");
241
242 // Create the implementation instance
243 new(&_storage)Impl();
244}
245
247{
248 // Delete the implementation instance
249 reinterpret_cast<Impl*>(&_storage)->~Impl();
250}
251
252void* StdInput::stream() const noexcept { return impl().stream(); }
253bool StdInput::IsValid() const noexcept { return impl().IsValid(); }
254size_t StdInput::Read(void* buffer, size_t size) { return impl().Read(buffer, size); }
255
256void StdInput::swap(StdInput& stream) noexcept
257{
258 using std::swap;
259 swap(_storage, stream._storage);
260}
261
263{
264 // Check implementation storage parameters
265 [[maybe_unused]] ValidateAlignedStorage<sizeof(Impl), alignof(Impl), StorageSize, StorageAlign> _;
266 static_assert((StorageSize >= sizeof(Impl)), "StdOutput::StorageSize must be increased!");
267 static_assert(((StorageAlign % alignof(Impl)) == 0), "StdOutput::StorageAlign must be adjusted!");
268
269 // Create the implementation instance
270 new(&_storage)Impl();
271}
272
274{
275 // Delete the implementation instance
276 reinterpret_cast<Impl*>(&_storage)->~Impl();
277}
278
279void* StdOutput::stream() const noexcept { return impl().stream(); }
280bool StdOutput::IsValid() const noexcept { return impl().IsValid(); }
281size_t StdOutput::Write(const void* buffer, size_t size) { return impl().Write(buffer, size); }
282void StdOutput::Flush() { return impl().Flush(); }
283
284void StdOutput::swap(StdOutput& stream) noexcept
285{
286 using std::swap;
287 swap(_storage, stream._storage);
288}
289
291{
292 // Check implementation storage parameters
293 [[maybe_unused]] ValidateAlignedStorage<sizeof(Impl), alignof(Impl), StorageSize, StorageAlign> _;
294 static_assert((StorageSize >= sizeof(Impl)), "StdError::StorageSize must be increased!");
295 static_assert(((StorageAlign % alignof(Impl)) == 0), "StdError::StorageAlign must be adjusted!");
296
297 // Create the implementation instance
298 new(&_storage)Impl();
299}
300
302{
303 // Delete the implementation instance
304 reinterpret_cast<Impl*>(&_storage)->~Impl();
305}
306
307void* StdError::stream() const noexcept { return impl().stream(); }
308bool StdError::IsValid() const noexcept { return impl().IsValid(); }
309size_t StdError::Write(const void* buffer, size_t size) { return impl().Write(buffer, size); }
310void StdError::Flush() { return impl().Flush(); }
311
312void StdError::swap(StdError& stream) noexcept
313{
314 using std::swap;
315 swap(_storage, stream._storage);
316}
317
318} // namespace CppCommon
Standard error stream.
Definition stream.h:128
size_t Write(const void *buffer, size_t size) override
Write a byte buffer into the stream.
Definition stream.cpp:309
void * stream() const noexcept
Get the native stream handler.
Definition stream.cpp:307
virtual ~StdError()
Definition stream.cpp:301
void Flush() override
Flush the stream.
Definition stream.cpp:310
friend void swap(StdError &stream1, StdError &stream2) noexcept
Definition stream.inl:21
bool IsValid() const noexcept
Is stream valid?
Definition stream.cpp:308
Standard input stream.
Definition stream.h:25
friend void swap(StdInput &stream1, StdInput &stream2) noexcept
Definition stream.inl:11
bool IsValid() const noexcept
Is stream valid?
Definition stream.cpp:253
virtual ~StdInput()
Definition stream.cpp:246
void * stream() const noexcept
Get the native stream handler.
Definition stream.cpp:252
size_t Read(void *buffer, size_t size) override
Read a bytes buffer from the stream.
Definition stream.cpp:254
Standard output stream.
Definition stream.h:76
virtual ~StdOutput()
Definition stream.cpp:273
void * stream() const noexcept
Get the native stream handler.
Definition stream.cpp:279
friend void swap(StdOutput &stream1, StdOutput &stream2) noexcept
Definition stream.inl:16
void Flush() override
Flush the stream.
Definition stream.cpp:282
size_t Write(const void *buffer, size_t size) override
Write a byte buffer into the stream.
Definition stream.cpp:281
bool IsValid() const noexcept
Is stream valid?
Definition stream.cpp:280
#define throwex
Throw extended exception macro.
Definition exceptions.h:23
Fatal abort execution definition.
C++ Common project definitions.
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition filecache.inl:23
Standard input/output/error stream definition.
Aligned storage validator definition.