Skip to content

Instantly share code, notes, and snippets.

@kelunik
Created June 6, 2017 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kelunik/0f043950e006c198b66e823d7d18d15d to your computer and use it in GitHub Desktop.
Save kelunik/0f043950e006c198b66e823d7d18d15d to your computer and use it in GitHub Desktop.
A simple RESP parser based on Amp\Parser.
<?php
use Amp\Parser\Parser;
class RespParser extends Parser {
private $onResponse;
public function __construct(callable $onResponse) {
$this->onResponse = $onResponse;
parent::__construct($this->parse());
}
private function parse() {
while (true) {
$response = yield from $this->parseSingle();
($this->onResponse)($response);
}
}
private function parseSingle() {
$firstLine = yield "\r\n";
\assert(\strlen($firstLine) > 0);
$type = $firstLine[0];
$value = \substr($firstLine, 1);
switch ($type) {
case "+":
return $value;
case ":":
return (int) $value;
case "*":
$arraySize = (int) $value;
$values = [];
while ($arraySize-- > 0) {
$values[] = yield from $this->parseSingle();
}
return $values;
case "$":
$length = (int) $value;
if ($length === -1) {
$payload = null;
} else {
$payload = yield ($length + 2);
$payload = \substr($payload, 0, -2);
}
return $payload;
case "-":
return new RespError($value);
default:
throw new ParseException(\sprintf(
"Unknown RESP data type: %s",
$type
));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment