Skip to content

Commit

Permalink
feat: implemented xz coder
Browse files Browse the repository at this point in the history
  • Loading branch information
petrknap committed Nov 2, 2024
1 parent 5aa356f commit 18ff752
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 3 deletions.
12 changes: 9 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
"allow-plugins": false,
"sort-packages": true
},
"conflict": {
"symfony/process": "<6|>=8"
},
"description": "Library for work with binary data and objects",
"funding": [
{
Expand All @@ -34,7 +37,8 @@
"hexadecimal",
"igbinary",
"serializer",
"zlib"
"zlib",
"xz"
],
"license": "LGPL-3.0-or-later",
"name": "petrknap/binary",
Expand All @@ -50,7 +54,8 @@
"nunomaduro/phpinsights": "^2.11",
"phpstan/phpstan": "^1.12",
"phpunit/phpunit": "^10.5",
"squizlabs/php_codesniffer": "^3.7"
"squizlabs/php_codesniffer": "^3.7",
"symfony/process": "*"
},
"scripts": {
"test": "@test-implementation",
Expand All @@ -76,6 +81,7 @@
"suggest": {
"ext-igbinary": "Required to serialize data via igbinary",
"ext-mbstring": "Required to bite bytes",
"ext-zlib": "Required to compress data"
"ext-zlib": "Required to compress data",
"symfony/process": "Required to call external executables"
}
}
63 changes: 63 additions & 0 deletions src/Coder/ExternalCoder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace PetrKnap\Binary\Coder;

use PetrKnap\Shorts\HasRequirements;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

/**
* @internal
*/
abstract class ExternalCoder extends Coder
{
use HasRequirements;

/**
* Must be set in {@see self::encode()}
*
* @var array<string>
*/
protected array $encodeCommand;

/**
* Must be set in {@see self::encode()}
*
* @var array<string>
*/
protected array $decodeCommand;

public function __construct()
{
self::checkRequirements(
classes: [
Process::class,
ProcessFailedException::class,
],
);
}

protected function doEncode(string $decoded): string
{
$encoder = new Process($this->encodeCommand);
$encoder->setInput($decoded);
$encoder->run();
if (!$encoder->isSuccessful()) {
throw new ProcessFailedException($encoder);
}
return $encoder->getOutput();
}

protected function doDecode(string $encoded): string
{
$decoder = new Process($this->decodeCommand);
$decoder->setInput($encoded);
$decoder->run();
if (!$decoder->isSuccessful()) {
throw new ProcessFailedException($decoder);
}
return $decoder->getOutput();
}
}
22 changes: 22 additions & 0 deletions src/Coder/Xz.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace PetrKnap\Binary\Coder;

final class Xz extends ExternalCoder
{
public function encode(string $decoded, int|null $level = null): string
{
$this->encodeCommand = ['xz', '--compress', '--stdout'];
if ($level !== null) {
$this->encodeCommand[] = "-{$level}";
}
return parent::encode($decoded);
}
public function decode(string $encoded): string
{
$this->decodeCommand = ['xz', '--decompress', '--stdout'];
return parent::decode($encoded);
}
}
43 changes: 43 additions & 0 deletions tests/Coder/XzTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace PetrKnap\Binary\Coder;

use PHPUnit\Framework\Attributes\DataProvider;

final class XzTest extends CoderTestCase
{
public static function data(): array
{
$data = self::getDecodedData();
return [
'default preset' => [$data, base64_decode('/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AA7ABxdAG0OUG7jCUfPj0z08gJbP9KgthIHS/jgLMk44AAAwVvY3vTzsZsAATg8V3V2GB+2830BAAAAAARZWg=='), null],
'preset 0' => [$data, base64_decode('/Td6WFoAAATm1rRGAgAhAQwAAACPmEGc4AA7ABxdAG0OUG7jCUfPj0z08gJbP9KgthIHS/jgLMk44AAAwVvY3vTzsZsAATg8V3V2GB+2830BAAAAAARZWg=='), 0],
'preset 9' => [$data, base64_decode('/Td6WFoAAATm1rRGAgAhARwAAAAQz1jM4AA7ABxdAG0OUG7jCUfPj0z08gJbP9KgthIHS/jgLMk44AAAwVvY3vTzsZsAATg8V3V2GB+2830BAAAAAARZWg=='), 9],
];
}

#[DataProvider('data')]
public function testEncodes(string $decoded, string $encoded, int|null $level): void
{
self::assertBinarySame(
$encoded,
(new Xz())->encode(
$decoded,
level: $level,
),
);
}

#[DataProvider('data')]
public function testDecodes(string $decoded, string $encoded): void
{
self::assertBinarySame(
$decoded,
(new Xz())->decode(
$encoded,
),
);
}
}

0 comments on commit 18ff752

Please sign in to comment.