Initial commit

This commit is contained in:
Christopher Vagnetoft
2026-04-02 22:29:35 +02:00
commit 62a1167055
31 changed files with 3759 additions and 0 deletions

64
src/Line/LineProtocol.php Normal file
View File

@@ -0,0 +1,64 @@
<?php
namespace NoccyLabs\React\Protocol\Line;
use Closure;
use NoccyLabs\React\Protocol\ProtocolInterface;
class LineProtocol implements ProtocolInterface
{
public function __construct(
private readonly string $lineBreak = "\n",
private readonly bool $quoteStrings = false,
private readonly bool $escapeSpecial = false,
private readonly ?Closure $beforePackCb = null,
private readonly ?Closure $afterPackCb = null,
private readonly ?Closure $beforeUnpackCb = null,
private readonly ?Closure $afterUnpackCb = null,
)
{
}
public function packFrame(array $frame): string
{
if (is_callable($this->beforePackCb))
$frame = call_user_func($this->beforePackCb, $frame);
if ($this->escapeSpecial) {
$frame = array_map(quotemeta(...), $frame);
}
if ($this->quoteStrings) {
$frame = array_map(fn($v) => is_string($v) ? ('"'.str_replace('"',"\\\"",$v).'"') : $v, $frame);
}
$data = join(" ", $frame);
$data .= $this->lineBreak;
if (is_callable($this->afterPackCb))
$data = call_user_func($this->afterPackCb, $data);
return $data;
}
public function unpackFrame(string $data): array
{
return str_getcsv($data, ' ', '"', "\\");
}
public function consumeFrame(string &$data): ?array
{
// check for $this->lineBreak
$p = strpos($data, $this->lineBreak);
if ($p === false) {
return null;
}
// break on separator
$frame = substr($data, 0, $p);
$data = substr($data, $p + strlen($this->lineBreak));
return $this->unpackFrame($frame);
}
}