mirror of
https://github.com/ramsey/uuid.git
synced 2026-06-14 15:56:48 +03:00
Optimize how OrderedTimeCodec rearranges bytes and validates instances
This commit is contained in:
@@ -16,7 +16,7 @@ namespace Ramsey\Uuid\Codec;
|
||||
|
||||
use Ramsey\Uuid\Exception\InvalidArgumentException;
|
||||
use Ramsey\Uuid\Exception\UnsupportedOperationException;
|
||||
use Ramsey\Uuid\Rfc4122\FieldsInterface;
|
||||
use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
@@ -50,16 +50,15 @@ class OrderedTimeCodec extends StringCodec
|
||||
public function encodeBinary(UuidInterface $uuid): string
|
||||
{
|
||||
if (
|
||||
$uuid->getVariant() !== Uuid::RFC_4122
|
||||
|| $uuid->getVersion() !== Uuid::UUID_TYPE_TIME
|
||||
|| !($uuid->getFields() instanceof FieldsInterface)
|
||||
!($uuid->getFields() instanceof Rfc4122FieldsInterface)
|
||||
|| $uuid->getFields()->getVersion() !== Uuid::UUID_TYPE_TIME
|
||||
) {
|
||||
throw new InvalidArgumentException(
|
||||
'Expected RFC 4122 version 1 (time-based) UUID'
|
||||
);
|
||||
}
|
||||
|
||||
/** @var FieldsInterface $fields */
|
||||
/** @var Rfc4122FieldsInterface $fields */
|
||||
$fields = $uuid->getFields();
|
||||
|
||||
$optimized = [
|
||||
@@ -92,24 +91,18 @@ class OrderedTimeCodec extends StringCodec
|
||||
);
|
||||
}
|
||||
|
||||
$unpacked = unpack('H*', $bytes);
|
||||
// Rearrange the bytes to their original order.
|
||||
$rearrangedBytes = substr($bytes, 4, 2)
|
||||
. substr($bytes, 6, 2)
|
||||
. substr($bytes, 2, 2)
|
||||
. substr($bytes, 0, 2)
|
||||
. substr($bytes, 8);
|
||||
|
||||
assert(is_string($unpacked[1]));
|
||||
|
||||
$hex = $unpacked[1];
|
||||
|
||||
// Rearrange the fields to their original order
|
||||
$hex = substr($hex, 8, 4)
|
||||
. substr($hex, 12, 4)
|
||||
. substr($hex, 4, 4)
|
||||
. substr($hex, 0, 4)
|
||||
. substr($hex, 16);
|
||||
|
||||
$uuid = $this->decode($hex);
|
||||
$uuid = parent::decodeBytes($rearrangedBytes);
|
||||
|
||||
if (
|
||||
$uuid->getVariant() !== Uuid::RFC_4122
|
||||
|| $uuid->getVersion() !== Uuid::UUID_TYPE_TIME
|
||||
!($uuid->getFields() instanceof Rfc4122FieldsInterface)
|
||||
|| $uuid->getFields()->getVersion() !== Uuid::UUID_TYPE_TIME
|
||||
) {
|
||||
throw new UnsupportedOperationException(
|
||||
'Attempting to decode a non-time-based UUID using '
|
||||
|
||||
@@ -9,13 +9,17 @@ use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Ramsey\Uuid\Builder\DefaultUuidBuilder;
|
||||
use Ramsey\Uuid\Builder\UuidBuilderInterface;
|
||||
use Ramsey\Uuid\Codec\OrderedTimeCodec;
|
||||
use Ramsey\Uuid\Converter\Number\GenericNumberConverter;
|
||||
use Ramsey\Uuid\Converter\NumberConverterInterface;
|
||||
use Ramsey\Uuid\Converter\Time\GenericTimeConverter;
|
||||
use Ramsey\Uuid\Converter\TimeConverterInterface;
|
||||
use Ramsey\Uuid\Exception\InvalidArgumentException;
|
||||
use Ramsey\Uuid\Exception\UnsupportedOperationException;
|
||||
use Ramsey\Uuid\Math\BrickMathCalculator;
|
||||
use Ramsey\Uuid\Nonstandard\Fields as NonstandardFields;
|
||||
use Ramsey\Uuid\Nonstandard\UuidBuilder;
|
||||
use Ramsey\Uuid\Rfc4122\Fields;
|
||||
use Ramsey\Uuid\Test\TestCase;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidFactory;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
@@ -120,7 +124,8 @@ class OrderedTimeCodecTest extends TestCase
|
||||
{
|
||||
$bytes = (string) hex2bin($this->optimizedHex);
|
||||
|
||||
$numberConverter = Mockery::mock(NumberConverterInterface::class);
|
||||
$calculator = new BrickMathCalculator();
|
||||
$numberConverter = new GenericNumberConverter($calculator);
|
||||
$timeConverter = Mockery::mock(TimeConverterInterface::class);
|
||||
$builder = new DefaultUuidBuilder($numberConverter, $timeConverter);
|
||||
$codec = new OrderedTimeCodec($builder);
|
||||
@@ -138,6 +143,7 @@ class OrderedTimeCodecTest extends TestCase
|
||||
{
|
||||
$nonRfc4122Uuid = '58e0a7d7-eebc-11d8-d669-0800200c9a66';
|
||||
|
||||
$fields = new NonstandardFields((string) hex2bin(str_replace('-', '', $nonRfc4122Uuid)));
|
||||
$numberConverter = Mockery::mock(NumberConverterInterface::class);
|
||||
$timeConverter = Mockery::mock(TimeConverterInterface::class);
|
||||
$builder = new DefaultUuidBuilder($numberConverter, $timeConverter);
|
||||
@@ -146,6 +152,7 @@ class OrderedTimeCodecTest extends TestCase
|
||||
$uuid = Mockery::mock(UuidInterface::class, [
|
||||
'getVariant' => 0,
|
||||
'toString' => $nonRfc4122Uuid,
|
||||
'getFields' => $fields,
|
||||
]);
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
@@ -183,15 +190,12 @@ class OrderedTimeCodecTest extends TestCase
|
||||
$nonRfc4122OptimizedHex = '11d8eebc58e0a7d716690800200c9a66';
|
||||
$bytes = (string) hex2bin($nonRfc4122OptimizedHex);
|
||||
|
||||
$uuid = Mockery::mock(UuidInterface::class, [
|
||||
'getVariant' => Uuid::RESERVED_NCS,
|
||||
]);
|
||||
$calculator = new BrickMathCalculator();
|
||||
$numberConverter = new GenericNumberConverter($calculator);
|
||||
$timeConverter = new GenericTimeConverter($calculator);
|
||||
$builder = new UuidBuilder($numberConverter, $timeConverter);
|
||||
|
||||
$codec = Mockery::mock(OrderedTimeCodec::class, [
|
||||
'decode' => $uuid,
|
||||
]);
|
||||
|
||||
$codec->shouldReceive('decodeBytes')->passthru();
|
||||
$codec = new OrderedTimeCodec($builder);
|
||||
|
||||
$this->expectException(UnsupportedOperationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
|
||||
Reference in New Issue
Block a user