ChannelStreams.cpp (4174B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "ChannelStreams.h" 5 6 7 namespace AppInstaller::CLI::Execution 8 { 9 using namespace VirtualTerminal; 10 11 size_t GetConsoleWidth() 12 { 13 CONSOLE_SCREEN_BUFFER_INFO consoleInfo{}; 14 if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) 15 { 16 return static_cast<size_t>(consoleInfo.dwSize.X); 17 } 18 else 19 { 20 return 120; 21 } 22 } 23 24 BaseStream::BaseStream(std::ostream& out, bool enabled, bool VTEnabled) : 25 m_out(out), m_enabled(enabled), m_VTEnabled(VTEnabled) {} 26 27 BaseStream& BaseStream::operator<<(std::ostream& (__cdecl* f)(std::ostream&)) 28 { 29 if (m_enabled) 30 { 31 f(m_out); 32 } 33 return *this; 34 } 35 36 BaseStream& BaseStream::operator<<(const Sequence& sequence) 37 { 38 if (m_enabled && m_VTEnabled) 39 { 40 m_VTUpdated = true; 41 m_out << sequence; 42 } 43 return *this; 44 } 45 46 BaseStream& BaseStream::operator<<(const ConstructedSequence& sequence) 47 { 48 if (m_enabled && m_VTEnabled) 49 { 50 m_VTUpdated = true; 51 m_out << sequence; 52 } 53 return *this; 54 } 55 56 void BaseStream::SetVTEnabled(bool enabled) 57 { 58 m_VTEnabled = enabled; 59 } 60 61 void BaseStream::RestoreDefault() 62 { 63 if (m_VTUpdated) 64 { 65 Write(TextFormat::Default, true); 66 } 67 } 68 69 void BaseStream::Disable() 70 { 71 m_enabled = false; 72 } 73 74 std::ostream& BaseStream::Get() 75 { 76 return m_out; 77 } 78 79 OutputStream::OutputStream(BaseStream& out, bool enabled, bool VTEnabled) : 80 m_out(out), 81 m_enabled(enabled), 82 m_VTEnabled(VTEnabled) 83 {} 84 85 void OutputStream::AddFormat(const Sequence& sequence) 86 { 87 m_format.Append(sequence); 88 } 89 90 void OutputStream::ClearFormat() 91 { 92 m_format.Clear(); 93 } 94 95 void OutputStream::ApplyFormat() 96 { 97 // Only apply format if m_applyFormatAtOne == 1 coming into this function. 98 if (m_applyFormatAtOne) 99 { 100 if (!--m_applyFormatAtOne) 101 { 102 m_out << m_format; 103 } 104 } 105 } 106 107 OutputStream& OutputStream::operator<<(std::ostream& (__cdecl* f)(std::ostream&)) 108 { 109 if (m_enabled) 110 { 111 m_out << f; 112 } 113 114 return *this; 115 } 116 117 OutputStream& OutputStream::operator<<(const Sequence& sequence) 118 { 119 if (m_enabled && m_VTEnabled) 120 { 121 // Apply format as normal to ensure that any previous format doesn't bleed through. 122 ApplyFormat(); 123 124 m_out << sequence; 125 126 // An incoming sequence will be valid for 1 "standard" output after this one. 127 // We set this to 2 to make that happen, because when it is 1, we will output 128 // the format for the current OutputStream. 129 m_applyFormatAtOne = 2; 130 } 131 132 return *this; 133 } 134 135 OutputStream& OutputStream::operator<<(const ConstructedSequence& sequence) 136 { 137 if (m_enabled && m_VTEnabled) 138 { 139 // Apply format as normal to ensure that any previous format doesn't bleed through. 140 ApplyFormat(); 141 142 m_out << sequence; 143 // An incoming sequence will be valid for 1 "standard" output after this one. 144 // We set this to 2 to make that happen, because when it is 1, we will output 145 // the format for the current OutputStream. 146 m_applyFormatAtOne = 2; 147 } 148 149 return *this; 150 } 151 152 OutputStream& OutputStream::operator<<(const std::filesystem::path& path) 153 { 154 if (m_enabled) 155 { 156 if (m_VTEnabled) 157 { 158 ApplyFormat(); 159 } 160 m_out << path.u8string(); 161 } 162 return *this; 163 164 } 165 }