6TF9鱈o3GwY9"rwU7bTyYHT hwigCt汾|I ?i{"3;`gC[A3t,/)>:(>][!kʿ0t$y}w_PUpT֢n Y'f^YQ=8/\N%5LWC" qZP8 Bΐ\D,r^6.:YE$dxOz#+juq+_NAzq6 xk;4PŨ] ėk}_Eo}Map]EamQʐ\w%?OllmOz#+juq+_NAҟxn (yۢf Dp=fXJpSM1~)Hys)*-MqdIse[#QЭmfqn_άV-sO}x|XN:>G_G73ծ&mV)v }2[HA&L9KH4|M4n [o/y6?O2 ǫbMcʟ_̢$:xt!oб $!tQuzu#V_#|r "*kgd7 LXބ *iG8CfC\CT2:һ2]=+=B;mLg;C F_녻uwgxp>0-0%^EObu@)2?6.&Lk>X`_SpdσBEYZڨD۵lUTXyѻ%;jPz):n]+LU<%H;p(8:E4~<ɡz"E_1$r빷JCNN<bK` L#Y{ s諷k>|\FIz!HlA6<M/?RsrL{A*vrl:Z_ :l r0/]|SWC '-+r?[c9/>]gm^]І5 fJhf?H|)֩9s.$R&ctSX`c1%ug:}@bne K|=³Hٳ %T]@]4C_c_Kjw:һ2]{CMg,ϫޅt`;!Ah΋zQ +Ǧ>'nU=|S!n4VxodXGWNgR~J")ye8jy,ĿqL(NF:|WM3ꗧu?3?,Sim{}  YVnum?H}D foK-~M#j p(8:E4~u#͜7$jRgՄW[%E,)c|(qsG6ۛ >E3ݽy@ؔ'޶Uybi[ir%80F@pFvCNB}_+2}o ̹`";brc{}/2''лQդwH|Ywθ4, ou@)2?Au8$amEsm-**D];.fWͿ&DZ8 (wu>Pq3u}+oQ~_'ZX610bg&Ar2K$q=+=B;m!uJ ]9{f;lh+7I.*r%\ԵXrR+RgA-Kz  k3b}b%̗\<'Jhc $nL17o}VJ\}.hۓט笼jZo ~g%M/a'w,_t!M9%R.= ?YE75e[I+k,2Ck21z8턾^qX J q #t n>Y%'-+r?r9DЇQzb+XNAGCKJ9,?~j1!"PJGB5-Hw A\-JzE&O|9eU'JuֆQ/Fk/E_{NNUE"L"!Y躳Wبcui )+D˴D5E6aW?zdOi4 "Y n{c&x"U2$\$ҥ w`ܿK~V/bAK8`G>.³a̗JS@z ң.C[PK'5rj8p n)c|(qsGN_3%3|@꿀/Xԟ{}JR7lُ *^˻UH%^~حuhn\uݢ&'rS?Mu!<"ϛU*V3Wк4&kRr*_bits[$i] = $this->bits[$i] | $mask; } } /** * Clears the bit array, unsetting every bit. */ public function clear() : void { $bitsLength = count($this->bits); for ($i = 0; $i < $bitsLength; ++$i) { $this->bits[$i] = 0; } } /** * Checks if a range of bits is set or not set. * @throws InvalidArgumentException if end is smaller than start */ public function isRange(int $start, int $end, bool $value) : bool { if ($end < $start) { throw new InvalidArgumentException('End must be greater or equal to start'); } if ($end === $start) { return true; } --$end; $firstInt = $start >> 5; $lastInt = $end >> 5; for ($i = $firstInt; $i <= $lastInt; ++$i) { $firstBit = $i > $firstInt ? 0 : $start & 0x1f; $lastBit = $i < $lastInt ? 31 : $end & 0x1f; if (0 === $firstBit && 31 === $lastBit) { $mask = 0x7fffffff; } else { $mask = 0; for ($j = $firstBit; $j <= $lastBit; ++$j) { $mask |= 1 << $j; } } if (($this->bits[$i] & $mask) !== ($value ? $mask : 0)) { return false; } } return true; } /** * Appends a bit to the array. */ public function appendBit(bool $bit) : void { $this->ensureCapacity($this->size + 1); if ($bit) { $this->bits[$this->size >> 5] = $this->bits[$this->size >> 5] | (1 << ($this->size & 0x1f)); } ++$this->size; } /** * Appends a number of bits (up to 32) to the array. * @throws InvalidArgumentException if num bits is not between 0 and 32 */ public function appendBits(int $value, int $numBits) : void { if ($numBits < 0 || $numBits > 32) { throw new InvalidArgumentException('Num bits must be between 0 and 32'); } $this->ensureCapacity($this->size + $numBits); for ($numBitsLeft = $numBits; $numBitsLeft > 0; $numBitsLeft--) { $this->appendBit((($value >> ($numBitsLeft - 1)) & 0x01) === 1); } } /** * Appends another bit array to this array. */ public function appendBitArray(self $other) : void { $otherSize = $other->getSize(); $this->ensureCapacity($this->size + $other->getSize()); for ($i = 0; $i < $otherSize; ++$i) { $this->appendBit($other->get($i)); } } /** * Makes an exclusive-or comparision on the current bit array. * * @throws InvalidArgumentException if sizes don't match */ public function xorBits(self $other) : void { $bitsLength = count($this->bits); $otherBits = $other->getBitArray(); if ($bitsLength !== count($otherBits)) { throw new InvalidArgumentException('Sizes don\'t match'); } for ($i = 0; $i < $bitsLength; ++$i) { $this->bits[$i] = $this->bits[$i] ^ $otherBits[$i]; } } /** * Converts the bit array to a byte array. * * @return SplFixedArray */ public function toBytes(int $bitOffset, int $numBytes) : SplFixedArray { $bytes = new SplFixedArray($numBytes); for ($i = 0; $i < $numBytes; ++$i) { $byte = 0; for ($j = 0; $j < 8; ++$j) { if ($this->get($bitOffset)) { $byte |= 1 << (7 - $j); } ++$bitOffset; } $bytes[$i] = $byte; } return $bytes; } /** * Gets the internal bit array. * * @return SplFixedArray */ public function getBitArray() : SplFixedArray { return $this->bits; } /** * Reverses the array. */ public function reverse() : void { $newBits = new SplFixedArray(count($this->bits)); for ($i = 0; $i < $this->size; ++$i) { if ($this->get($this->size - $i - 1)) { $newBits[$i >> 5] = $newBits[$i >> 5] | (1 << ($i & 0x1f)); } } $this->bits = $newBits; } /** * Returns a string representation of the bit array. */ public function __toString() : string { $result = ''; for ($i = 0; $i < $this->size; ++$i) { if (0 === ($i & 0x07)) { $result .= ' '; } $result .= $this->get($i) ? 'X' : '.'; } return $result; } }