From 34f05feae4c1646c251748d63a6f88c5b0f4293d Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 24 Jul 2023 11:46:26 +0200 Subject: [PATCH] ios: extend and update Signed-off-by: Simon Rozman --- include/stdex/ios.hpp | 77 ++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/include/stdex/ios.hpp b/include/stdex/ios.hpp index 29326f804..88e2fb6a5 100644 --- a/include/stdex/ios.hpp +++ b/include/stdex/ios.hpp @@ -82,6 +82,11 @@ namespace stdex return *this; } + inline basic_ostreamfmt<_Elem, _Traits>& write_byte(_In_ uint8_t value) + { + return write(value); + } + /// /// Formats string using `printf()` and write it to stream. /// @@ -120,7 +125,7 @@ namespace stdex inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ uint16_t value) { return write(value); } inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ uint32_t value) { return write(value); } inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ uint64_t value) { return write(value); } -#ifdef _NATIVE_SIZE_T_DEFINED +#if defined(_NATIVE_SIZE_T_DEFINED) && defined(_WIN64) inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ size_t value) { return write(value); } #endif inline basic_ostreamfmt<_Elem, _Traits>& operator <<(_In_ float value) { return write(value); } @@ -202,6 +207,13 @@ namespace stdex return *this; } + inline uint8_t read_byte() + { + uint8_t value; + read(value); + return value; + } + inline basic_istreamfmt<_Elem, _Traits>& operator >>(_Out_ int8_t& value) { return read(value); } inline basic_istreamfmt<_Elem, _Traits>& operator >>(_Out_ int16_t& value) { return read(value); } inline basic_istreamfmt<_Elem, _Traits>& operator >>(_Out_ int32_t& value) { return read(value); } @@ -210,7 +222,7 @@ namespace stdex inline basic_istreamfmt<_Elem, _Traits>& operator >>(_Out_ uint16_t& value) { return read(value); } inline basic_istreamfmt<_Elem, _Traits>& operator >>(_Out_ uint32_t& value) { return read(value); } inline basic_istreamfmt<_Elem, _Traits>& operator >>(_Out_ uint64_t& value) { return read(value); } -#ifdef _NATIVE_SIZE_T_DEFINED +#if defined(_NATIVE_SIZE_T_DEFINED) && defined(_WIN64) inline basic_istreamfmt<_Elem, _Traits>& operator >>(_Out_ size_t& value) { return read(value); } #endif inline basic_istreamfmt<_Elem, _Traits>& operator >>(_Out_ float& value) { return read(value); } @@ -278,9 +290,9 @@ namespace stdex if (which & std::ios_base::in) { _Elem* target; switch (way) { - case std::ios_base::beg: target = eback() + off; break; - case std::ios_base::cur: target = gptr() + off; break; - case std::ios_base::end: target = egptr() + off; break; + case std::ios_base::beg: target = eback() + static_cast(off); break; + case std::ios_base::cur: target = gptr() + static_cast(off); break; + case std::ios_base::end: target = egptr() + static_cast(off); break; default: throw std::invalid_argument("invalid seek reference"); } if (eback() <= target && target <= egptr()) { @@ -295,7 +307,7 @@ namespace stdex { // change to specified position, according to mode if (which & std::ios_base::in) { - _Elem* target = eback() + pos; + _Elem* target = eback() + static_cast(pos); if (eback() <= target && target <= egptr()) { gbump(static_cast(target - gptr())); return pos_type{ off_type{ target - eback() } }; @@ -346,6 +358,11 @@ namespace stdex { public: using _Mybase = std::basic_fstream<_Elem, _Traits>; +#if _HAS_CXX20 + using time_point = std::chrono::time_point; +#else + using time_point = std::chrono::time_point; +#endif basic_fstream() {} @@ -392,18 +409,12 @@ namespace stdex #endif } -#if _HAS_CXX20 - using time_type = std::chrono::time_point; -#else - using time_type = std::chrono::time_point; -#endif - /// /// Returns file modification time /// /// \returns File modification time /// - time_type mtime() const + time_point mtime() const { auto h = os_fhandle(); #ifdef _WIN32 @@ -413,10 +424,10 @@ namespace stdex if (!GetFileTime(h, NULL, NULL, &ft)) throw std::runtime_error("failed to get mtime"); #if _HAS_CXX20 - return time_type(time_type::duration(((static_cast(ft.dwHighDateTime) << 32) | ft.dwLowDateTime))); + return time_point(time_point::duration(((static_cast(ft.dwHighDateTime) << 32) | ft.dwLowDateTime))); #else // Adjust epoch to std::chrono::time_point/time_t. - return time_type(time_type::duration(((static_cast(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) - 116444736000000000ll)); + return time_point(time_point::duration(((static_cast(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) - 116444736000000000ll)); #endif #else #error Implement! @@ -468,14 +479,14 @@ namespace stdex /// template 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) : - _Mybase(std::ios_base::in | std::ios_base::out | (mode & std::ios_base::bin | std::ios_base::app)) + _Mybase(std::ios_base::in | std::ios_base::out | (mode & std::ios_base::binary | std::ios_base::app)) { std::basic_ifstream<_Elem, _Traits> input(filename, mode & ~(std::ios_base::ate | std::ios_base::app), prot); input.seekg(0, input.end); auto size = input.tellg(); if (size > SIZE_MAX) throw std::runtime_error("file too big to fit into memory"); - str.reserve(static_cast(size)); + str().reserve(static_cast(size)); input.seekg(0); do { _Elem buf[0x1000]; @@ -493,10 +504,38 @@ namespace stdex /// \param[in] mode Mode flags to open file. The std::stringstream returned is always opened as in|out. /// \param[in] prot Protection flags to open file /// - template - explicit basic_stringstream(_In_ const std::basic_string& filename, _In_ std::ios_base::openmode mode = std::ios_base::in, _In_ int prot = std::ios_base::_Default_open_prot) : + template , class _Alloc2 = std::allocator<_Elem2>> + 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) : basic_stringstream(filename.c_str(), mode, prot) {} + + /// + /// Saves stream content to a file. + /// + /// \param[in] filename File name + /// \param[in] mode Mode flags to open file + /// \param[in] prot Protection flags to open file + /// + template + 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) + { + std::basic_ofstream<_Elem, _Traits> output(filename, mode, prot); + auto origin = tellg(); + seekg(0, end); + auto size = tellg(); + do { + _Elem buf[0x1000]; + read(buf, _countof(buf)); + output.write(buf, gcount()); + } while (!eof()); + seekg(origin); + } + + template , class _Alloc2 = std::allocator> + 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) + { + save(filename.data(), mode, prot); + } }; using stringstream = basic_stringstream, std::allocator>;