-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
203 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PetrKnap\Binary; | ||
|
||
use PetrKnap\Shorts\HasRequirements; | ||
use RuntimeException; | ||
|
||
class Byter | ||
{ | ||
use HasRequirements; | ||
|
||
private const ENCODING = '8bit'; | ||
|
||
public function __construct() | ||
{ | ||
self::checkRequirements( | ||
functions: [ | ||
'mb_strcut', | ||
'mb_strlen', | ||
], | ||
); | ||
} | ||
|
||
/** | ||
* @param int $size1 size of bite in bytes; if negative, bites from the end | ||
* | ||
* @return array<string> bites of specified sizes; and remains, if any | ||
* | ||
* @throws Exception\CouldNotBiteData | ||
*/ | ||
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( | ||
'Remains are smaller than bite', | ||
)); | ||
} | ||
$bite = mb_strcut($remains, 0, $size, encoding: self::ENCODING); | ||
$remains = mb_strcut($remains, $size, encoding: self::ENCODING); | ||
if ($size < 0) { | ||
$bites[] = $remains; | ||
$remains = $bite; | ||
} else { | ||
$bites[] = $bite; | ||
} | ||
} | ||
if ($remains !== '') { | ||
$bites[] = $remains; | ||
} | ||
return $bites; | ||
} | ||
|
||
/** | ||
* Backward version of {@see self::bite()} | ||
* | ||
* @link https://en.wikipedia.org/wiki/Backwards_(Red_Dwarf) | ||
*/ | ||
public function unbite(string $bite1, string ...$biteN): string | ||
{ | ||
return implode([$bite1, ...$biteN]); | ||
} | ||
|
||
/** | ||
* @return int size in bytes | ||
*/ | ||
public function size(string $data): int | ||
{ | ||
return mb_strlen($data, encoding: self::ENCODING); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PetrKnap\Binary\Exception; | ||
|
||
interface ByterException extends BinaryException | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PetrKnap\Binary\Exception; | ||
|
||
use PetrKnap\Shorts\Exception\CouldNotProcessData; | ||
|
||
/** | ||
* @extends CouldNotProcessData<string> | ||
*/ | ||
final class CouldNotBiteData extends CouldNotProcessData implements ByterException | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace PetrKnap\Binary; | ||
|
||
use PHPUnit\Framework\Attributes\DataProvider; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
final class ByterTest extends TestCase | ||
{ | ||
#[DataProvider('dataBitesData')] | ||
public function testBitesData(array $expected, array $sizes): void | ||
{ | ||
self::assertSame( | ||
$expected, | ||
(new Byter())->bite(self::getData(), ...$sizes), | ||
); | ||
} | ||
|
||
public static function dataBitesData(): array | ||
{ | ||
return [ | ||
'one left bite' => [[hex2bin('0102'), hex2bin('030405')], [2]], | ||
'one right bite' => [[hex2bin('0405'), hex2bin('010203')], [-2]], | ||
'empty bite' => [['', hex2bin('0102030405')], [0]], | ||
'full bite' => [[hex2bin('0102030405')], [5]], | ||
'many bites' => [[hex2bin('0102'), hex2bin('0405'), '', hex2bin('03')], [2, -2, 0, 1]], | ||
]; | ||
} | ||
|
||
public function testBiteThrowsWhenThereIsNotEnoughData(): void | ||
{ | ||
self::expectException(Exception\CouldNotBiteData::class); | ||
|
||
$data = self::getData(); | ||
$byter = new Byter(); | ||
$byter->bite( | ||
$data, | ||
$byter->size($data) + 1, | ||
); | ||
} | ||
|
||
public function testUnbitesBites(): void | ||
{ | ||
self::assertSame( | ||
self::getData(), | ||
(new Byter())->unbite(hex2bin('0102'), hex2bin('030405')), | ||
); | ||
} | ||
|
||
public function testReturnsSizeOfData(): void | ||
{ | ||
self::assertSame( | ||
5, | ||
(new Byter())->size(self::getData()), | ||
); | ||
} | ||
|
||
private static function getData(): string | ||
{ | ||
return hex2bin('0102030405'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters