diff --git a/composer.json b/composer.json index 2a29746..96f310c 100755 --- a/composer.json +++ b/composer.json @@ -14,6 +14,9 @@ "allow-plugins": false, "sort-packages": true }, + "conflict": { + "petrknap/xz-utils": "<1|>=2" + }, "description": "Library for work with binary data and objects", "funding": [ { @@ -34,7 +37,8 @@ "hexadecimal", "igbinary", "serializer", - "zlib" + "zlib", + "xz" ], "license": "LGPL-3.0-or-later", "name": "petrknap/binary", @@ -48,6 +52,7 @@ "ext-mbstring": "*", "ext-zlib": "*", "nunomaduro/phpinsights": "^2.11", + "petrknap/xz-utils": "*", "phpstan/phpstan": "^1.12", "phpunit/phpunit": "^10.5", "squizlabs/php_codesniffer": "^3.7" @@ -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", + "petrknap/xz-utils": "Required to compress data" } } diff --git a/src/Coder.php b/src/Coder.php index 58da67a..0e21b97 100644 --- a/src/Coder.php +++ b/src/Coder.php @@ -48,6 +48,13 @@ abstract public function checksum(string|null $algorithm = null): static; */ abstract public function hex(): static; + /** + * @see Coder\Xz + * + * @throws Coder\Exception\CoderException + */ + abstract public function xz(): static; + /** * @see Coder\zlib * diff --git a/src/Coder/Xz.php b/src/Coder/Xz.php new file mode 100644 index 0000000..287a903 --- /dev/null +++ b/src/Coder/Xz.php @@ -0,0 +1,45 @@ +compressionPreset = $compressionPreset; + return parent::encode($decoded); + } + + protected function doEncode(string $decoded): string + { + return (new Inner())->compress( + data: $decoded, + compressionPreset: $this->compressionPreset, + ); + } + + protected function doDecode(string $encoded): string + { + return (new Inner())->decompress( + data: $encoded, + ); + } +} diff --git a/src/Decoder.php b/src/Decoder.php index 2703e99..0e3c48c 100644 --- a/src/Decoder.php +++ b/src/Decoder.php @@ -28,6 +28,13 @@ public function hex(): static )); } + public function xz(): static + { + return $this->withData((new Coder\Xz())->decode( + $this->data, + )); + } + public function zlib(int|null $maxLength = null): static { return $this->withData((new Coder\Zlib())->decode( diff --git a/src/Encoder.php b/src/Encoder.php index 5878e45..3a1da70 100644 --- a/src/Encoder.php +++ b/src/Encoder.php @@ -29,6 +29,14 @@ public function hex(): static )); } + public function xz(int|null $compressionPreset = null): static + { + return $this->withData((new Coder\Xz())->encode( + $this->data, + compressionPreset: $compressionPreset, + )); + } + public function zlib(int|null $encoding = null, int|null $level = null): static { return $this->withData((new Coder\Zlib())->encode( diff --git a/tests/Coder/XzTest.php b/tests/Coder/XzTest.php new file mode 100644 index 0000000..e2e4528 --- /dev/null +++ b/tests/Coder/XzTest.php @@ -0,0 +1,43 @@ + [$data, base64_decode('/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AA7ABxdAG0OUG7jCUfPj0z08gJbP9KgthIHS/jgLMk44AAAwVvY3vTzsZsAATg8V3V2GB+2830BAAAAAARZWg=='), null], + 'compression preset 0' => [$data, base64_decode('/Td6WFoAAATm1rRGAgAhAQwAAACPmEGc4AA7ABxdAG0OUG7jCUfPj0z08gJbP9KgthIHS/jgLMk44AAAwVvY3vTzsZsAATg8V3V2GB+2830BAAAAAARZWg=='), 0], + 'compression preset 9' => [$data, base64_decode('/Td6WFoAAATm1rRGAgAhARwAAAAQz1jM4AA7ABxdAG0OUG7jCUfPj0z08gJbP9KgthIHS/jgLMk44AAAwVvY3vTzsZsAATg8V3V2GB+2830BAAAAAARZWg=='), 9], + ]; + } + + #[DataProvider('data')] + public function testEncodes(string $decoded, string $encoded, int|null $compressionPreset): void + { + self::assertBinarySame( + $encoded, + (new Xz())->encode( + $decoded, + compressionPreset: $compressionPreset, + ), + ); + } + + #[DataProvider('data')] + public function testDecodes(string $decoded, string $encoded): void + { + self::assertBinarySame( + $decoded, + (new Xz())->decode( + $encoded, + ), + ); + } +} diff --git a/tests/DecoderTest.php b/tests/DecoderTest.php index 56b0948..c357c65 100644 --- a/tests/DecoderTest.php +++ b/tests/DecoderTest.php @@ -30,6 +30,14 @@ public function testDecodesHex(): void ); } + public function testDecodesXz(): void + { + self::assertBinarySame( + Coder\XzTest::getDecodedData(), + (new Decoder(Coder\XzTest::getEncodedData()))->xz()->data, + ); + } + public function testDecodesZlib(): void { self::assertBinarySame( diff --git a/tests/EncoderTest.php b/tests/EncoderTest.php index 9d64a7b..1056edc 100644 --- a/tests/EncoderTest.php +++ b/tests/EncoderTest.php @@ -30,6 +30,14 @@ public function testEncodesHex(): void ); } + public function testEncodesXz(): void + { + self::assertBinarySame( + Coder\XzTest::getEncodedData(), + (new Encoder(Coder\XzTest::getDecodedData()))->xz()->data, + ); + } + public function testEncodesZlib(): void { self::assertBinarySame(