Skip to content

Commit 2563ad3

Browse files
committed
Use more reliable, external UTF-8 sequencer
This is broken due to the Sequencer class not properly handling byte sequences.
1 parent f02dd30 commit 2563ad3

File tree

2 files changed

+16
-29
lines changed

2 files changed

+16
-29
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"require": {
1414
"php": ">=5.3",
1515
"react/event-loop": "0.3.*|0.4.*",
16-
"react/stream": "^0.4.2"
16+
"react/stream": "^0.4.2",
17+
"clue/utf8-react": "^0.1"
1718
},
1819
"autoload": {
1920
"psr-4": { "Clue\\React\\Stdio\\": "src/" }

src/Readline.php

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use React\Stream\ReadableStreamInterface;
77
use React\Stream\WritableStreamInterface;
88
use React\Stream\Util;
9+
use Clue\React\Utf8\Sequencer as Utf8Sequencer;
10+
use React\Stream\ReadableStream;
911

1012
class Readline extends EventEmitter implements ReadableStreamInterface
1113
{
@@ -62,35 +64,19 @@ public function __construct(ReadableStreamInterface $input, WritableStreamInterf
6264
$this->sequencer->addSequence(self::ESC_SEQUENCE . self::ESC_DEL, array($this, 'onKeyDelete'));
6365
$this->sequencer->addSequence(self::ESC_SEQUENCE . self::ESC_END, array($this, 'onKeyEnd'));
6466

65-
$expect = 0;
66-
$char = '';
67-
$that = $this;
68-
$this->sequencer->addFallback('', function ($byte) use (&$expect, &$char, $that) {
69-
if ($expect === 0) {
70-
$code = ord($byte);
71-
// count number of bytes expected for this UTF-8 multi-byte character
72-
$expect = 1;
73-
if ($code & 128 && $code & 64) {
74-
++$expect;
75-
if ($code & 32) {
76-
++$expect;
77-
if ($code & 16) {
78-
++$expect;
79-
}
80-
}
81-
}
82-
}
83-
$char .= $byte;
84-
--$expect;
85-
86-
// forward buffered bytes as a single multi byte character once last byte has been read
87-
if ($expect === 0) {
88-
$save = $char;
89-
$char = '';
90-
$that->onFallback($save);
91-
}
67+
// push input into sequencer
68+
$input->on('data', array($this->sequencer, 'push'));
69+
70+
// push sequencer output through utf8sequencer
71+
$readable = new ReadableStream();
72+
$this->sequencer->addFallback('', function ($data) use ($readable) {
73+
$readable->emit('data', array($data));
9274
});
9375

76+
// push utf8sequences as input
77+
$utf8 = new Utf8Sequencer($readable);
78+
$utf8->on('data', array($this, 'onFallback'));
79+
9480
$this->sequencer->addFallback(self::ESC_SEQUENCE, function ($bytes) {
9581
echo 'unknown sequence: ' . ord($bytes) . PHP_EOL;
9682
});
@@ -519,7 +505,7 @@ public function onFallback($chars)
519505
$post = $this->substr($this->linebuffer, $this->linepos);
520506

521507
$this->linebuffer = $pre . $chars . $post;
522-
++$this->linepos;
508+
$this->linepos += $this->strlen($chars);
523509

524510
$this->redraw();
525511
}

0 commit comments

Comments
 (0)