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