]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/nowide/src/iostream.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / nowide / src / iostream.cpp
CommitLineData
f67539c2 1// Copyright (c) 2012 Artyom Beilis (Tonkikh)
1e59de90 2// Copyright (c) 2020-2021 Alexander Grund
f67539c2 3//
1e59de90
TL
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE or copy at
f67539c2 6// http://www.boost.org/LICENSE_1_0.txt)
1e59de90 7
f67539c2
TL
8#define BOOST_NOWIDE_SOURCE
9#include <boost/nowide/iostream.hpp>
10
11#ifndef BOOST_WINDOWS
12
13namespace boost {
14namespace nowide {
1e59de90 15 // LCOV_EXCL_START
f67539c2
TL
16 /// Avoid empty compilation unit warnings
17 /// \internal
18 BOOST_NOWIDE_DECL void dummy_exported_function()
19 {}
1e59de90 20 // LCOV_EXCL_STOP
f67539c2
TL
21} // namespace nowide
22} // namespace boost
23
24#else
25
1e59de90 26#include "console_buffer.hpp"
f67539c2 27#include <cassert>
f67539c2 28#include <iostream>
f67539c2
TL
29
30#ifndef NOMINMAX
31#define NOMINMAX
32#endif
f67539c2
TL
33#include <windows.h>
34
35namespace boost {
36namespace nowide {
37 namespace detail {
38
39 namespace {
40 bool is_atty_handle(HANDLE h)
41 {
1e59de90
TL
42 DWORD dummy;
43 return h && GetConsoleMode(h, &dummy) != FALSE;
f67539c2
TL
44 }
45 } // namespace
46
1e59de90 47 class console_output_buffer final : public console_output_buffer_base
f67539c2 48 {
1e59de90
TL
49 HANDLE handle_;
50
f67539c2 51 public:
1e59de90 52 explicit console_output_buffer(HANDLE handle) : handle_(handle)
f67539c2
TL
53 {}
54
55 protected:
1e59de90
TL
56 bool
57 do_write(const wchar_t* buffer, std::size_t num_chars_to_write, std::size_t& num_chars_written) override
f67539c2 58 {
f67539c2 59 DWORD size = 0;
1e59de90
TL
60 const bool result =
61 WriteConsoleW(handle_, buffer, static_cast<DWORD>(num_chars_to_write), &size, 0) != 0;
62 num_chars_written = size;
63 return result;
f67539c2 64 }
f67539c2
TL
65 };
66
1e59de90 67 class console_input_buffer final : public console_input_buffer_base
f67539c2 68 {
1e59de90
TL
69 HANDLE handle_;
70
f67539c2 71 public:
1e59de90 72 explicit console_input_buffer(HANDLE handle) : handle_(handle)
f67539c2
TL
73 {}
74
75 protected:
1e59de90 76 bool do_read(wchar_t* buffer, std::size_t num_chars_to_read, std::size_t& num_chars_read) override
20effc67 77 {
1e59de90
TL
78 DWORD size = 0;
79 const auto to_read_size = static_cast<DWORD>(num_chars_to_read);
80 const bool result = ReadConsoleW(handle_, buffer, to_read_size, &size, 0) != 0;
81 num_chars_read = size;
82 return result;
f67539c2 83 }
f67539c2
TL
84 };
85
1e59de90 86 winconsole_ostream::winconsole_ostream(const bool isBuffered, winconsole_ostream* tieStream) : std::ostream(0)
f67539c2 87 {
1e59de90
TL
88 HANDLE h;
89 if(isBuffered)
90 h = GetStdHandle(STD_OUTPUT_HANDLE);
91 else
92 h = GetStdHandle(STD_ERROR_HANDLE);
f67539c2
TL
93 if(is_atty_handle(h))
94 {
95 d.reset(new console_output_buffer(h));
96 std::ostream::rdbuf(d.get());
97 } else
98 {
1e59de90
TL
99 std::ostream::rdbuf(isBuffered ? std::cout.rdbuf() : std::cerr.rdbuf());
100 assert(rdbuf());
f67539c2
TL
101 }
102 if(tieStream)
1e59de90 103 {
f67539c2 104 tie(tieStream);
1e59de90
TL
105 setf(ios_base::unitbuf); // If tieStream is set, this is cerr -> set unbuffered
106 }
f67539c2
TL
107 }
108 winconsole_ostream::~winconsole_ostream()
109 {
110 try
111 {
112 flush();
113 } catch(...)
1e59de90 114 {} // LCOV_EXCL_LINE
f67539c2
TL
115 }
116
117 winconsole_istream::winconsole_istream(winconsole_ostream* tieStream) : std::istream(0)
118 {
119 HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
120 if(is_atty_handle(h))
121 {
122 d.reset(new console_input_buffer(h));
123 std::istream::rdbuf(d.get());
124 } else
125 {
126 std::istream::rdbuf(std::cin.rdbuf());
1e59de90 127 assert(rdbuf());
f67539c2
TL
128 }
129 if(tieStream)
130 tie(tieStream);
131 }
132
133 winconsole_istream::~winconsole_istream()
134 {}
135
136 } // namespace detail
137
1e59de90
TL
138 // Make sure those are initialized as early as possible
139#ifdef BOOST_MSVC
140#pragma warning(disable : 4073)
141#pragma init_seg(lib)
142#endif
143#ifdef BOOST_NOWIDE_HAS_INIT_PRIORITY
144#define BOOST_NOWIDE_INIT_PRIORITY __attribute__((init_priority(101)))
145#else
146#define BOOST_NOWIDE_INIT_PRIORITY
147#endif
148 detail::winconsole_ostream cout BOOST_NOWIDE_INIT_PRIORITY(true, nullptr);
149 detail::winconsole_istream cin BOOST_NOWIDE_INIT_PRIORITY(&cout);
150 detail::winconsole_ostream cerr BOOST_NOWIDE_INIT_PRIORITY(false, &cout);
151 detail::winconsole_ostream clog BOOST_NOWIDE_INIT_PRIORITY(false, nullptr);
f67539c2
TL
152} // namespace nowide
153} // namespace boost
154
155#endif