Primo Committ

This commit is contained in:
paoloar77
2024-05-07 12:17:25 +02:00
commit e73d0e5113
7204 changed files with 884387 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter\Number;
use Ramsey\Uuid\Converter\NumberConverterInterface;
use Ramsey\Uuid\Math\BrickMathCalculator;
/**
* Previously used to integrate moontoast/math as a bignum arithmetic library,
* BigNumberConverter is deprecated in favor of GenericNumberConverter
*
* @deprecated Transition to {@see GenericNumberConverter}.
*
* @psalm-immutable
*/
class BigNumberConverter implements NumberConverterInterface
{
/**
* @var NumberConverterInterface
*/
private $converter;
public function __construct()
{
$this->converter = new GenericNumberConverter(new BrickMathCalculator());
}
/**
* @inheritDoc
* @psalm-pure
*/
public function fromHex(string $hex): string
{
return $this->converter->fromHex($hex);
}
/**
* @inheritDoc
* @psalm-pure
*/
public function toHex(string $number): string
{
return $this->converter->toHex($number);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter\Number;
/**
* @deprecated DegradedNumberConverter is no longer necessary for converting
* numbers on 32-bit systems. Transition to {@see GenericNumberConverter}.
*
* @psalm-immutable
*/
class DegradedNumberConverter extends BigNumberConverter
{
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter\Number;
use Ramsey\Uuid\Converter\NumberConverterInterface;
use Ramsey\Uuid\Math\CalculatorInterface;
use Ramsey\Uuid\Type\Integer as IntegerObject;
/**
* GenericNumberConverter uses the provided calculator to convert decimal
* numbers to and from hexadecimal values
*
* @psalm-immutable
*/
class GenericNumberConverter implements NumberConverterInterface
{
/**
* @var CalculatorInterface
*/
private $calculator;
public function __construct(CalculatorInterface $calculator)
{
$this->calculator = $calculator;
}
/**
* @inheritDoc
* @psalm-pure
* @psalm-return numeric-string
* @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty
* @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty
*/
public function fromHex(string $hex): string
{
return $this->calculator->fromBase($hex, 16)->toString();
}
/**
* @inheritDoc
* @psalm-pure
* @psalm-return non-empty-string
* @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty
* @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty
*/
public function toHex(string $number): string
{
/** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */
return $this->calculator->toBase(new IntegerObject($number), 16);
}
}

View File

@@ -0,0 +1,57 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter;
/**
* A number converter converts UUIDs from hexadecimal characters into
* representations of integers and vice versa
*
* @psalm-immutable
*/
interface NumberConverterInterface
{
/**
* Converts a hexadecimal number into an string integer representation of
* the number
*
* The integer representation returned is a string representation of the
* integer, to accommodate unsigned integers greater than PHP_INT_MAX.
*
* @param string $hex The hexadecimal string representation to convert
*
* @return string String representation of an integer
*
* @psalm-return numeric-string
*
* @psalm-pure
*/
public function fromHex(string $hex): string;
/**
* Converts a string integer representation into a hexadecimal string
* representation of the number
*
* @param string $number A string integer representation to convert; this
* must be a numeric string to accommodate unsigned integers greater
* than PHP_INT_MAX.
*
* @return string Hexadecimal string
*
* @psalm-return non-empty-string
*
* @psalm-pure
*/
public function toHex(string $number): string;
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter\Time;
use Ramsey\Uuid\Converter\TimeConverterInterface;
use Ramsey\Uuid\Math\BrickMathCalculator;
use Ramsey\Uuid\Type\Hexadecimal;
use Ramsey\Uuid\Type\Time;
/**
* Previously used to integrate moontoast/math as a bignum arithmetic library,
* BigNumberTimeConverter is deprecated in favor of GenericTimeConverter
*
* @deprecated Transition to {@see GenericTimeConverter}.
*
* @psalm-immutable
*/
class BigNumberTimeConverter implements TimeConverterInterface
{
/**
* @var TimeConverterInterface
*/
private $converter;
public function __construct()
{
$this->converter = new GenericTimeConverter(new BrickMathCalculator());
}
public function calculateTime(string $seconds, string $microseconds): Hexadecimal
{
return $this->converter->calculateTime($seconds, $microseconds);
}
public function convertTime(Hexadecimal $uuidTimestamp): Time
{
return $this->converter->convertTime($uuidTimestamp);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter\Time;
/**
* @deprecated DegradedTimeConverter is no longer necessary for converting
* time on 32-bit systems. Transition to {@see GenericTimeConverter}.
*
* @psalm-immutable
*/
class DegradedTimeConverter extends BigNumberTimeConverter
{
}

View File

@@ -0,0 +1,124 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter\Time;
use Ramsey\Uuid\Converter\TimeConverterInterface;
use Ramsey\Uuid\Math\CalculatorInterface;
use Ramsey\Uuid\Math\RoundingMode;
use Ramsey\Uuid\Type\Hexadecimal;
use Ramsey\Uuid\Type\Integer as IntegerObject;
use Ramsey\Uuid\Type\Time;
use function explode;
use function str_pad;
use const STR_PAD_LEFT;
/**
* GenericTimeConverter uses the provided calculator to calculate and convert
* time values
*
* @psalm-immutable
*/
class GenericTimeConverter implements TimeConverterInterface
{
/**
* The number of 100-nanosecond intervals from the Gregorian calendar epoch
* to the Unix epoch.
*/
private const GREGORIAN_TO_UNIX_INTERVALS = '122192928000000000';
/**
* The number of 100-nanosecond intervals in one second.
*/
private const SECOND_INTERVALS = '10000000';
/**
* The number of 100-nanosecond intervals in one microsecond.
*/
private const MICROSECOND_INTERVALS = '10';
/**
* @var CalculatorInterface
*/
private $calculator;
public function __construct(CalculatorInterface $calculator)
{
$this->calculator = $calculator;
}
public function calculateTime(string $seconds, string $microseconds): Hexadecimal
{
$timestamp = new Time($seconds, $microseconds);
// Convert the seconds into a count of 100-nanosecond intervals.
$sec = $this->calculator->multiply(
$timestamp->getSeconds(),
new IntegerObject(self::SECOND_INTERVALS)
);
// Convert the microseconds into a count of 100-nanosecond intervals.
$usec = $this->calculator->multiply(
$timestamp->getMicroseconds(),
new IntegerObject(self::MICROSECOND_INTERVALS)
);
// Combine the seconds and microseconds intervals and add the count of
// 100-nanosecond intervals from the Gregorian calendar epoch to the
// Unix epoch. This gives us the correct count of 100-nanosecond
// intervals since the Gregorian calendar epoch for the given seconds
// and microseconds.
/** @var IntegerObject $uuidTime */
$uuidTime = $this->calculator->add(
$sec,
$usec,
new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS)
);
$uuidTimeHex = str_pad(
$this->calculator->toHexadecimal($uuidTime)->toString(),
16,
'0',
STR_PAD_LEFT
);
return new Hexadecimal($uuidTimeHex);
}
public function convertTime(Hexadecimal $uuidTimestamp): Time
{
// From the total, subtract the number of 100-nanosecond intervals from
// the Gregorian calendar epoch to the Unix epoch. This gives us the
// number of 100-nanosecond intervals from the Unix epoch, which also
// includes the microtime.
$epochNanoseconds = $this->calculator->subtract(
$this->calculator->toInteger($uuidTimestamp),
new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS)
);
// Convert the 100-nanosecond intervals into seconds and microseconds.
$unixTimestamp = $this->calculator->divide(
RoundingMode::HALF_UP,
6,
$epochNanoseconds,
new IntegerObject(self::SECOND_INTERVALS)
);
$split = explode('.', (string) $unixTimestamp, 2);
return new Time($split[0], $split[1] ?? 0);
}
}

View File

@@ -0,0 +1,183 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter\Time;
use Ramsey\Uuid\Converter\TimeConverterInterface;
use Ramsey\Uuid\Math\BrickMathCalculator;
use Ramsey\Uuid\Math\CalculatorInterface;
use Ramsey\Uuid\Type\Hexadecimal;
use Ramsey\Uuid\Type\Integer as IntegerObject;
use Ramsey\Uuid\Type\Time;
use function count;
use function dechex;
use function explode;
use function is_float;
use function is_int;
use function str_pad;
use function strlen;
use function substr;
use const STR_PAD_LEFT;
use const STR_PAD_RIGHT;
/**
* PhpTimeConverter uses built-in PHP functions and standard math operations
* available to the PHP programming language to provide facilities for
* converting parts of time into representations that may be used in UUIDs
*
* @psalm-immutable
*/
class PhpTimeConverter implements TimeConverterInterface
{
/**
* The number of 100-nanosecond intervals from the Gregorian calendar epoch
* to the Unix epoch.
*/
private const GREGORIAN_TO_UNIX_INTERVALS = 0x01b21dd213814000;
/**
* The number of 100-nanosecond intervals in one second.
*/
private const SECOND_INTERVALS = 10000000;
/**
* The number of 100-nanosecond intervals in one microsecond.
*/
private const MICROSECOND_INTERVALS = 10;
/**
* @var CalculatorInterface
*/
private $calculator;
/**
* @var TimeConverterInterface
*/
private $fallbackConverter;
/**
* @var int
*/
private $phpPrecision;
public function __construct(
?CalculatorInterface $calculator = null,
?TimeConverterInterface $fallbackConverter = null
) {
if ($calculator === null) {
$calculator = new BrickMathCalculator();
}
if ($fallbackConverter === null) {
$fallbackConverter = new GenericTimeConverter($calculator);
}
$this->calculator = $calculator;
$this->fallbackConverter = $fallbackConverter;
$this->phpPrecision = (int) ini_get('precision');
}
public function calculateTime(string $seconds, string $microseconds): Hexadecimal
{
$seconds = new IntegerObject($seconds);
$microseconds = new IntegerObject($microseconds);
// Calculate the count of 100-nanosecond intervals since the Gregorian
// calendar epoch for the given seconds and microseconds.
$uuidTime = ((int) $seconds->toString() * self::SECOND_INTERVALS)
+ ((int) $microseconds->toString() * self::MICROSECOND_INTERVALS)
+ self::GREGORIAN_TO_UNIX_INTERVALS;
// Check to see whether we've overflowed the max/min integer size.
// If so, we will default to a different time converter.
/** @psalm-suppress RedundantCondition */
if (!is_int($uuidTime)) {
return $this->fallbackConverter->calculateTime(
$seconds->toString(),
$microseconds->toString()
);
}
return new Hexadecimal(str_pad(dechex($uuidTime), 16, '0', STR_PAD_LEFT));
}
public function convertTime(Hexadecimal $uuidTimestamp): Time
{
$timestamp = $this->calculator->toInteger($uuidTimestamp);
// Convert the 100-nanosecond intervals into seconds and microseconds.
$splitTime = $this->splitTime(
((int) $timestamp->toString() - self::GREGORIAN_TO_UNIX_INTERVALS)
/ self::SECOND_INTERVALS
);
if (count($splitTime) === 0) {
return $this->fallbackConverter->convertTime($uuidTimestamp);
}
return new Time($splitTime['sec'], $splitTime['usec']);
}
/**
* @param int|float $time The time to split into seconds and microseconds
*
* @return string[]
*/
private function splitTime($time): array
{
$split = explode('.', (string) $time, 2);
// If the $time value is a float but $split only has 1 element, then the
// float math was rounded up to the next second, so we want to return
// an empty array to allow use of the fallback converter.
if (is_float($time) && count($split) === 1) {
return [];
}
if (count($split) === 1) {
return [
'sec' => $split[0],
'usec' => '0',
];
}
// If the microseconds are less than six characters AND the length of
// the number is greater than or equal to the PHP precision, then it's
// possible that we lost some precision for the microseconds. Return an
// empty array, so that we can choose to use the fallback converter.
if (strlen($split[1]) < 6 && strlen((string) $time) >= $this->phpPrecision) {
return [];
}
$microseconds = $split[1];
// Ensure the microseconds are no longer than 6 digits. If they are,
// truncate the number to the first 6 digits and round up, if needed.
if (strlen($microseconds) > 6) {
$roundingDigit = (int) substr($microseconds, 6, 1);
$microseconds = (int) substr($microseconds, 0, 6);
if ($roundingDigit >= 5) {
$microseconds++;
}
}
return [
'sec' => $split[0],
'usec' => str_pad((string) $microseconds, 6, '0', STR_PAD_RIGHT),
];
}
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Converter;
use Ramsey\Uuid\Type\Hexadecimal;
use Ramsey\Uuid\Type\Time;
/**
* A time converter converts timestamps into representations that may be used
* in UUIDs
*
* @psalm-immutable
*/
interface TimeConverterInterface
{
/**
* Uses the provided seconds and micro-seconds to calculate the count of
* 100-nanosecond intervals since UTC 00:00:00.00, 15 October 1582, for
* RFC 4122 variant UUIDs
*
* @link http://tools.ietf.org/html/rfc4122#section-4.2.2 RFC 4122, § 4.2.2: Generation Details
*
* @param string $seconds A string representation of the number of seconds
* since the Unix epoch for the time to calculate
* @param string $microseconds A string representation of the micro-seconds
* associated with the time to calculate
*
* @return Hexadecimal The full UUID timestamp as a Hexadecimal value
*
* @psalm-pure
*/
public function calculateTime(string $seconds, string $microseconds): Hexadecimal;
/**
* Converts a timestamp extracted from a UUID to a Unix timestamp
*
* @param Hexadecimal $uuidTimestamp A hexadecimal representation of a UUID
* timestamp; a UUID timestamp is a count of 100-nanosecond intervals
* since UTC 00:00:00.00, 15 October 1582.
*
* @return Time An instance of {@see Time}
*
* @psalm-pure
*/
public function convertTime(Hexadecimal $uuidTimestamp): Time;
}