react-http2/src/Huffman/Codec.php

50 lines
1.3 KiB
PHP

<?php
namespace NoccyLabs\React\Http2\Huffman;
class Codec
{
private Dictionary $dictionary;
const CODE_EOS = 256;
public function __construct(Dictionary $dictionary)
{
$this->dictionary = $dictionary;
}
public function decode(string $data): ?string
{
$in = array_map("ord", str_split($data));
$out = [];
$bits = '';
for ($ch = 0; $ch < count($in); $ch++) {
$bits .= str_pad(decbin($in[$ch]), 8, "0", STR_PAD_LEFT);
while (($code = $this->dictionary->match($bits)) !== null) {
if ($code === self::CODE_EOS) break(2);
$out[] = $code;
}
}
return join("", array_map("chr", $out));
}
public function encode(string $data): ?string
{
$in = array_map("ord", str_split($data));
//$in[] = self::CODE_EOS;
$out = [];
$bits = '';
for ($ch = 0; $ch < count($in); $ch++) {
$bits .= $this->dictionary->pattern($in[$ch]);
while (strlen($bits) >= 8) {
$out[] = bindec(substr($bits, 0, 8));
$bits = substr($bits, 8);
}
}
if (strlen($bits) > 0) {
$out[] = bindec(str_pad($bits, 8, "1", STR_PAD_RIGHT));
}
return join("", array_map("chr", $out));
}
}