diff options
Diffstat (limited to 'test/API/driver/kwsys/ConsoleBuf.hxx.in')
-rw-r--r-- | test/API/driver/kwsys/ConsoleBuf.hxx.in | 398 |
1 files changed, 0 insertions, 398 deletions
diff --git a/test/API/driver/kwsys/ConsoleBuf.hxx.in b/test/API/driver/kwsys/ConsoleBuf.hxx.in deleted file mode 100644 index 49dbdf7..0000000 --- a/test/API/driver/kwsys/ConsoleBuf.hxx.in +++ /dev/null @@ -1,398 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_ConsoleBuf_hxx -#define @KWSYS_NAMESPACE@_ConsoleBuf_hxx - -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <@KWSYS_NAMESPACE@/Encoding.hxx> - -#include <cstring> -#include <iostream> -#include <sstream> -#include <stdexcept> -#include <streambuf> -#include <string> - -#if defined(_WIN32) -# include <windows.h> -# if __cplusplus >= 201103L -# include <system_error> -# endif -#endif - -namespace @KWSYS_NAMESPACE@ { -#if defined(_WIN32) - -template <class CharT, class Traits = std::char_traits<CharT> > -class BasicConsoleBuf : public std::basic_streambuf<CharT, Traits> -{ -public: - typedef typename Traits::int_type int_type; - typedef typename Traits::char_type char_type; - - class Manager - { - public: - Manager(std::basic_ios<CharT, Traits>& ios, const bool err = false) - : m_consolebuf(0) - { - m_ios = &ios; - try { - m_consolebuf = new BasicConsoleBuf<CharT, Traits>(err); - m_streambuf = m_ios->rdbuf(m_consolebuf); - } catch (const std::runtime_error& ex) { - std::cerr << "Failed to create ConsoleBuf!" << std::endl - << ex.what() << std::endl; - }; - } - - BasicConsoleBuf<CharT, Traits>* GetConsoleBuf() { return m_consolebuf; } - - void SetUTF8Pipes() - { - if (m_consolebuf) { - m_consolebuf->input_pipe_codepage = CP_UTF8; - m_consolebuf->output_pipe_codepage = CP_UTF8; - m_consolebuf->activateCodepageChange(); - } - } - - ~Manager() - { - if (m_consolebuf) { - delete m_consolebuf; - m_ios->rdbuf(m_streambuf); - } - } - - private: - std::basic_ios<CharT, Traits>* m_ios; - std::basic_streambuf<CharT, Traits>* m_streambuf; - BasicConsoleBuf<CharT, Traits>* m_consolebuf; - }; - - BasicConsoleBuf(const bool err = false) - : flush_on_newline(true) - , input_pipe_codepage(0) - , output_pipe_codepage(0) - , input_file_codepage(CP_UTF8) - , output_file_codepage(CP_UTF8) - , m_consolesCodepage(0) - { - m_hInput = ::GetStdHandle(STD_INPUT_HANDLE); - checkHandle(true, "STD_INPUT_HANDLE"); - if (!setActiveInputCodepage()) { - throw std::runtime_error("setActiveInputCodepage failed!"); - } - m_hOutput = err ? ::GetStdHandle(STD_ERROR_HANDLE) - : ::GetStdHandle(STD_OUTPUT_HANDLE); - checkHandle(false, err ? "STD_ERROR_HANDLE" : "STD_OUTPUT_HANDLE"); - if (!setActiveOutputCodepage()) { - throw std::runtime_error("setActiveOutputCodepage failed!"); - } - _setg(); - _setp(); - } - - ~BasicConsoleBuf() throw() { sync(); } - - bool activateCodepageChange() - { - return setActiveInputCodepage() && setActiveOutputCodepage(); - } - -protected: - virtual int sync() - { - bool success = true; - if (m_hInput && m_isConsoleInput && - ::FlushConsoleInputBuffer(m_hInput) == 0) { - success = false; - } - if (m_hOutput && !m_obuffer.empty()) { - const std::wstring wbuffer = getBuffer(m_obuffer); - if (m_isConsoleOutput) { - DWORD charsWritten; - success = - ::WriteConsoleW(m_hOutput, wbuffer.c_str(), (DWORD)wbuffer.size(), - &charsWritten, nullptr) == 0 - ? false - : true; - } else { - DWORD bytesWritten; - std::string buffer; - success = encodeOutputBuffer(wbuffer, buffer); - if (success) { - success = - ::WriteFile(m_hOutput, buffer.c_str(), (DWORD)buffer.size(), - &bytesWritten, nullptr) == 0 - ? false - : true; - } - } - } - m_ibuffer.clear(); - m_obuffer.clear(); - _setg(); - _setp(); - return success ? 0 : -1; - } - - virtual int_type underflow() - { - if (this->gptr() >= this->egptr()) { - if (!m_hInput) { - _setg(true); - return Traits::eof(); - } - if (m_isConsoleInput) { - // ReadConsole doesn't tell if there's more input available - // don't support reading more characters than this - wchar_t wbuffer[8192]; - DWORD charsRead; - if (ReadConsoleW(m_hInput, wbuffer, - (sizeof(wbuffer) / sizeof(wbuffer[0])), &charsRead, - nullptr) == 0 || - charsRead == 0) { - _setg(true); - return Traits::eof(); - } - setBuffer(std::wstring(wbuffer, charsRead), m_ibuffer); - } else { - std::wstring wbuffer; - std::string strbuffer; - DWORD bytesRead; - LARGE_INTEGER size; - if (GetFileSizeEx(m_hInput, &size) == 0) { - _setg(true); - return Traits::eof(); - } - char* buffer = new char[size.LowPart]; - while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, nullptr) == - 0) { - if (GetLastError() == ERROR_MORE_DATA) { - strbuffer += std::string(buffer, bytesRead); - continue; - } - _setg(true); - delete[] buffer; - return Traits::eof(); - } - if (bytesRead > 0) { - strbuffer += std::string(buffer, bytesRead); - } - delete[] buffer; - if (!decodeInputBuffer(strbuffer, wbuffer)) { - _setg(true); - return Traits::eof(); - } - setBuffer(wbuffer, m_ibuffer); - } - _setg(); - } - return Traits::to_int_type(*this->gptr()); - } - - virtual int_type overflow(int_type ch = Traits::eof()) - { - if (!Traits::eq_int_type(ch, Traits::eof())) { - char_type chr = Traits::to_char_type(ch); - m_obuffer += chr; - if ((flush_on_newline && Traits::eq(chr, '\n')) || - Traits::eq_int_type(ch, 0x00)) { - sync(); - } - return ch; - } - sync(); - return Traits::eof(); - } - -public: - bool flush_on_newline; - UINT input_pipe_codepage; - UINT output_pipe_codepage; - UINT input_file_codepage; - UINT output_file_codepage; - -private: - HANDLE m_hInput; - HANDLE m_hOutput; - std::basic_string<char_type> m_ibuffer; - std::basic_string<char_type> m_obuffer; - bool m_isConsoleInput; - bool m_isConsoleOutput; - UINT m_activeInputCodepage; - UINT m_activeOutputCodepage; - UINT m_consolesCodepage; - void checkHandle(bool input, std::string handleName) - { - if ((input && m_hInput == INVALID_HANDLE_VALUE) || - (!input && m_hOutput == INVALID_HANDLE_VALUE)) { - std::string errmsg = - "GetStdHandle(" + handleName + ") returned INVALID_HANDLE_VALUE"; -# if __cplusplus >= 201103L - throw std::system_error(::GetLastError(), std::system_category(), - errmsg); -# else - throw std::runtime_error(errmsg); -# endif - } - } - UINT getConsolesCodepage() - { - if (!m_consolesCodepage) { - m_consolesCodepage = GetConsoleCP(); - if (!m_consolesCodepage) { - m_consolesCodepage = GetACP(); - } - } - return m_consolesCodepage; - } - bool setActiveInputCodepage() - { - m_isConsoleInput = false; - switch (GetFileType(m_hInput)) { - case FILE_TYPE_DISK: - m_activeInputCodepage = input_file_codepage; - break; - case FILE_TYPE_CHAR: - // Check for actual console. - DWORD consoleMode; - m_isConsoleInput = - GetConsoleMode(m_hInput, &consoleMode) == 0 ? false : true; - if (m_isConsoleInput) { - break; - } - @KWSYS_NAMESPACE@_FALLTHROUGH; - case FILE_TYPE_PIPE: - m_activeInputCodepage = input_pipe_codepage; - break; - default: - return false; - } - if (!m_isConsoleInput && m_activeInputCodepage == 0) { - m_activeInputCodepage = getConsolesCodepage(); - } - return true; - } - bool setActiveOutputCodepage() - { - m_isConsoleOutput = false; - switch (GetFileType(m_hOutput)) { - case FILE_TYPE_DISK: - m_activeOutputCodepage = output_file_codepage; - break; - case FILE_TYPE_CHAR: - // Check for actual console. - DWORD consoleMode; - m_isConsoleOutput = - GetConsoleMode(m_hOutput, &consoleMode) == 0 ? false : true; - if (m_isConsoleOutput) { - break; - } - @KWSYS_NAMESPACE@_FALLTHROUGH; - case FILE_TYPE_PIPE: - m_activeOutputCodepage = output_pipe_codepage; - break; - default: - return false; - } - if (!m_isConsoleOutput && m_activeOutputCodepage == 0) { - m_activeOutputCodepage = getConsolesCodepage(); - } - return true; - } - void _setg(bool empty = false) - { - if (!empty) { - this->setg((char_type*)m_ibuffer.data(), (char_type*)m_ibuffer.data(), - (char_type*)m_ibuffer.data() + m_ibuffer.size()); - } else { - this->setg((char_type*)m_ibuffer.data(), - (char_type*)m_ibuffer.data() + m_ibuffer.size(), - (char_type*)m_ibuffer.data() + m_ibuffer.size()); - } - } - void _setp() - { - this->setp((char_type*)m_obuffer.data(), - (char_type*)m_obuffer.data() + m_obuffer.size()); - } - bool encodeOutputBuffer(const std::wstring wbuffer, std::string& buffer) - { - if (wbuffer.size() == 0) { - buffer = std::string(); - return true; - } - const int length = - WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), nullptr, 0, nullptr, nullptr); - char* buf = new char[length]; - const bool success = - WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), buf, length, nullptr, - nullptr) > 0 - ? true - : false; - buffer = std::string(buf, length); - delete[] buf; - return success; - } - bool decodeInputBuffer(const std::string buffer, std::wstring& wbuffer) - { - size_t length = buffer.length(); - if (length == 0) { - wbuffer = std::wstring(); - return true; - } - int actualCodepage = m_activeInputCodepage; - const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) }; - const char* data = buffer.data(); - const size_t BOMsize = sizeof(BOM_UTF8); - if (length >= BOMsize && std::memcmp(data, BOM_UTF8, BOMsize) == 0) { - // PowerShell uses UTF-8 with BOM for pipes - actualCodepage = CP_UTF8; - data += BOMsize; - length -= BOMsize; - } - const size_t wlength = static_cast<size_t>(MultiByteToWideChar( - actualCodepage, 0, data, static_cast<int>(length), nullptr, 0)); - wchar_t* wbuf = new wchar_t[wlength]; - const bool success = - MultiByteToWideChar(actualCodepage, 0, data, static_cast<int>(length), - wbuf, static_cast<int>(wlength)) > 0 - ? true - : false; - wbuffer = std::wstring(wbuf, wlength); - delete[] wbuf; - return success; - } - std::wstring getBuffer(const std::basic_string<char> buffer) - { - return Encoding::ToWide(buffer); - } - std::wstring getBuffer(const std::basic_string<wchar_t> buffer) - { - return buffer; - } - void setBuffer(const std::wstring wbuffer, std::basic_string<char>& target) - { - target = Encoding::ToNarrow(wbuffer); - } - void setBuffer(const std::wstring wbuffer, - std::basic_string<wchar_t>& target) - { - target = wbuffer; - } - -}; // BasicConsoleBuf class - -typedef BasicConsoleBuf<char> ConsoleBuf; -typedef BasicConsoleBuf<wchar_t> WConsoleBuf; - -#endif -} // KWSYS_NAMESPACE - -#endif |