mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-10-26 22:11:35 +00:00
terminal/sagas: fix handling multibyte unicode
Enable the stream option on the text decode for the stdout and uart stream handlers that pipe data to the terminal. This fixes improperly printing multibyte unicode characters that get split across multiple data packets. A new decode is added for each different stream in case both are used at the same time. Fixes: https://github.com/pybricks/support/issues/1743
This commit is contained in:
1 parent
a308303f07
commit
baaa9a7920
3 files changed
+18
-6
No files matched your search
+4
-1
@@ -6,8 +6,11 @@
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fixed Bluetooth firmware updates sometimes failing on macOS. ([support#1787])
|
- Fixed Bluetooth firmware updates sometimes failing on macOS. ([support#1787])
|
||||||
|
- Fixed multibyte unicode characters not printing correctly in terminal when
|
||||||
|
split across Bluetooth packets. ([support#1743])
|
||||||
|
|
||||||
[[support#1787]]: https://github.com/pybricks/support/issues/1787
|
[support#1743]: https://github.com/pybricks/support/issues/1743
|
||||||
|
[support#1787]: https://github.com/pybricks/support/issues/1787
|
||||||
|
|
||||||
## [2.3.0-beta.1] - 2023-11-24
|
## [2.3.0-beta.1] - 2023-11-24
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
// Copyright (c) 2020-2023 The Pybricks Authors
|
// Copyright (c) 2020-2024 The Pybricks Authors
|
||||||
|
|
||||||
import PushStream from 'zen-push';
|
import PushStream from 'zen-push';
|
||||||
import { AsyncSaga, delay } from '../../test';
|
import { AsyncSaga, delay } from '../../test';
|
||||||
@@ -86,6 +86,14 @@ describe('receiving stdout from hub', () => {
|
|||||||
|
|
||||||
await expect(saga.take()).resolves.toEqual(sendData(' '));
|
await expect(saga.take()).resolves.toEqual(sendData(' '));
|
||||||
|
|
||||||
|
// ensure that unicode characters are handled correctly when split
|
||||||
|
// across buffers
|
||||||
|
|
||||||
|
saga.put(didReceiveWriteStdout(new Uint8Array([0xe4]).buffer));
|
||||||
|
await expect(saga.take()).resolves.toEqual(sendData(''));
|
||||||
|
saga.put(didReceiveWriteStdout(new Uint8Array([0xb8, 0xad]).buffer));
|
||||||
|
await expect(saga.take()).resolves.toEqual(sendData('中'));
|
||||||
|
|
||||||
await saga.end();
|
await saga.end();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
// Copyright (c) 2020-2023 The Pybricks Authors
|
// Copyright (c) 2020-2024 The Pybricks Authors
|
||||||
|
|
||||||
import { AnyAction } from 'redux';
|
import { AnyAction } from 'redux';
|
||||||
import {
|
import {
|
||||||
@@ -39,7 +39,8 @@ import { receiveData, sendData } from './actions';
|
|||||||
export type TerminalSagaContext = { terminal: TerminalContextValue };
|
export type TerminalSagaContext = { terminal: TerminalContextValue };
|
||||||
|
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
const decoder = new TextDecoder();
|
const uartDecoder = new TextDecoder();
|
||||||
|
const stdoutDecoder = new TextDecoder();
|
||||||
|
|
||||||
function* receiveUartData(action: ReturnType<typeof didNotify>): Generator {
|
function* receiveUartData(action: ReturnType<typeof didNotify>): Generator {
|
||||||
const { runtime: hubState, useLegacyStdio } = yield* select(
|
const { runtime: hubState, useLegacyStdio } = yield* select(
|
||||||
@@ -56,14 +57,14 @@ function* receiveUartData(action: ReturnType<typeof didNotify>): Generator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const value = decoder.decode(action.value.buffer);
|
const value = uartDecoder.decode(action.value.buffer, { stream: true });
|
||||||
yield* put(sendData(value));
|
yield* put(sendData(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function* handleReceiveWriteStdout(
|
function* handleReceiveWriteStdout(
|
||||||
action: ReturnType<typeof didReceiveWriteStdout>,
|
action: ReturnType<typeof didReceiveWriteStdout>,
|
||||||
): Generator {
|
): Generator {
|
||||||
const value = decoder.decode(action.payload);
|
const value = stdoutDecoder.decode(action.payload, { stream: true });
|
||||||
yield* put(sendData(value));
|
yield* put(sendData(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user