Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  declare(strict_types=1);
   3  
   4  namespace ZipStream;
   5  
   6  use OverflowException;
   7  
   8  class Bigint
   9  {
  10      /**
  11       * @var int[]
  12       */
  13      private $bytes = [0, 0, 0, 0, 0, 0, 0, 0];
  14  
  15      /**
  16       * Initialize the bytes array
  17       *
  18       * @param int $value
  19       */
  20      public function __construct(int $value = 0)
  21      {
  22          $this->fillBytes($value, 0, 8);
  23      }
  24  
  25      /**
  26       * Fill the bytes field with int
  27       *
  28       * @param int $value
  29       * @param int $start
  30       * @param int $count
  31       * @return void
  32       */
  33      protected function fillBytes(int $value, int $start, int $count): void
  34      {
  35          for ($i = 0; $i < $count; $i++) {
  36              $this->bytes[$start + $i] = $i >= PHP_INT_SIZE ? 0 : $value & 0xFF;
  37              $value >>= 8;
  38          }
  39      }
  40  
  41      /**
  42       * Get an instance
  43       *
  44       * @param int $value
  45       * @return Bigint
  46       */
  47      public static function init(int $value = 0): self
  48      {
  49          return new self($value);
  50      }
  51  
  52      /**
  53       * Fill bytes from low to high
  54       *
  55       * @param int $low
  56       * @param int $high
  57       * @return Bigint
  58       */
  59      public static function fromLowHigh(int $low, int $high): self
  60      {
  61          $bigint = new Bigint();
  62          $bigint->fillBytes($low, 0, 4);
  63          $bigint->fillBytes($high, 4, 4);
  64          return $bigint;
  65      }
  66  
  67      /**
  68       * Get high 32
  69       *
  70       * @return int
  71       */
  72      public function getHigh32(): int
  73      {
  74          return $this->getValue(4, 4);
  75      }
  76  
  77      /**
  78       * Get value from bytes array
  79       *
  80       * @param int $end
  81       * @param int $length
  82       * @return int
  83       */
  84      public function getValue(int $end = 0, int $length = 8): int
  85      {
  86          $result = 0;
  87          for ($i = $end + $length - 1; $i >= $end; $i--) {
  88              $result <<= 8;
  89              $result |= $this->bytes[$i];
  90          }
  91          return $result;
  92      }
  93  
  94      /**
  95       * Get low FF
  96       *
  97       * @param bool $force
  98       * @return float
  99       */
 100      public function getLowFF(bool $force = false): float
 101      {
 102          if ($force || $this->isOver32()) {
 103              return (float)0xFFFFFFFF;
 104          }
 105          return (float)$this->getLow32();
 106      }
 107  
 108      /**
 109       * Check if is over 32
 110       *
 111       * @psalm-suppress ArgumentTypeCoercion
 112       * @param bool $force
 113       * @return bool
 114       */
 115      public function isOver32(bool $force = false): bool
 116      {
 117          // value 0xFFFFFFFF already needs a Zip64 header
 118          return $force ||
 119              max(array_slice($this->bytes, 4, 4)) > 0 ||
 120              min(array_slice($this->bytes, 0, 4)) === 0xFF;
 121      }
 122  
 123      /**
 124       * Get low 32
 125       *
 126       * @return int
 127       */
 128      public function getLow32(): int
 129      {
 130          return $this->getValue(0, 4);
 131      }
 132  
 133      /**
 134       * Get hexadecimal
 135       *
 136       * @return string
 137       */
 138      public function getHex64(): string
 139      {
 140          $result = '0x';
 141          for ($i = 7; $i >= 0; $i--) {
 142              $result .= sprintf('%02X', $this->bytes[$i]);
 143          }
 144          return $result;
 145      }
 146  
 147      /**
 148       * Add
 149       *
 150       * @param Bigint $other
 151       * @return Bigint
 152       */
 153      public function add(Bigint $other): Bigint
 154      {
 155          $result = clone $this;
 156          $overflow = false;
 157          for ($i = 0; $i < 8; $i++) {
 158              $result->bytes[$i] += $other->bytes[$i];
 159              if ($overflow) {
 160                  $result->bytes[$i]++;
 161                  $overflow = false;
 162              }
 163              if ($result->bytes[$i] & 0x100) {
 164                  $overflow = true;
 165                  $result->bytes[$i] &= 0xFF;
 166              }
 167          }
 168          if ($overflow) {
 169              throw new OverflowException;
 170          }
 171          return $result;
 172      }
 173  }