summaryrefslogtreecommitdiffstats
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.php51
-rw-r--r--vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php25
-rw-r--r--vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php124
-rw-r--r--vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php183
4 files changed, 383 insertions, 0 deletions
diff --git a/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php
new file mode 100644
index 0000000..7390dad
--- /dev/null
+++ b/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php
@@ -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);
+ }
+}
diff --git a/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php
new file mode 100644
index 0000000..cdc2875
--- /dev/null
+++ b/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php
@@ -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
+{
+}
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 0000000..a8aa64b
--- /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
new file mode 100644
index 0000000..538d2f2
--- /dev/null
+++ b/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php
@@ -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),
+ ];
+ }
+}