Skip to content

Commit

Permalink
Introduce WKBByteOrder enum
Browse files Browse the repository at this point in the history
  • Loading branch information
BenMorel committed Oct 17, 2023
1 parent 956b7c0 commit 6756773
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 62 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
💥 **Breaking changes**

- **Minimum PHP version is now `8.1`**
- `AbstractWKBWriter::setByteOrder()` now accepts a `WKBByteOrder` enum instead of a `WKBTools::*_ENDIAN` constant
- constants `WKBTools::BIG_ENDIAN` and `WKBTools::LITTLE_ENDIAN` have been removed
- method `WKBTools::checkByteOrder()` has been removed

## [0.9.0](https://github.com/brick/geo/releases/tag/0.9.0) - 2022-11-22

Expand Down
26 changes: 8 additions & 18 deletions src/IO/AbstractWKBWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,9 @@
*/
abstract class AbstractWKBWriter
{
/**
* @psalm-var WKBTools::BIG_ENDIAN|WKBTools::LITTLE_ENDIAN
*/
private int $byteOrder;
private WKBByteOrder $byteOrder;

/**
* @psalm-var WKBTools::BIG_ENDIAN|WKBTools::LITTLE_ENDIAN
*/
private int $machineByteOrder;
private WKBByteOrder $machineByteOrder;

/**
* @throws GeometryIOException
Expand All @@ -39,15 +33,8 @@ public function __construct()
$this->byteOrder = $this->machineByteOrder = WKBTools::getMachineByteOrder();
}

/**
* @param int $byteOrder The byte order, one of the WKBTools::BIG_ENDIAN or WKBTools::LITTLE_ENDIAN constants.
*
* @throws \InvalidArgumentException If the byte order is invalid.
*/
public function setByteOrder(int $byteOrder) : void
public function setByteOrder(WKBByteOrder $byteOrder) : void
{
WKBTools::checkByteOrder($byteOrder);
/** @var WKBTools::BIG_ENDIAN|WKBTools::LITTLE_ENDIAN byteOrder */
$this->byteOrder = $byteOrder;
}

Expand Down Expand Up @@ -110,12 +97,15 @@ protected function doWrite(Geometry $geometry, bool $outer) : string

private function packByteOrder() : string
{
return pack('C', $this->byteOrder);
return pack('C', $this->byteOrder->value);
}

protected function packUnsignedInteger(int $uint) : string
{
return pack($this->byteOrder === WKBTools::BIG_ENDIAN ? 'N' : 'V', $uint);
return pack(match ($this->byteOrder) {
WKBByteOrder::BIG_ENDIAN => 'N',
WKBByteOrder::LITTLE_ENDIAN => 'V'
}, $uint);
}

private function packDouble(float $double) : string
Expand Down
8 changes: 4 additions & 4 deletions src/IO/WKBBuffer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ class WKBBuffer
private readonly string $wkb;
private readonly int $length;
private int $position = 0;
/** @psalm-var WKBTools::BIG_ENDIAN|WKBTools::LITTLE_ENDIAN */
private readonly int $machineByteOrder;
private readonly WKBByteOrder $machineByteOrder;
private bool $invert = false;

public function __construct(string $wkb)
Expand Down Expand Up @@ -105,12 +104,13 @@ public function readDoubles(int $count) : array
public function readByteOrder() : void
{
$byteOrder = $this->readUnsignedChar();
$wkbByteOrder = WKBByteOrder::tryFrom($byteOrder);

if ($byteOrder !== WKBTools::BIG_ENDIAN && $byteOrder !== WKBTools::LITTLE_ENDIAN) {
if ($wkbByteOrder === null) {
throw GeometryIOException::invalidWKB('unknown byte order: ' . $byteOrder);
}

$this->invert = ($byteOrder !== $this->machineByteOrder);
$this->invert = ($wkbByteOrder !== $this->machineByteOrder);
}

public function rewind(int $bytes) : void
Expand Down
11 changes: 11 additions & 0 deletions src/IO/WKBByteOrder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Brick\Geo\IO;

enum WKBByteOrder: int
{
case BIG_ENDIAN = 0;
case LITTLE_ENDIAN = 1;
}
23 changes: 4 additions & 19 deletions src/IO/WKBTools.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
*/
abstract class WKBTools
{
final public const BIG_ENDIAN = 0;
final public const LITTLE_ENDIAN = 1;

/**
* @throws GeometryIOException
*/
Expand All @@ -24,34 +21,22 @@ private static function checkDoubleIs64Bit() : void
}
}

/**
* @throws \InvalidArgumentException
*/
public static function checkByteOrder(int $byteOrder) : void
{
if ($byteOrder !== self::BIG_ENDIAN && $byteOrder !== self::LITTLE_ENDIAN) {
throw new \InvalidArgumentException('Invalid byte order: ' . var_export($byteOrder, true));
}
}

/**
* Detects the machine byte order (big endian or little endian).
*
* @psalm-return self::BIG_ENDIAN|self::LITTLE_ENDIAN
*
* @throws GeometryIOException
*/
public static function getMachineByteOrder() : int
public static function getMachineByteOrder() : WKBByteOrder
{
/** @psalm-var self::BIG_ENDIAN|self::LITTLE_ENDIAN|null $byteOrder */
/** @var WKBByteOrder|null $byteOrder */
static $byteOrder;

if ($byteOrder === null) {
self::checkDoubleIs64Bit();

$byteOrder = match (pack('L', 0x61626364)) {
'abcd' => self::BIG_ENDIAN,
'dcba' => self::LITTLE_ENDIAN,
'abcd' => WKBByteOrder::BIG_ENDIAN,
'dcba' => WKBByteOrder::LITTLE_ENDIAN,
default => throw GeometryIOException::unsupportedEndianness(),
};
}
Expand Down
10 changes: 5 additions & 5 deletions tests/GeometryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Brick\Geo\Tests;

use Brick\Geo\Exception\UnexpectedGeometryException;
use Brick\Geo\IO\WKBByteOrder;
use Brick\Geo\IO\WKBTools;
use Brick\Geo\Geometry;
use Brick\Geo\Point;
Expand Down Expand Up @@ -71,11 +72,10 @@ public function testAsBinary(string $text, string $bigEndianBinary, string $litt
{
$machineByteOrder = WKBTools::getMachineByteOrder();

if ($machineByteOrder === WKBTools::BIG_ENDIAN) {
$binary = $bigEndianBinary;
} else {
$binary = $littleEndianBinary;
}
$binary = match ($machineByteOrder) {
WKBByteOrder::BIG_ENDIAN => $bigEndianBinary,
WKBByteOrder::LITTLE_ENDIAN => $littleEndianBinary,
};

self::assertSame($binary, bin2hex(Geometry::fromText($text)->asBinary()));
}
Expand Down
18 changes: 9 additions & 9 deletions tests/IO/EWKBWriterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Brick\Geo\Tests\IO;

use Brick\Geo\Exception\GeometryIOException;
use Brick\Geo\IO\EWKBTools;
use Brick\Geo\IO\EWKBWriter;
use Brick\Geo\IO\EWKTReader;
use Brick\Geo\IO\WKBByteOrder;
use Brick\Geo\Point;

/**
Expand All @@ -18,11 +18,11 @@ class EWKBWriterTest extends EWKBAbstractTest
/**
* @dataProvider providerWrite
*
* @param string $ewkt The EWKT to read.
* @param string $ewkb The expected EWKB output, hex-encoded.
* @param int $byteOrder The byte order to use.
* @param string $ewkt The EWKT to read.
* @param string $ewkb The expected EWKB output, hex-encoded.
* @param WKBByteOrder $byteOrder The byte order to use.
*/
public function testWrite(string $ewkt, string $ewkb, int $byteOrder) : void
public function testWrite(string $ewkt, string $ewkb, WKBByteOrder $byteOrder) : void
{
$writer = new EWKBWriter();
$writer->setByteOrder($byteOrder);
Expand All @@ -38,19 +38,19 @@ public function testWrite(string $ewkt, string $ewkb, int $byteOrder) : void
public function providerWrite() : \Generator
{
foreach ($this->providerLittleEndianEWKB() as [$wkt, $ewkb]) {
yield [$wkt, $ewkb, EWKBTools::LITTLE_ENDIAN];
yield [$wkt, $ewkb, WKBByteOrder::LITTLE_ENDIAN];
}

foreach ($this->providerLittleEndianEWKB_SRID() as [$wkt, $ewkb]) {
yield [$wkt, $ewkb, EWKBTools::LITTLE_ENDIAN];
yield [$wkt, $ewkb, WKBByteOrder::LITTLE_ENDIAN];
}

foreach ($this->providerBigEndianEWKB() as [$wkt, $ewkb]) {
yield [$wkt, $ewkb, EWKBTools::BIG_ENDIAN];
yield [$wkt, $ewkb, WKBByteOrder::BIG_ENDIAN];
}

foreach ($this->providerBigEndianEWKB_SRID() as [$wkt, $ewkb]) {
yield [$wkt, $ewkb, EWKBTools::BIG_ENDIAN];
yield [$wkt, $ewkb, WKBByteOrder::BIG_ENDIAN];
}
}

Expand Down
14 changes: 7 additions & 7 deletions tests/IO/WKBWriterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Brick\Geo\Tests\IO;

use Brick\Geo\Exception\GeometryIOException;
use Brick\Geo\IO\WKBTools;
use Brick\Geo\IO\WKBByteOrder;
use Brick\Geo\IO\WKBWriter;
use Brick\Geo\IO\WKTReader;
use Brick\Geo\Point;
Expand All @@ -18,11 +18,11 @@ class WKBWriterTest extends WKBAbstractTest
/**
* @dataProvider providerWrite
*
* @param string $wkt The WKT to read.
* @param string $wkb The expected WKB output, hex-encoded.
* @param int $byteOrder The byte order to use.
* @param string $wkt The WKT to read.
* @param string $wkb The expected WKB output, hex-encoded.
* @param WKBByteOrder $byteOrder The byte order to use.
*/
public function testWrite(string $wkt, string $wkb, int $byteOrder) : void
public function testWrite(string $wkt, string $wkb, WKBByteOrder $byteOrder) : void
{
$writer = new WKBWriter();
$writer->setByteOrder($byteOrder);
Expand All @@ -38,11 +38,11 @@ public function testWrite(string $wkt, string $wkb, int $byteOrder) : void
public function providerWrite() : \Generator
{
foreach ($this->providerLittleEndianWKB() as [$wkt, $wkb]) {
yield [$wkt, $wkb, WKBTools::LITTLE_ENDIAN];
yield [$wkt, $wkb, WKBByteOrder::LITTLE_ENDIAN];
}

foreach ($this->providerBigEndianWKB() as [$wkt, $wkb]) {
yield [$wkt, $wkb, WKBTools::BIG_ENDIAN];
yield [$wkt, $wkb, WKBByteOrder::BIG_ENDIAN];
}
}

Expand Down

0 comments on commit 6756773

Please sign in to comment.