-
Notifications
You must be signed in to change notification settings - Fork 186
/
Copy pathProtocolStreamReader.php
66 lines (59 loc) Β· 2.27 KB
/
ProtocolStreamReader.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
declare(strict_types = 1);
namespace LanguageServer;
use LanguageServer\Message;
use AdvancedJsonRpc\Message as MessageBody;
use Sabre\Event\{Loop, Emitter};
class ProtocolStreamReader extends Emitter implements ProtocolReader
{
const PARSE_HEADERS = 1;
const PARSE_BODY = 2;
private $input;
private $parsingMode = self::PARSE_HEADERS;
private $buffer = '';
private $headers = [];
private $contentLength;
/**
* @param resource $input
*/
public function __construct($input)
{
$this->input = $input;
$this->on('close', function () {
Loop\removeReadStream($this->input);
});
Loop\addReadStream($this->input, function () {
if (feof($this->input)) {
// If stream_select reported a status change for this stream,
// but the stream is EOF, it means it was closed.
$this->emit('close');
return;
}
while (($c = fgetc($this->input)) !== false && $c !== '') {
$this->buffer .= $c;
switch ($this->parsingMode) {
case self::PARSE_HEADERS:
if ($this->buffer === "\r\n") {
$this->parsingMode = self::PARSE_BODY;
$this->contentLength = (int)$this->headers['Content-Length'];
$this->buffer = '';
} else if (substr($this->buffer, -2) === "\r\n") {
$parts = explode(':', $this->buffer);
$this->headers[$parts[0]] = trim($parts[1]);
$this->buffer = '';
}
break;
case self::PARSE_BODY:
if (strlen($this->buffer) === $this->contentLength) {
$msg = new Message(MessageBody::parse($this->buffer), $this->headers);
$this->emit('message', [$msg]);
$this->parsingMode = self::PARSE_HEADERS;
$this->headers = [];
$this->buffer = '';
}
break;
}
}
});
}
}