Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC: removed public constants from coders, removed interfaces for abstract classes, rearranged exceptions #16

Merged
merged 1 commit into from
Nov 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ See the examples below for more information, or check out [`Encoder`](./src/Enco
namespace PetrKnap\Binary;

$data = base64_decode('hmlpFnFwbchsoQARSibVpfbWVfuwAHLbGxjFl9eC8fiGaWkWcXBtyGyhABFKJtWl9tZV+7AActsbGMWX14Lx+A==');
$encoded = Binary::encode($data)->checksum()->zlib()->base64(urlSafe: true)->getData();
$decoded = Binary::decode($encoded)->base64()->zlib()->checksum()->getData();
$encoded = Binary::encode($data)->checksum()->zlib()->base64(urlSafe: true)->data;
$decoded = Binary::decode($encoded)->base64()->zlib()->checksum()->data;

printf('Data was coded into `%s` %s.', $encoded, $decoded === $data ? 'successfully' : 'unsuccessfully');
```
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"require": {
"php": ">=8.1",
"petrknap/optional": "^3.1",
"petrknap/shorts": "^2.0"
"petrknap/shorts": "^3.0"
},
"require-dev": {
"ext-igbinary": "*",
Expand All @@ -63,7 +63,7 @@
"phpcs --colors --standard=PSR12 --exclude=Generic.Files.LineLength src tests",
"phpstan analyse --level max src --ansi --no-interaction",
"phpstan analyse --level 5 tests --ansi --no-interaction",
"phpinsights analyse src --ansi --no-interaction"
"phpinsights analyse src tests --ansi --no-interaction --format=github-action | sed -e \"s#::error file=$PWD/#::notice file=#g\""
],
"check-requirements": [
"composer update \"petrknap/*\"",
Expand Down
4 changes: 2 additions & 2 deletions src/Binary.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

final class Binary
{
public static function encode(string $data): EncoderInterface
public static function encode(string $data): Encoder
{
return new Encoder($data);
}

public static function decode(string $data): DecoderInterface
public static function decode(string $data): Decoder
{
return new Decoder($data);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Byter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use PetrKnap\Shorts\HasRequirements;
use RuntimeException;

class Byter
final class Byter
{
use HasRequirements;

Expand All @@ -28,15 +28,15 @@ functions: [
*
* @return array<string> bites of specified sizes; and remains, if any
*
* @throws Exception\CouldNotBiteData
* @throws Exception\ByterCouldNotBiteData
*/
public function bite(string $data, int $size1, int ...$sizeN): array
{
$remains = $data;
$bites = [];
foreach ([$size1, ...$sizeN] as $size) {
if (abs($size) > $this->size($remains)) {
throw new Exception\CouldNotBiteData(__METHOD__, $data, new RuntimeException(
throw new Exception\ByterCouldNotBiteData(__METHOD__, $data, new RuntimeException(
'Remains are smaller than bite',
));
}
Expand Down
54 changes: 37 additions & 17 deletions src/Coder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,54 @@

namespace PetrKnap\Binary;

use PetrKnap\Shorts\Exception;

/**
* @internal please use subclass
*
* @phpstan-consistent-constructor override {@see self::create()} if not
*
* @implements CoderInterface<Exception\CouldNotProcessData>
* @internal shared logic
*/
abstract class Coder implements CoderInterface
abstract class Coder
{
public function __construct(
protected readonly string $data = '',
final public function __construct(
public readonly string $data = '',
) {
}

public function withData(string $data): static
final public function withData(string $data): static
{
return static::create($this, $data);
return new static($data);
}

public function getData(): string
/**
* @deprecated use readonly property $data
*/
final public function getData(): string
{
return $this->data;
}

protected static function create(self $coder, string $data): static
{
return new static($data);
}
/**
* @see Coder\Base64
*
* @throws Coder\Exception\CoderException
*/
abstract public function base64(): static;

/**
* @see Coder\Checksum
*
* @throws Coder\Exception\CoderException
*/
abstract public function checksum(string|null $algorithm = null): static;

/**
* @see Coder\Hex
*
* @throws Coder\Exception\CoderException
*/
abstract public function hex(): static;

/**
* @see Coder\zlib
*
* @throws Coder\Exception\CoderException
*/
abstract public function zlib(): static;
}
8 changes: 3 additions & 5 deletions src/Coder/Base64.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@
*/
final class Base64 extends Coder
{
public const URL_SAFE = false;

private const URL_REPLACE_TABLE = [
['+', '/', '='],
['-', '_', ''],
];

private bool $urlSafe;

public function encode(string $decoded, ?bool $urlSafe = null): string
public function encode(string $decoded, bool|null $urlSafe = null): string
{
$this->urlSafe = $urlSafe ?? self::URL_SAFE;
$this->urlSafe = $urlSafe ?? false;
return parent::encode($decoded);
}

Expand All @@ -42,7 +40,7 @@ protected function doDecode(string $encoded): string
str_replace(self::URL_REPLACE_TABLE[1], self::URL_REPLACE_TABLE[0], $encoded),
strict: true,
))->orElseThrow(
static fn () => new Exception\CouldNotDecodeData(__METHOD__, $encoded),
static fn () => new Exception\CoderCouldNotDecodeData(__METHOD__, $encoded),
);
}
}
15 changes: 9 additions & 6 deletions src/Coder/Checksum.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
*/
final class Checksum extends Coder
{
public const ALGORITHM = 'crc32';
/**
* @internal public for testing purposes only
*/
public const DEFAULT_ALGORITHM = 'crc32';

private string $algorithm;
private readonly Byter $byter;
Expand All @@ -23,15 +26,15 @@ public function __construct()
$this->byter = new Byter();
}

public function encode(string $decoded, ?string $algorithm = null): string
public function encode(string $decoded, string|null $algorithm = null): string
{
$this->algorithm = $algorithm ?? self::ALGORITHM;
$this->algorithm = $algorithm ?? self::DEFAULT_ALGORITHM;
return parent::encode($decoded);
}

public function decode(string $encoded, ?string $algorithm = null): string
public function decode(string $encoded, string|null $algorithm = null): string
{
$this->algorithm = $algorithm ?? self::ALGORITHM;
$this->algorithm = $algorithm ?? self::DEFAULT_ALGORITHM;
return parent::decode($encoded);
}

Expand All @@ -46,7 +49,7 @@ protected function doDecode(string $encoded): string
$checksumLength = $this->byter->size(hash($this->algorithm, '', binary: true));
[,$decoded] = $this->byter->bite($encoded, -$checksumLength);
if ($this->doEncode($decoded) !== $encoded) {
throw new Exception\CouldNotDecodeData(__METHOD__, $encoded);
throw new Exception\CoderCouldNotDecodeData(__METHOD__, $encoded);
}
return $decoded;
}
Expand Down
17 changes: 9 additions & 8 deletions src/Coder/Coder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,30 @@

use Throwable;

/**
* @internal shared logic
*/
abstract class Coder implements CoderInterface
{
public function encode(string $decoded): string
{
try {
return $this->doEncode($decoded);
} catch (Exception\CoderCouldNotEncodeData $exception) {
throw $exception;
} catch (Throwable $reason) {
if ($reason instanceof Exception\CouldNotEncodeData) {
throw $reason;
}
throw new Exception\CouldNotEncodeData(__METHOD__, $decoded, $reason);
throw new Exception\CoderCouldNotEncodeData(__METHOD__, $decoded, $reason);
}
}

public function decode(string $encoded): string
{
try {
return $this->doDecode($encoded);
} catch (Exception\CoderCouldNotDecodeData $exception) {
throw $exception;
} catch (Throwable $reason) {
if ($reason instanceof Exception\CouldNotDecodeData) {
throw $reason;
}
throw new Exception\CouldNotDecodeData(__METHOD__, $encoded, $reason);
throw new Exception\CoderCouldNotDecodeData(__METHOD__, $encoded, $reason);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Coder/CoderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
interface CoderInterface
{
/**
* @throws Exception\CouldNotEncodeData
* @throws Exception\CoderCouldNotEncodeData
*/
public function encode(string $decoded): string;

/**
* @throws Exception\CouldNotDecodeData
* @throws Exception\CoderCouldNotDecodeData
*/
public function decode(string $encoded): string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
/**
* @extends CouldNotProcessData<string>
*/
final class CouldNotDecodeData extends CouldNotProcessData implements CoderException
final class CoderCouldNotDecodeData extends CouldNotProcessData implements CoderException
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
/**
* @extends CouldNotProcessData<string>
*/
final class CouldNotEncodeData extends CouldNotProcessData implements CoderException
final class CoderCouldNotEncodeData extends CouldNotProcessData implements CoderException
{
}
4 changes: 2 additions & 2 deletions src/Coder/Exception/CoderException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace PetrKnap\Binary\Coder\Exception;

use PetrKnap\Binary\Exception\BinaryException;
use PetrKnap\Binary\Exception\Exception;

interface CoderException extends BinaryException
interface CoderException extends Exception
{
}
2 changes: 1 addition & 1 deletion src/Coder/Hex.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ protected function doEncode(string $decoded): string
protected function doDecode(string $encoded): string
{
return OptionalString::ofFalsable(hex2bin($encoded))->orElseThrow(
static fn () => new Exception\CouldNotDecodeData(__METHOD__, $encoded),
static fn () => new Exception\CoderCouldNotDecodeData(__METHOD__, $encoded),
);
}
}
39 changes: 24 additions & 15 deletions src/Coder/Zlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,9 @@ final class Zlib extends Coder
{
use HasRequirements;

public const ENCODING = ZLIB_ENCODING_RAW;
public const LEVEL = -1;
public const MAX_LENGTH = 0;

private int $encoding;
private int $level;
private int $maxLength;
private int|null $level;
private int|null $maxLength;

public function __construct()
{
Expand All @@ -36,30 +32,43 @@ functions: [
);
}

public function encode(string $decoded, ?int $encoding = null, ?int $level = null): string
public function encode(string $decoded, int|null $encoding = null, int|null $level = null): string
{
$this->encoding = $encoding ?? self::ENCODING;
$this->level = $level ?? self::LEVEL;
$this->encoding = $encoding ?? ZLIB_ENCODING_RAW;
$this->level = $level;
return parent::encode($decoded);
}

public function decode(string $encoded, ?int $maxLength = null): string
public function decode(string $encoded, int|null $maxLength = null): string
{
$this->maxLength = $maxLength ?? self::MAX_LENGTH;
$this->maxLength = $maxLength;
return parent::decode($encoded);
}

protected function doEncode(string $decoded): string
{
return OptionalString::ofFalsable(zlib_encode($decoded, $this->encoding, $this->level))->orElseThrow(
static fn () => new Exception\CouldNotEncodeData(__METHOD__, $decoded),
$encodeArgs = [
'data' => $decoded,
'encoding' => $this->encoding,
];
if ($this->level !== null) {
$encodeArgs['level'] = $this->level;
}
return OptionalString::ofFalsable(zlib_encode(...$encodeArgs))->orElseThrow(
static fn () => new Exception\CoderCouldNotEncodeData(__METHOD__, $decoded),
);
}

protected function doDecode(string $encoded): string
{
return OptionalString::ofFalsable(zlib_decode($encoded, $this->maxLength))->orElseThrow(
static fn () => new Exception\CouldNotDecodeData(__METHOD__, $encoded),
$decodeArgs = [
'data' => $encoded,
];
if ($this->maxLength !== null) {
$decodeArgs['max_length'] = $this->maxLength;
}
return OptionalString::ofFalsable(zlib_decode(...$decodeArgs))->orElseThrow(
static fn () => new Exception\CoderCouldNotDecodeData(__METHOD__, $encoded),
);
}
}
Loading
Loading