Kaynağa Gözat

:bath: too many static calls in here

smiley 1 ay önce
ebeveyn
işleme
490cc43b47

+ 1 - 1
phpstan-baseline.neon

@@ -253,7 +253,7 @@ parameters:
 			path: tests/Data/DataInterfaceTestAbstract.php
 
 		-
-			rawMessage: 'Parameter #1 $data of class chillerlan\QRCode\Data\Byte constructor expects string, string|false given.'
+			rawMessage: 'Parameter #1 $data of class chillerlan\QRCode\Data\Byte constructor expects string|null, string|false given.'
 			identifier: argument.type
 			count: 1
 			path: tests/Data/ECITest.php

+ 7 - 7
src/Data/AlphaNum.php

@@ -44,7 +44,7 @@ final class AlphaNum extends QRDataModeAbstract{
 
 		$bitBuffer
 			->put(self::DATAMODE, 4)
-			->put($len, $this::getLengthBits($versionNumber))
+			->put($len, $this->getLengthBits($versionNumber))
 		;
 
 		// encode 2 characters in 11 bits
@@ -68,8 +68,8 @@ final class AlphaNum extends QRDataModeAbstract{
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
-		$length = $bitBuffer->read(self::getLengthBits($versionNumber));
+	public function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
+		$length = $bitBuffer->read($this->getLengthBits($versionNumber));
 		$result = '';
 		// Read two characters at a time
 		while($length > 1){
@@ -79,8 +79,8 @@ final class AlphaNum extends QRDataModeAbstract{
 			}
 
 			$nextTwoCharsBits  = $bitBuffer->read(11);
-			$result           .= self::chr(intdiv($nextTwoCharsBits, 45));
-			$result           .= self::chr($nextTwoCharsBits % 45);
+			$result           .= $this->chr(intdiv($nextTwoCharsBits, 45));
+			$result           .= $this->chr($nextTwoCharsBits % 45);
 			$length           -= 2;
 		}
 
@@ -90,7 +90,7 @@ final class AlphaNum extends QRDataModeAbstract{
 				throw new QRCodeDataException('not enough bits available'); // @codeCoverageIgnore
 			}
 
-			$result .= self::chr($bitBuffer->read(6));
+			$result .= $this->chr($bitBuffer->read(6));
 		}
 
 		return $result;
@@ -113,7 +113,7 @@ final class AlphaNum extends QRDataModeAbstract{
 	/**
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	private static function chr(int $ord):string{
+	private function chr(int $ord):string{
 
 		if($ord < 0 || $ord > 44){
 			throw new QRCodeDataException('invalid character code'); // @codeCoverageIgnore

+ 3 - 3
src/Data/Byte.php

@@ -37,7 +37,7 @@ final class Byte extends QRDataModeAbstract{
 
 		$bitBuffer
 			->put(self::DATAMODE, 4)
-			->put($len, $this::getLengthBits($versionNumber))
+			->put($len, $this->getLengthBits($versionNumber))
 		;
 
 		$i = 0;
@@ -55,8 +55,8 @@ final class Byte extends QRDataModeAbstract{
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
-		$length = $bitBuffer->read(self::getLengthBits($versionNumber));
+	public function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
+		$length = $bitBuffer->read($this->getLengthBits($versionNumber));
 
 		if($bitBuffer->available() < (8 * $length)){
 			throw new QRCodeDataException('not enough bits available'); // @codeCoverageIgnore

+ 20 - 14
src/Data/ECI.php

@@ -26,22 +26,26 @@ final class ECI extends QRDataModeAbstract{
 	public const DATAMODE = Mode::ECI;
 
 	/**
-	 * The current ECI encoding id
+	 * The current ECI encoding id (default to UTF-8)
 	 */
-	private int $encoding;
+	private int $encoding = ECICharset::ISO_IEC_10646_UTF_8;
 
 	/**
 	 * @inheritDoc
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 * @noinspection PhpMissingParentConstructorInspection
 	 */
-	public function __construct(int $encoding){
+	public function __construct(int|null $encoding = null){
 
-		if($encoding < 0 || $encoding > 999999){
-			throw new QRCodeDataException(sprintf('invalid encoding id: "%s"', $encoding));
+		if($encoding !== null){
+
+			if($encoding < 0 || $encoding > 999999){
+				throw new QRCodeDataException(sprintf('invalid encoding id: "%s"', $encoding));
+			}
+
+			$this->encoding = $encoding;
 		}
 
-		$this->encoding = $encoding;
 	}
 
 	public function getLengthInBits():int{
@@ -76,7 +80,7 @@ final class ECI extends QRDataModeAbstract{
 			$bitBuffer->put(($this->encoding | 0xC00000), 24);
 		}
 		else{
-			throw new QRCodeDataException('invalid ECI ID');
+			throw new QRCodeDataException('invalid ECI ID'); // @codeCoverageIgnore
 		}
 
 		return $this;
@@ -87,7 +91,7 @@ final class ECI extends QRDataModeAbstract{
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public static function parseValue(BitBuffer $bitBuffer):ECICharset{
+	public function parseValue(BitBuffer $bitBuffer):ECICharset{
 		$firstByte = $bitBuffer->read(8);
 
 		// just one byte
@@ -121,23 +125,25 @@ final class ECI extends QRDataModeAbstract{
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
-		$eciCharset = self::parseValue($bitBuffer);
+	public function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
+		$eciCharset = $this->parseValue($bitBuffer);
 		$nextMode   = $bitBuffer->read(4);
 		$encoding   = $eciCharset->getName();
 
 		// this is definitely weird, but there are QR Codes out in the wild
 		// that have ECI followed by numeric and alphanum segments
 		// @see https://github.com/chillerlan/php-qrcode/discussions/289
-		$data = match($nextMode){
-			Mode::NUMBER   => Number::decodeSegment($bitBuffer, $versionNumber),
-			Mode::ALPHANUM => AlphaNum::decodeSegment($bitBuffer, $versionNumber),
-			Mode::BYTE     => Byte::decodeSegment($bitBuffer, $versionNumber),
+		$dataMode = match($nextMode){
+			Mode::NUMBER   => new Number,
+			Mode::ALPHANUM => new AlphaNum,
+			Mode::BYTE     => new Byte,
 			default        => throw new QRCodeDataException(
 				sprintf('ECI designator followed by invalid mode: "%04b"', $nextMode),
 			),
 		};
 
+		$data = $dataMode->decodeSegment($bitBuffer, $versionNumber);
+
 		if($encoding === null){
 			// The spec isn't clear on this mode; see
 			// section 6.4.5: it does not say which encoding to assuming

+ 4 - 4
src/Data/Hanzi.php

@@ -125,8 +125,8 @@ final class Hanzi extends QRDataModeAbstract{
 
 		$bitBuffer
 			->put(self::DATAMODE, 4)
-			->put($this::GB2312_SUBSET, 4)
-			->put($this->getCharCount(), $this::getLengthBits($versionNumber))
+			->put(self::GB2312_SUBSET, 4)
+			->put($this->getCharCount(), $this->getLengthBits($versionNumber))
 		;
 
 		$len = strlen($this->data);
@@ -159,14 +159,14 @@ final class Hanzi extends QRDataModeAbstract{
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
+	public function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
 
 		// Hanzi mode contains a subset indicator right after mode indicator
 		if($bitBuffer->read(4) !== self::GB2312_SUBSET){
 			throw new QRCodeDataException('ecpected subset indicator for Hanzi mode');
 		}
 
-		$length = $bitBuffer->read(self::getLengthBits($versionNumber));
+		$length = $bitBuffer->read($this->getLengthBits($versionNumber));
 
 		if($bitBuffer->available() < ($length * 13)){
 			throw new QRCodeDataException('not enough bits available');

+ 3 - 3
src/Data/Kanji.php

@@ -113,7 +113,7 @@ final class Kanji extends QRDataModeAbstract{
 
 		$bitBuffer
 			->put(self::DATAMODE, 4)
-			->put($this->getCharCount(), $this::getLengthBits($versionNumber))
+			->put($this->getCharCount(), $this->getLengthBits($versionNumber))
 		;
 
 		$len = strlen($this->data);
@@ -146,8 +146,8 @@ final class Kanji extends QRDataModeAbstract{
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
-		$length = $bitBuffer->read(self::getLengthBits($versionNumber));
+	public function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
+		$length = $bitBuffer->read($this->getLengthBits($versionNumber));
 
 		if($bitBuffer->available() < ($length * 13)){
 			throw new QRCodeDataException('not enough bits available');  // @codeCoverageIgnore

+ 3 - 3
src/Data/Number.php

@@ -37,7 +37,7 @@ final class Number extends QRDataModeAbstract{
 
 		$bitBuffer
 			->put(self::DATAMODE, 4)
-			->put($len, $this::getLengthBits($versionNumber))
+			->put($len, $this->getLengthBits($versionNumber))
 		;
 
 		$i = 0;
@@ -90,8 +90,8 @@ final class Number extends QRDataModeAbstract{
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
-		$length = $bitBuffer->read(self::getLengthBits($versionNumber));
+	public function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
+		$length = $bitBuffer->read($this->getLengthBits($versionNumber));
 		$result = '';
 		// Read three digits at a time
 		while($length >= 3){

+ 11 - 7
src/Data/QRDataModeAbstract.php

@@ -21,21 +21,25 @@ abstract class QRDataModeAbstract implements QRDataModeInterface{
 	/**
 	 * The data to write
 	 */
-	protected string $data;
+	protected string $data = '';
 
 	/**
 	 * QRDataModeAbstract constructor.
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public function __construct(string $data){
-		$data = $this::convertEncoding($data);
+	public function __construct(string|null $data = null){
 
-		if(!$this::validateString($data)){
-			throw new QRCodeDataException('invalid data');
+		if($data !== null){
+			$data = $this::convertEncoding($data);
+
+			if(!$this::validateString($data)){
+				throw new QRCodeDataException('invalid data');
+			}
+
+			$this->data = $data;
 		}
 
-		$this->data = $data;
 	}
 
 	/**
@@ -52,7 +56,7 @@ abstract class QRDataModeAbstract implements QRDataModeInterface{
 	/**
 	 * shortcut
 	 */
-	protected static function getLengthBits(int $versionNumber):int{
+	protected function getLengthBits(int $versionNumber):int{
 		return Mode::getLengthBitsForVersion(static::DATAMODE, $versionNumber);
 	}
 

+ 1 - 1
src/Data/QRDataModeInterface.php

@@ -55,6 +55,6 @@ interface QRDataModeInterface{
 	/**
 	 * reads a segment from the BitBuffer and decodes in the current data mode
 	 */
-	public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string;
+	public function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string;
 
 }

+ 6 - 6
src/Decoder/Decoder.php

@@ -117,16 +117,16 @@ final class Decoder{
 				break;
 			}
 			elseif($datamode === Mode::NUMBER){
-				$result .= Number::decodeSegment($this->bitBuffer, $versionNumber);
+				$result .= (new Number)->decodeSegment($this->bitBuffer, $versionNumber);
 			}
 			elseif($datamode === Mode::ALPHANUM){
 				$result .= $this->decodeAlphanumSegment($versionNumber, $fc1InEffect);
 			}
 			elseif($datamode === Mode::BYTE){
-				$result .= Byte::decodeSegment($this->bitBuffer, $versionNumber);
+				$result .= (new Byte)->decodeSegment($this->bitBuffer, $versionNumber);
 			}
 			elseif($datamode === Mode::KANJI){
-				$result .= Kanji::decodeSegment($this->bitBuffer, $versionNumber);
+				$result .= (new Kanji)->decodeSegment($this->bitBuffer, $versionNumber);
 			}
 			elseif($datamode === Mode::STRCTURED_APPEND){
 
@@ -143,10 +143,10 @@ final class Decoder{
 				$fc1InEffect = true;
 			}
 			elseif($datamode === Mode::ECI){
-				$result .= ECI::decodeSegment($this->bitBuffer, $versionNumber);
+				$result .= (new ECI)->decodeSegment($this->bitBuffer, $versionNumber);
 			}
 			elseif($datamode === Mode::HANZI){
-				$result .= Hanzi::decodeSegment($this->bitBuffer, $versionNumber);
+				$result .= (new Hanzi)->decodeSegment($this->bitBuffer, $versionNumber);
 			}
 			else{
 				throw new QRCodeDecoderException('invalid data mode');
@@ -167,7 +167,7 @@ final class Decoder{
 	}
 
 	private function decodeAlphanumSegment(int $versionNumber, bool $fc1InEffect):string{
-		$str = AlphaNum::decodeSegment($this->bitBuffer, $versionNumber);
+		$str = (new AlphaNum)->decodeSegment($this->bitBuffer, $versionNumber);
 
 		// See section 6.4.8.1, 6.4.8.2
 		if($fc1InEffect){ // ???

+ 4 - 4
tests/Data/DataInterfaceTestAbstract.php

@@ -89,7 +89,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{
 		// read 4 bits (data mode indicator)
 		$bitBuffer->read(4);
 		// decode and check against the given string
-		$decoded = $dataModeInterface::decodeSegment($bitBuffer, 40);
+		$decoded = $dataModeInterface->decodeSegment($bitBuffer, 40);
 
 		$this::assertSame($string, $decoded);
 	}
@@ -129,7 +129,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{
 		// read the first 4 bits
 		$this::assertSame($this->dataMode::DATAMODE, $bitBuffer->read(4));
 		// decode the data
-		$this::assertSame(static::testData, $this->dataMode::decodeSegment($bitBuffer, $options->version));
+		$this::assertSame(static::testData, $this->dataMode->decodeSegment($bitBuffer, $options->version));
 	}
 
 	/**
@@ -187,7 +187,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{
 		$bitBuffer         = $this->QRData->getBitBuffer();
 
 		$this::assertSame($this->dataMode::DATAMODE, $bitBuffer->read(4));
-		$this::assertSame($str, $this->dataMode::decodeSegment($bitBuffer, $options->version));
+		$this::assertSame($str, $this->dataMode->decodeSegment($bitBuffer, $options->version));
 	}
 
 	/**
@@ -218,7 +218,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{
 
 		// verify the encoded data
 		$this::assertSame($this->dataMode::DATAMODE, $bitBuffer->read(4));
-		$this::assertSame($str, $this->dataMode::decodeSegment($bitBuffer, $minimumVersionNumber));
+		$this::assertSame($str, $this->dataMode->decodeSegment($bitBuffer, $minimumVersionNumber));
 	}
 
 	/**

+ 4 - 4
tests/Data/ECITest.php

@@ -67,7 +67,7 @@ final class ECITest extends TestCase{
 		// read the first 4 bits
 		$this::assertSame($segments[0]::DATAMODE, $bitBuffer->read(4));
 		// decode the data
-		$this::assertSame(self::testData, ECI::decodeSegment($bitBuffer, $options->version));
+		$this::assertSame(self::testData, (new ECI)->decodeSegment($bitBuffer, $options->version));
 	}
 
 	#[Test]
@@ -112,7 +112,7 @@ final class ECITest extends TestCase{
 
 		$this::assertSame($lengthInBits, $eci->getLengthInBits());
 		$this::assertSame(Mode::ECI, $bitBuffer->read(4));
-		$this::assertSame($id, ECI::parseValue($bitBuffer)->getID());
+		$this::assertSame($id, $eci->parseValue($bitBuffer)->getID());
 	}
 
 	/**
@@ -134,7 +134,7 @@ final class ECITest extends TestCase{
 		// verify the ECI mode indicator
 		$this::assertSame(Mode::ECI, $bitBuffer->read(4));
 		// throw
-		ECI::decodeSegment($bitBuffer, $options->version);
+		(new ECI)->decodeSegment($bitBuffer, $options->version);
 	}
 
 	/**
@@ -159,7 +159,7 @@ final class ECITest extends TestCase{
 		$segments  = [new ECI($id), new Byte($data)];
 		$bitBuffer = (new QRData($options, $segments))->getBitBuffer();
 		$this::assertSame(Mode::ECI, $bitBuffer->read(4));
-		$this::assertSame($data, ECI::decodeSegment($bitBuffer, $options->version));
+		$this::assertSame($data,(new ECI)->decodeSegment($bitBuffer, $options->version));
 	}
 
 }