Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // This is workaround of console unicode input/output from https://alfps.wordpress.com/2011/12/08/unicode-part-2-utf-8-stream-mode/
- #include "stdafx.h"
- #include "stream_fixer.h"
- typedef ptrdiff_t Size;
- bool throwX(string const& s) { throw runtime_error(s); }
- bool hopefully(bool v) { return v; }
- class DirectInputBuffer
- : public std::basic_streambuf< wchar_t >
- {
- private:
- wstring buffer_;
- Size bufferSize() const { return buffer_.size(); }
- wchar_t* pBufferStart() { return &buffer_[0]; }
- wchar_t* pBufferEnd() { return pBufferStart() + bufferSize(); }
- wchar_t* pStart() const { return eback(); }
- wchar_t* pCurrent() const { return gptr(); }
- wchar_t* pEnd() const { return egptr(); }
- static HANDLE inputHandle()
- {
- static HANDLE const handle = GetStdHandle(STD_INPUT_HANDLE);
- return handle;
- }
- public:
- typedef std::basic_streambuf< wchar_t > Base;
- typedef Base::traits_type Traits;
- DirectInputBuffer(Base const& anOriginalBuffer)
- : Base(anOriginalBuffer) // Copies buffer read area pointers.
- , buffer_(256, L'#')
- {}
- protected:
- virtual streamsize xsgetn(wchar_t* const pBuffer, streamsize const n)
- {
- wchar_t const ctrlZ = wchar_t(1 + ('Z' - 'A'));
- DWORD nCharactersRead = 0;
- bool const readSucceeded = !!ReadConsole(
- inputHandle(), pBuffer, static_cast< DWORD >(n), &nCharactersRead, nullptr
- );
- if (readSucceeded)
- {
- wchar_t const* const pCleanEnd =
- remove(pBuffer, pBuffer + nCharactersRead, L'\r');
- nCharactersRead = (DWORD)(pCleanEnd - pBuffer);
- bool const isInteractiveEOF =
- (nCharactersRead == 2 && pBuffer[0] == ctrlZ && pBuffer[1] == '\n');
- return (isInteractiveEOF ? 0 : static_cast< streamsize >(nCharactersRead));
- }
- return 0;
- }
- virtual int_type underflow()
- {
- // Try to get some more input (maximum a line).
- if (pCurrent() == 0 || pCurrent() >= pEnd())
- {
- streamsize const nCharactersRead =
- xsgetn(pBufferStart(), bufferSize());
- if (nCharactersRead > 0)
- {
- setg(
- pBufferStart(), // Reading area start
- pBufferStart(), // Reading area current
- pBufferStart() + nCharactersRead // Reading area end
- );
- }
- }
- if (pCurrent() == 0 || pCurrent() >= pEnd())
- {
- return Traits::eof();
- }
- return Traits::to_int_type(*pCurrent());
- }
- };
- void setUtf8Mode(FILE* f, char const name[])
- {
- int const newMode = _setmode(_fileno(f), _O_U8TEXT);
- hopefully(newMode != -1)
- || throwX(string() + "setmode failed for " + name);
- }
- bool inputIsFromConsole()
- {
- static HANDLE const inputHandle = GetStdHandle(STD_INPUT_HANDLE);
- DWORD consoleMode;
- return !!GetConsoleMode(inputHandle, &consoleMode);
- }
- void FixIOStream()
- {
- if (inputIsFromConsole())
- {
- static DirectInputBuffer buffer(*wcin.rdbuf());
- wcin.rdbuf(&buffer);
- }
- setUtf8Mode(stdin, "stdin");
- setUtf8Mode(stdout, "stdout");
- }
- wstring lineFrom(wistream& stream)
- {
- wstring result;
- getline(stream, result);
- hopefully(!stream.fail())
- || throwX("lineFrom: getline failed");
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement