Skip to content

Commit 32ea419

Browse files
authored
Implement til::u8u16 and til::u16u8 conversion functions (#4093)
This commit also switches ConptyConnection to consume til::u8u16 and removes the UTF8OutPipeReader. Closes #4092.
1 parent 1445380 commit 32ea419

24 files changed

+2245
-312
lines changed

OpenConsole.sln

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BDB237B6
269269
EndProject
270270
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "til.unit.tests", "src\til\ut_til\til.unit.tests.vcxproj", "{767268EE-174A-46FE-96F0-EEE698A1BBC9}"
271271
EndProject
272+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "U8U16Test", "src\tools\U8U16Test\U8U16Test.vcxproj", "{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}"
273+
EndProject
272274
Global
273275
GlobalSection(SolutionConfigurationPlatforms) = preSolution
274276
AuditMode|Any CPU = AuditMode|Any CPU
@@ -1374,6 +1376,26 @@ Global
13741376
{767268EE-174A-46FE-96F0-EEE698A1BBC9}.Release|x64.Build.0 = Release|x64
13751377
{767268EE-174A-46FE-96F0-EEE698A1BBC9}.Release|x86.ActiveCfg = Release|Win32
13761378
{767268EE-174A-46FE-96F0-EEE698A1BBC9}.Release|x86.Build.0 = Release|Win32
1379+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.AuditMode|Any CPU.ActiveCfg = Release|x64
1380+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.AuditMode|Any CPU.Build.0 = Release|x64
1381+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.AuditMode|ARM64.ActiveCfg = Release|x64
1382+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.AuditMode|ARM64.Build.0 = Release|x64
1383+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.AuditMode|x64.ActiveCfg = Release|x64
1384+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.AuditMode|x64.Build.0 = Release|x64
1385+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.AuditMode|x86.ActiveCfg = Release|Win32
1386+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.AuditMode|x86.Build.0 = Release|Win32
1387+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Debug|Any CPU.ActiveCfg = Debug|Win32
1388+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Debug|ARM64.ActiveCfg = Debug|Win32
1389+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Debug|x64.ActiveCfg = Debug|x64
1390+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Debug|x64.Build.0 = Debug|x64
1391+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Debug|x86.ActiveCfg = Debug|Win32
1392+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Debug|x86.Build.0 = Debug|Win32
1393+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|Any CPU.ActiveCfg = Release|Win32
1394+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|ARM64.ActiveCfg = Release|Win32
1395+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x64.ActiveCfg = Release|x64
1396+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x64.Build.0 = Release|x64
1397+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x86.ActiveCfg = Release|Win32
1398+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x86.Build.0 = Release|Win32
13771399
EndGlobalSection
13781400
GlobalSection(SolutionProperties) = preSolution
13791401
HideSolutionNode = FALSE
@@ -1444,6 +1466,7 @@ Global
14441466
{A021EDFF-45C8-4DC2-BEF7-36E1B3B8CFE8} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
14451467
{BDB237B6-1D1D-400F-84CC-40A58FA59C8E} = {59840756-302F-44DF-AA47-441A9D673202}
14461468
{767268EE-174A-46FE-96F0-EEE698A1BBC9} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
1469+
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1} = {A10C4720-DCA4-4640-9749-67F4314F527C}
14471470
EndGlobalSection
14481471
GlobalSection(ExtensibilityGlobals) = postSolution
14491472
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}

src/cascadia/TerminalConnection/ConptyConnection.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
#include "../../types/inc/Utils.hpp"
1717
#include "../../types/inc/Environment.hpp"
18-
#include "../../types/inc/UTF8OutPipeReader.hpp"
1918
#include "LibraryResources.h"
2019

2120
using namespace ::Microsoft::Console;
@@ -169,7 +168,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
169168
_commandline{ commandline },
170169
_startingDirectory{ startingDirectory },
171170
_startingTitle{ startingTitle },
172-
_guid{ initialGuid }
171+
_guid{ initialGuid },
172+
_u8State{},
173+
_u16Str{},
174+
_buffer{}
173175
{
174176
if (_guid == guid{})
175177
{
@@ -344,14 +346,27 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
344346

345347
DWORD ConptyConnection::_OutputThread()
346348
{
347-
UTF8OutPipeReader pipeReader{ _outPipe.get() };
348-
std::string_view strView{};
349-
350349
// process the data of the output pipe in a loop
351350
while (true)
352351
{
353-
const HRESULT result = pipeReader.Read(strView);
354-
if (FAILED(result) || result == S_FALSE)
352+
DWORD read{};
353+
354+
const auto readFail{ !ReadFile(_outPipe.get(), _buffer.data(), gsl::narrow_cast<DWORD>(_buffer.size()), &read, nullptr) };
355+
if (readFail) // reading failed (we must check this first, because read will also be 0.)
356+
{
357+
const auto lastError = GetLastError();
358+
if (lastError != ERROR_BROKEN_PIPE && !_isStateAtOrBeyond(ConnectionState::Closing))
359+
{
360+
// EXIT POINT
361+
_indicateExitWithStatus(HRESULT_FROM_WIN32(lastError)); // print a message
362+
_transitionToState(ConnectionState::Failed);
363+
return gsl::narrow_cast<DWORD>(HRESULT_FROM_WIN32(lastError));
364+
}
365+
// else we call convertUTF8ChunkToUTF16 with an empty string_view to convert possible remaining partials to U+FFFD
366+
}
367+
368+
const HRESULT result{ til::u8u16(std::string_view{ _buffer.data(), read }, _u16Str, _u8State) };
369+
if (FAILED(result))
355370
{
356371
if (_isStateAtOrBeyond(ConnectionState::Closing))
357372
{
@@ -362,10 +377,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
362377
// EXIT POINT
363378
_indicateExitWithStatus(result); // print a message
364379
_transitionToState(ConnectionState::Failed);
365-
return gsl::narrow_cast<DWORD>(-1);
380+
return gsl::narrow_cast<DWORD>(result);
366381
}
367382

368-
if (strView.empty())
383+
if (_u16Str.empty())
369384
{
370385
return 0;
371386
}
@@ -386,11 +401,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
386401
_recievedFirstByte = true;
387402
}
388403

389-
// Convert buffer to hstring
390-
auto hstr{ winrt::to_hstring(strView) };
391-
392404
// Pass the output to our registered event handlers
393-
_TerminalOutputHandlers(hstr);
405+
_TerminalOutputHandlers(_u16Str);
394406
}
395407

396408
return 0;

src/cascadia/TerminalConnection/ConptyConnection.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
5252
wil::unique_static_pseudoconsole_handle _hPC;
5353
wil::unique_threadpool_wait _clientExitWait;
5454

55+
til::u8state _u8State;
56+
std::wstring _u16Str;
57+
std::array<char, 4096> _buffer;
58+
5559
DWORD _OutputThread();
5660
};
5761
}

src/inc/til.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "til/at.h"
77
#include "til/some.h"
8+
#include "til/u8u16convert.h"
89

910
namespace til // Terminal Implementation Library. Also: "Today I Learned"
1011
{

0 commit comments

Comments
 (0)