12#include "internal.hpp"
31 template <
class _Elem,
class _Traits>
35 std::basic_ostream<_Elem, _Traits> &sp;
37 inline basic_ostreamfmt(_Inout_ std::basic_ostream<_Elem, _Traits> &stream) : sp(stream) {}
39 using pos_type =
typename _Traits::pos_type;
40 using off_type =
typename _Traits::off_type;
41 inline pos_type tellp() {
return sp.tellp(); }
44 inline bool good()
const noexcept {
return sp.good(); }
45 inline bool eof()
const noexcept {
return sp.eof(); }
46 inline bool fail()
const noexcept {
return sp.fail(); }
47 inline bool bad()
const noexcept {
return sp.bad(); }
51 sp.write(
reinterpret_cast<const _Elem*
>(data), size/
sizeof(_Elem));
59 sp.write(
reinterpret_cast<const _Elem*
>(&value),
sizeof(T)/
sizeof(_Elem));
65 size_t count = strlen(value);
66 if (count > UINT32_MAX)
67 throw std::invalid_argument(
"string too big");
68 sp.write(
static_cast<uint32_t
>(count));
69 sp.write(
reinterpret_cast<const _Elem*
>(value), (std::streamsize)count *
sizeof(
char)/
sizeof(_Elem));
75 size_t count = strlen(value);
76 if (count > UINT32_MAX)
77 throw std::invalid_argument(
"string too big");
78 sp.write(
static_cast<uint32_t
>(count));
80 for (
size_t i = 0; i < count; ++i)
83 sp.write(
reinterpret_cast<const _Elem*
>(value), (std::streamsize)count *
sizeof(
wchar_t)/
sizeof(_Elem));
100 template <
class _Elem2>
101 void vprintf(_In_z_ _Printf_format_string_
const _Elem2 *format, _In_opt_ locale_t locale, _In_ va_list arg)
103 std::basic_string<_Elem2> str;
104 vappendf(str, format, locale, arg);
105 sp.write(
reinterpret_cast<const _Elem*
>(str.c_str()), str.size() *
sizeof(_Elem2)/
sizeof(_Elem));
114 template <
class _Elem2>
115 void printf(_In_z_ _Printf_format_string_
const _Elem2 *format, _In_opt_ locale_t locale, ...)
118 va_start(arg, locale);
124 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ int16_t value) {
return write(value); }
125 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ int32_t value) {
return write(value); }
126 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ int64_t value) {
return write(value); }
127 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ uint8_t value) {
return write(value); }
128 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ uint16_t value) {
return write(value); }
129 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ uint32_t value) {
return write(value); }
130 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ uint64_t value) {
return write(value); }
131#if defined(_NATIVE_SIZE_T_DEFINED) && defined(_WIN64)
132 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_
size_t value) {
return write(value); }
134 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_
float value) {
return write(value); }
135 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_
double value) {
return write(value); }
136 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_
char value) {
return write(value); }
137#ifdef _NATIVE_WCHAR_T_DEFINED
138 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_
wchar_t value) {
return write(value); }
140 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_z_
const char* value) {
return write(value); }
141 inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_z_
const wchar_t* value) {
return write(value); }
144 using ostreamfmt = basic_ostreamfmt<char, std::char_traits<char>>;
145 using wostreamfmt = basic_ostreamfmt<wchar_t, std::char_traits<wchar_t>>;
150 template <
class _Elem,
class _Traits>
154 std::basic_istream<_Elem, _Traits> &sg;
156 inline basic_istreamfmt(_Inout_ std::basic_istream<_Elem, _Traits> &stream) : sg(stream) {}
158 using pos_type =
typename _Traits::pos_type;
159 using off_type =
typename _Traits::off_type;
160 inline pos_type tellg() {
return sg.tellg(); }
163 inline bool good()
const noexcept {
return sg.good(); }
164 inline bool eof()
const noexcept {
return sg.eof(); }
165 inline bool fail()
const noexcept {
return sg.fail(); }
166 inline bool bad()
const noexcept {
return sg.bad(); }
167 inline std::streamsize gcount()
const noexcept {
return sg.gcount(); }
171 sg.read(
reinterpret_cast<_Elem*
>(data), size/
sizeof(_Elem));
178 sg.read(
reinterpret_cast<_Elem*
>(&value),
sizeof(T)/
sizeof(_Elem));
184 template <
class _Traits = std::
char_traits<
char>,
class _Alloc = std::allocator<
char>>
191 sg.read(
reinterpret_cast<_Elem*
>(&value[0]), (std::streamsize)count *
sizeof(
char)/
sizeof(_Elem));
196 template <
class _Traits = std::
char_traits<
wchar_t>,
class _Alloc = std::allocator<
wchar_t>>
204 for (
size_t i = 0; i < count; ++i)
207 sg.read(
reinterpret_cast<_Elem*
>(&value[0]), (std::streamsize)count *
sizeof(
wchar_t)/
sizeof(_Elem));
213 inline uint8_t read_byte()
228#if defined(_NATIVE_SIZE_T_DEFINED) && defined(_WIN64)
234#ifdef _NATIVE_WCHAR_T_DEFINED
237 template <
class _Traits = std::
char_traits<
char>,
class _Alloc = std::allocator<
char>>
239 template <
class _Traits = std::
char_traits<
wchar_t>,
class _Alloc = std::allocator<
wchar_t>>
249 template <
class _Elem,
class _Traits>
265 template <
class _Elem,
class _Traits>
271 setg(
const_cast<_Elem*
>(data),
const_cast<_Elem*
>(data),
const_cast<_Elem*
>(data + size));
276 setg(other.eback(), other.gptr(), other.egptr());
281 if (
this != std::addressof(other))
282 std::basic_streambuf<_Elem, _Traits>::operator =(other);
291 virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
293 if (which & std::ios_base::in) {
296 case std::ios_base::beg: target = eback() +
static_cast<ptrdiff_t
>(off);
break;
297 case std::ios_base::cur: target = gptr() +
static_cast<ptrdiff_t
>(off);
break;
298 case std::ios_base::end: target = egptr() +
static_cast<ptrdiff_t
>(off);
break;
299 default:
throw std::invalid_argument(
"invalid seek reference");
301 if (eback() <= target && target <= egptr()) {
302 gbump(
static_cast<int>(target - gptr()));
303 return pos_type{ off_type{ target - eback() } };
306 return pos_type{ off_type{-1} };
309 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
311 if (which & std::ios_base::in) {
312 _Elem* target = eback() +
static_cast<size_t>(pos);
313 if (eback() <= target && target <= egptr()) {
314 gbump(
static_cast<int>(target - gptr()));
315 return pos_type{ off_type{ target - eback() } };
318 return pos_type{ off_type{-1} };
322 template <
class _Elem,
class _Traits>
328 std::basic_istream<_Elem, _Traits>(&m_buf)
343 template <
class _Elem,
class _Traits>
347 using guest_stream = std::basic_iostream<_Elem, _Traits>;
349 template<
typename _Iter>
350 basic_diagstreambuf(_In_
const _Iter first, _In_
const _Iter last) : m_streams(first, last) {}
360 virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
362 if (m_streams.empty())
363 return pos_type{ off_type{-1} };
364 auto r = pos_type{ off_type{-1} };
365 if ((which & std::ios_base::in)) {
366 m_streams[0]->seekg(off, way);
367 r = m_streams[0]->bad() ? pos_type{ off_type{-1} } : m_streams[0]->tellg();
368 for (
size_t i = 1, n = m_streams.size(); i < n; ++i) {
369 m_streams[i]->seekg(off, way);
370 if (m_streams[i]->bad())
371 r = pos_type{ off_type{-1} };
374 if ((which & std::ios_base::out)) {
375 m_streams[0]->seekp(off, way);
376 r = m_streams[0]->bad() ? pos_type{ off_type{-1} } : m_streams[0]->tellp();
377 for (
size_t i = 1, n = m_streams.size(); i < n; ++i) {
378 m_streams[i]->seekp(off, way);
379 if (m_streams[i]->bad())
380 r = pos_type{ off_type{-1} };
386 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
388 return seekoff(pos, std::ios_base::beg, which);
391 virtual int_type underflow()
393 int_type eof = _Traits::eof();
394 if (m_streams.empty())
397 m_streams[0]->read(&data, 1);
398 int_type r = m_streams[0]->gcount() == 1 ? _Traits::to_int_type(data) : eof;
399 for (
size_t i = 1, n = m_streams.size(); i < n; ++i) {
400 m_streams[i]->read(&data, 1);
401 int_type temp_r = m_streams[i]->gcount() == 1 ? _Traits::to_int_type(data) : eof;
408 virtual int_type overflow(int_type ch = _Traits::eof())
410 if (_Traits::not_eof(ch)) {
411 _Elem data = _Traits::to_char_type(ch);
413 for (
size_t i = 0, n = m_streams.size(); i < n; ++i) {
414 m_streams[i]->write(&data, 1);
415 good &= m_streams[i]->good();
417 return good ? 0 : _Traits::eof();
425 for (
size_t i = 0, n = m_streams.size(); i < n; ++i)
426 if (m_streams[i]->sync() < 0)
432 std::vector<guest_stream*> m_streams;
441 template <
class _Elem,
class _Traits>
445 using guest_stream = std::basic_iostream<_Elem, _Traits>;
447 template<
typename _Iter>
450 std::basic_iostream<_Elem, _Traits>(&m_buf)
453 basic_diagstream(_In_reads_(count) guest_stream*
const* streams, _In_
size_t count) :
469 inline FILE* filebuf_fhandle(_In_ std::filebuf* rb)
474 inline FILE* filebuf_fhandle(_In_ std::wfilebuf* rb)
476 return (*rb).*get(getter<FILE*, std::wfilebuf>());
484 template <
class _Elem,
class _Traits>
488 using _Mybase = std::basic_fstream<_Elem, _Traits>;
490 using time_point = std::chrono::time_point<std::chrono::file_clock>;
492 using time_point = std::chrono::time_point<std::chrono::system_clock>;
498 _In_z_
const char* file_name,
499 _In_ ios_base::openmode mode = ios_base::in | ios_base::out,
500 _In_
int prot = ios_base::_Default_open_prot) : _Mybase(file_name, mode, prot) {}
503 _In_z_
const wchar_t* file_name,
504 _In_ ios_base::openmode mode = ios_base::in | ios_base::out,
505 _In_
int prot = ios_base::_Default_open_prot) : _Mybase(file_name, mode, prot) {}
507 template<
class _Elem2,
class _Traits2,
class _Ax>
509 _In_
const std::basic_string<_Elem2, _Traits2, _Ax>& str,
510 _In_ ios_base::openmode mode = ios_base::in | ios_base::out,
511 _In_
int prot = ios_base::_Default_open_prot) :
basic_fstream(str.c_str(), mode, prot) {}
523 auto h = os_fhandle();
525 if (h == INVALID_HANDLE_VALUE)
526 throw std::runtime_error(
"invalid handle");
529 pos_lo =
static_cast<LONG
>(pos & 0xffffffff),
530 pos_hi =
static_cast<LONG
>((pos >> 32) & 0xffffffff);
531 if (SetFilePointer(h, pos_lo, &pos_hi, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
532 throw std::runtime_error(
"failed to seek");
533 if (!SetEndOfFile(h))
534 throw std::runtime_error(
"failed to truncate");
547 auto h = os_fhandle();
549 if (h == INVALID_HANDLE_VALUE)
550 throw std::runtime_error(
"invalid handle");
552 if (!GetFileTime(h, NULL, NULL, &ft))
553 throw std::runtime_error(
"failed to get mtime");
555 return time_point(time_point::duration(((
static_cast<int64_t
>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime)));
558 return time_point(time_point::duration(((
static_cast<int64_t
>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) - 116444736000000000ll));
567 HANDLE os_fhandle()
const
569 FILE* f = filebuf_fhandle(rdbuf());
571 return INVALID_HANDLE_VALUE;
575 return INVALID_HANDLE_VALUE;
577 return (HANDLE)_get_osfhandle(fd);
584 using fstream = basic_fstream<char, std::char_traits<char>>;
585 using wfstream = basic_fstream<wchar_t, std::char_traits<wchar_t>>;
590 template <
class _Elem,
class _Traits,
class _Alloc>
593 using _Mybase = std::basic_stringstream<_Elem, _Traits, _Alloc>;
594 using _Mystr = std::basic_string<_Elem, _Traits, _Alloc>;
598 explicit basic_stringstream(_In_
const _Mystr& str, _In_ std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : _Mybase(str, mode) {}
609 explicit basic_stringstream(_In_z_
const T* filename, _In_ std::ios_base::openmode mode = std::ios_base::in, _In_
int prot = std::ios_base::_Default_open_prot) :
610 _Mybase(std::ios_base::in | std::ios_base::out | (mode & std::ios_base::binary | std::ios_base::app))
612 std::basic_ifstream<_Elem, _Traits> input(filename, mode & ~(std::ios_base::ate | std::ios_base::app), prot);
613 input.seekg(0, input.end);
614 auto size = input.tellg();
616 throw std::runtime_error(
"file too big to fit into memory");
617 str().reserve(
static_cast<size_t>(size));
621 input.read(buf, _countof(buf));
622 write(buf, input.gcount());
623 }
while (!input.eof());
624 if (!(mode & (std::ios_base::ate | std::ios_base::app)))
635 template <
class _Elem2,
class _Traits2 = std::
char_traits<_Elem2>,
class _Alloc2 = std::allocator<_Elem2>>
636 explicit basic_stringstream(_In_
const std::basic_string<_Elem2, _Traits2, _Alloc2>& filename, _In_ std::ios_base::openmode mode = std::ios_base::in, _In_
int prot = std::ios_base::_Default_open_prot) :
648 void save(_In_z_
const T* filename, _In_ std::ios_base::openmode mode = std::ios_base::out, _In_
int prot = std::ios_base::_Default_open_prot)
650 std::basic_ofstream<_Elem, _Traits> output(filename, mode, prot);
651 auto origin = tellg();
656 read(buf, _countof(buf));
657 output.write(buf, gcount());
662 template <
class _Elem2,
class _Traits2 = std::
char_traits<T>,
class _Alloc2 = std::allocator<T>>
663 void save(_In_
const std::basic_string<_Elem2, _Traits2, _Alloc2>& filename, _In_ std::ios_base::openmode mode = std::ios_base::out, _In_
int prot = std::ios_base::_Default_open_prot)
665 save(filename.data(), mode, prot);
669 using stringstream = basic_stringstream<char, std::char_traits<char>, std::allocator<char>>;
670 using wstringstream = basic_stringstream<wchar_t, std::char_traits<wchar_t>, std::allocator<char>>;
Diagnostic input/output stream.
Definition ios.hpp:443
Diagnostic input stream buffer.
Definition ios.hpp:345
File stream with additional std::filesystem features.
Definition ios.hpp:486
time_point mtime() const
Returns file modification time.
Definition ios.hpp:545
void truncate()
Sets end of file at current put position.
Definition ios.hpp:520
Binary stream reader/writer.
Definition ios.hpp:251
Binary stream reader.
Definition ios.hpp:152
Binary stream writer.
Definition ios.hpp:33
void vprintf(const _Elem2 *format, locale_t locale, va_list arg)
Formats string using printf() and write it to stream.
Definition ios.hpp:101
void printf(const _Elem2 *format, locale_t locale,...)
Formats string using printf() and write it to stream.
Definition ios.hpp:115
Shared-memory string stream buffer.
Definition ios.hpp:267
String stream.
Definition ios.hpp:591
basic_stringstream(const T *filename, std::ios_base::openmode mode=std::ios_base::in, int prot=std::ios_base::_Default_open_prot)
Initializes stream with content from file.
Definition ios.hpp:609
void save(const T *filename, std::ios_base::openmode mode=std::ios_base::out, int prot=std::ios_base::_Default_open_prot)
Saves stream content to a file.
Definition ios.hpp:648
basic_stringstream(const std::basic_string< _Elem2, _Traits2, _Alloc2 > &filename, std::ios_base::openmode mode=std::ios_base::in, int prot=std::ios_base::_Default_open_prot)
Initializes stream with content from file.
Definition ios.hpp:636
Helper template to allow access to internal std C++ private members.
Definition internal.hpp:30
Helper template to allow access to internal std C++ private members.
Definition internal.hpp:18