fix(monitor/ansi_converter): decode multibyte characters

This commit is contained in:
Peter Dragun
2023-06-23 09:32:13 +02:00
parent 96119acc8b
commit 57e188c2e3

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
import ctypes import ctypes
@ -62,12 +62,15 @@ class ANSIColorConverter(object):
self.decode_output = False self.decode_output = False
self.handle = GetStdHandle(STD_ERROR_HANDLE if self.output == sys.stderr else STD_OUTPUT_HANDLE) self.handle = GetStdHandle(STD_ERROR_HANDLE if self.output == sys.stderr else STD_OUTPUT_HANDLE)
self.matched = b'' self.matched = b''
self.decode_buffer = b''
self.force_color = force_color # always print ANSI for colors if true self.force_color = force_color # always print ANSI for colors if true
def _output_write(self, data): # type: (Union[str, bytes]) -> None def _output_write(self, data): # type: (Union[str, bytes]) -> None
try: try:
if self.decode_output: if self.decode_output:
data = self.decode_buffer + data # type: ignore
self.output.write(data.decode()) # type: ignore self.output.write(data.decode()) # type: ignore
self.decode_buffer = b''
else: else:
self.output.write(data) # type: ignore self.output.write(data) # type: ignore
except (IOError, OSError): except (IOError, OSError):
@ -79,8 +82,12 @@ class ANSIColorConverter(object):
# (garbage bytes, etc) # (garbage bytes, etc)
pass pass
except UnicodeDecodeError: except UnicodeDecodeError:
# In case of double byte Unicode characters display '?' self.decode_buffer += data # type: ignore
self.output.write('?') # type: ignore if len(self.decode_buffer) > 4:
# Multi-byte character contain up to 4 bytes and if buffer have more then 4 bytes
# and still can not decode it we can just ignore some bytes
self.output.write(self.decode_buffer.decode(errors='replace')) # type: ignore
self.decode_buffer = b''
def write(self, data): # type: ignore def write(self, data): # type: ignore
if isinstance(data, bytes): if isinstance(data, bytes):