aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/ramsey/uuid/src/Converter/Time
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/ramsey/uuid/src/Converter/Time')
-rw-r--r--vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php58
-rw-r--r--vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php33
-rw-r--r--vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php124
-rw-r--r--vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php168
4 files changed, 309 insertions, 74 deletions
diff --git a/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php
index 112f72272..7390dad83 100644
--- a/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php
+++ b/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php
@@ -1,4 +1,5 @@
<?php
+
/**
* This file is part of the ramsey/uuid library
*
@@ -7,53 +8,44 @@
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
- * @link https://benramsey.com/projects/ramsey-uuid/ Documentation
- * @link https://packagist.org/packages/ramsey/uuid Packagist
- * @link https://github.com/ramsey/uuid GitHub
*/
+declare(strict_types=1);
+
namespace Ramsey\Uuid\Converter\Time;
-use Moontoast\Math\BigNumber;
use Ramsey\Uuid\Converter\TimeConverterInterface;
+use Ramsey\Uuid\Math\BrickMathCalculator;
+use Ramsey\Uuid\Type\Hexadecimal;
+use Ramsey\Uuid\Type\Time;
/**
- * BigNumberTimeConverter uses the moontoast/math library's `BigNumber` to
- * provide facilities for converting parts of time into representations that may
- * be used in UUIDs
+ * 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
{
/**
- * Uses the provided seconds and micro-seconds to calculate the time_low,
- * time_mid, and time_high fields used by RFC 4122 version 1 UUIDs
- *
- * @param string $seconds
- * @param string $microSeconds
- * @return string[] An array containing `low`, `mid`, and `high` keys
- * @link http://tools.ietf.org/html/rfc4122#section-4.2.2
+ * @var TimeConverterInterface
*/
- public function calculateTime($seconds, $microSeconds)
- {
- $uuidTime = new BigNumber('0');
-
- $sec = new BigNumber($seconds);
- $sec->multiply('10000000');
+ private $converter;
- $usec = new BigNumber($microSeconds);
- $usec->multiply('10');
-
- $uuidTime
- ->add($sec)
- ->add($usec)
- ->add('122192928000000000');
+ public function __construct()
+ {
+ $this->converter = new GenericTimeConverter(new BrickMathCalculator());
+ }
- $uuidTimeHex = sprintf('%016s', $uuidTime->convertToBase(16));
+ public function calculateTime(string $seconds, string $microseconds): Hexadecimal
+ {
+ return $this->converter->calculateTime($seconds, $microseconds);
+ }
- return [
- 'low' => substr($uuidTimeHex, 8),
- 'mid' => substr($uuidTimeHex, 4, 4),
- 'hi' => substr($uuidTimeHex, 0, 4),
- ];
+ public function convertTime(Hexadecimal $uuidTimestamp): Time
+ {
+ return $this->converter->convertTime($uuidTimestamp);
}
}
diff --git a/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php
index b94589cd3..cdc28752d 100644
--- a/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php
+++ b/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php
@@ -1,4 +1,5 @@
<?php
+
/**
* This file is part of the ramsey/uuid library
*
@@ -7,36 +8,18 @@
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
- * @link https://benramsey.com/projects/ramsey-uuid/ Documentation
- * @link https://packagist.org/packages/ramsey/uuid Packagist
- * @link https://github.com/ramsey/uuid GitHub
*/
-namespace Ramsey\Uuid\Converter\Time;
+declare(strict_types=1);
-use Ramsey\Uuid\Converter\TimeConverterInterface;
-use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
+namespace Ramsey\Uuid\Converter\Time;
/**
- * DegradedTimeConverter throws `UnsatisfiedDependencyException` exceptions
- * if attempting to use time conversion functionality in an environment that
- * does not support large integers (i.e. when moontoast/math is not available)
+ * @deprecated DegradedTimeConverter is no longer necessary for converting
+ * time on 32-bit systems. Transition to {@see GenericTimeConverter}.
+ *
+ * @psalm-immutable
*/
-class DegradedTimeConverter implements TimeConverterInterface
+class DegradedTimeConverter extends BigNumberTimeConverter
{
- /**
- * Throws an `UnsatisfiedDependencyException`
- *
- * @param string $seconds
- * @param string $microSeconds
- * @return void
- * @throws UnsatisfiedDependencyException if called on a 32-bit system and `Moontoast\Math\BigNumber` is not present
- */
- public function calculateTime($seconds, $microSeconds)
- {
- throw new UnsatisfiedDependencyException(
- 'When calling ' . __METHOD__ . ' on a 32-bit system, '
- . 'Moontoast\Math\BigNumber must be present.'
- );
- }
}
diff --git a/vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php
new file mode 100644
index 000000000..a8aa64b73
--- /dev/null
+++ b/vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php
@@ -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);
+ }
+}
diff --git a/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php
index 57c882dbb..52963fed6 100644
--- a/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php
+++ b/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php
@@ -1,4 +1,5 @@
<?php
+
/**
* This file is part of the ramsey/uuid library
*
@@ -7,41 +8,176 @@
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
- * @link https://benramsey.com/projects/ramsey-uuid/ Documentation
- * @link https://packagist.org/packages/ramsey/uuid Packagist
- * @link https://github.com/ramsey/uuid GitHub
*/
+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
{
/**
- * Uses the provided seconds and micro-seconds to calculate the time_low,
- * time_mid, and time_high fields used by RFC 4122 version 1 UUIDs
+ * 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((int) $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
*
- * @param string $seconds
- * @param string $microSeconds
- * @return string[] An array containing `low`, `mid`, and `high` keys
- * @link http://tools.ietf.org/html/rfc4122#section-4.2.2
+ * @return string[]
*/
- public function calculateTime($seconds, $microSeconds)
+ private function splitTime($time): array
{
- // 0x01b21dd213814000 is the number of 100-ns intervals between the
- // UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
- $uuidTime = ($seconds * 10000000) + ($microSeconds * 10) + 0x01b21dd213814000;
+ $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 [
- 'low' => sprintf('%08x', $uuidTime & 0xffffffff),
- 'mid' => sprintf('%04x', ($uuidTime >> 32) & 0xffff),
- 'hi' => sprintf('%04x', ($uuidTime >> 48) & 0x0fff),
+ 'sec' => $split[0],
+ 'usec' => str_pad((string) $microseconds, 6, '0', STR_PAD_RIGHT),
];
}
}