From 723ef345bf759e4c7ae49a948a1680d51e39b0fa Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 30 Oct 2014 10:16:22 +0100 Subject: [PATCH] Refactor factory functions Remove $littleEndian parameter Add fromGuidString/Bytes factory methods for GUIDs No longer possible to output GUIDs as UUIDs and vice-versa Pass tests --- src/Codec.php | 4 +++- src/Codec/GuidStringCodec.php | 14 +++++++++++--- src/Codec/StringCodec.php | 15 +++++++++++++-- src/Uuid.php | 32 ++++++++++++++------------------ src/UuidInterface.php | 2 ++ tests/UuidTest.php | 10 ++++------ 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/Codec.php b/src/Codec.php index 0e045c7..9912851 100644 --- a/src/Codec.php +++ b/src/Codec.php @@ -4,7 +4,9 @@ namespace Rhumsaa\Uuid; interface Codec { - public function encode(UuidInterface $plainUuid); + public function encode(UuidInterface $uuid); + + public function encodeBinary(UuidInterface $uuid); public function decode($encodedUuid); diff --git a/src/Codec/GuidStringCodec.php b/src/Codec/GuidStringCodec.php index a8afb25..1e03e6e 100644 --- a/src/Codec/GuidStringCodec.php +++ b/src/Codec/GuidStringCodec.php @@ -28,6 +28,13 @@ class GuidStringCodec implements Codec ); } + public function encodeBinary(UuidInterface $uuid) + { + $reversed = $this->_decode($this->encode($uuid), false); + + return (new StringCodec())->encodeBinary($reversed); + } + public function decode($encodedUuid) { return $this->_decode($encodedUuid, true); @@ -41,7 +48,7 @@ class GuidStringCodec implements Codec $hexUuid = unpack('H*', $bytes); - return $this->_decode($hexUuid, false); + return $this->_decode($hexUuid[1], false); } private function _decode($hex, $swap) @@ -72,11 +79,12 @@ class GuidStringCodec implements Codec $components[1] = $hex[1]; $hex = unpack('H*', pack('v', hexdec($components[2]))); $components[2] = $hex[1]; - $nameParsed = implode('-', $components); } + $nameParsed = implode('-', $components); + if (! Uuid::isValid($nameParsed)) { - throw new InvalidArgumentException('Invalid UUID string: ' . $name); + throw new InvalidArgumentException('Invalid UUID string: ' . $hex); } $fields = array( diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php index a65f108..b787a6e 100644 --- a/src/Codec/StringCodec.php +++ b/src/Codec/StringCodec.php @@ -20,6 +20,17 @@ class StringCodec implements Codec ); } + public function encodeBinary(UuidInterface $uuid) + { + $bytes = ''; + + foreach (range(-2, -32, 2) as $step) { + $bytes = chr(hexdec(substr($uuid->getHex(), $step, 2))) . $bytes; + } + + return $bytes; + } + public function decode($encodedUuid) { $nameParsed = str_replace(array( @@ -44,7 +55,7 @@ class StringCodec implements Codec $nameParsed = implode('-', $components); if (! Uuid::isValid($nameParsed)) { - throw new InvalidArgumentException('Invalid UUID string: ' . $name); + throw new InvalidArgumentException('Invalid UUID string: ' . $encodedUuid); } $fields = array( @@ -67,6 +78,6 @@ class StringCodec implements Codec $hexUuid = unpack('H*', $bytes); - return $this->decode($hexUuid); + return $this->decode($hexUuid[1]); } } diff --git a/src/Uuid.php b/src/Uuid.php index 4cdbddc..3cc6d69 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -258,13 +258,7 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public function getBytes() { - $bytes = ''; - - foreach (range(-2, -32, 2) as $step) { - $bytes = chr(hexdec(substr($this->getHex(), $step, 2))) . $bytes; - } - - return $bytes; + return $this->codec->encodeBinary($this); } /** @@ -845,7 +839,7 @@ final class Uuid implements UuidInterface, \JsonSerializable * * @return string */ - public function toString($forceBigEndian = false) + public function toString() { return $this->codec->encode($this); } @@ -857,15 +851,16 @@ final class Uuid implements UuidInterface, \JsonSerializable * @return Uuid * @throws InvalidArgumentException If the $bytes string does not contain 16 characters */ - public static function fromBytes($bytes, $littleEndian = false) + public static function fromBytes($bytes) { - if ($littleEndian) { - return (new GuidStringCodec())->decodeBytes($bytes); - } - return (new StringCodec())->decodeBytes($bytes); } + public static function fromGuidBytes($bytes) + { + return (new GuidStringCodec())->decodeBytes($bytes); + } + /** * Creates a UUID from the string standard representation as described * in the toString() method. @@ -875,15 +870,16 @@ final class Uuid implements UuidInterface, \JsonSerializable * @return Uuid * @throws InvalidArgumentException If the $name isn't a valid UUID */ - public static function fromString($name, $littleEndian = false) + public static function fromString($name) { - if ($littleEndian) { - return (new GuidStringCodec())->decode($name); - } - return (new StringCodec())->decode($name); } + public static function fromGuidString($name) + { + return (new GuidStringCodec())->decode($name); + } + /** * Creates a UUID from either the UUID as a 128-bit integer string or a Moontoast\Math\BigNumber object. * diff --git a/src/UuidInterface.php b/src/UuidInterface.php index d268ff2..f82f161 100644 --- a/src/UuidInterface.php +++ b/src/UuidInterface.php @@ -9,6 +9,8 @@ interface UuidInterface public function equals($other); + public function getHex(); + public function getFieldsHex(); public function getClockSeqHiAndReservedHex(); diff --git a/tests/UuidTest.php b/tests/UuidTest.php index fe56804..a601b20 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -29,7 +29,7 @@ class UuidTest extends TestCase public function testFromLittleEndianString() { $uuid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); - $guid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66', true); + $guid = Uuid::fromGuidString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $guid); // UUID's and GUID's share the same textual representation @@ -1456,18 +1456,16 @@ class UuidTest extends TestCase $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bytes = $uuid->getBytes(); - $guid = Uuid::fromBytes($bytes, true); + $guid = Uuid::fromGuidBytes($bytes); // First three fields should be reversed $this->assertEquals('b08c6fff-7dc5-e111-9b21-0800200c9a66', $guid->toString()); - // Except if forcing big endian - $this->assertEquals($uuid->toString(), $guid->toString(true)); // Check that parsing LE bytes as LE preserves fields - $guid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', true); + $guid = Uuid::fromGuidString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bytes = $guid->getBytes(); - $parsedGuid = Uuid::fromBytes($bytes, true); + $parsedGuid = Uuid::fromGuidBytes($bytes); $this->assertEquals($guid->toString(), $parsedGuid->toString()); }