Skip to content

Commit 53b52b7

Browse files
committed
:octocat: allow for ECI encoded numeric and alphanum segments (???), see #289
1 parent 90eb116 commit 53b52b7

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

examples/reader.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
var_dump($result);
2525
}
2626
catch(Throwable $e){
27-
echo $e->getMessage();
27+
printf("%s(%s): %s\n%s", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getTraceAsString());
2828
}
2929

3030
exit;

src/Data/ECI.php

+17-8
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,12 @@ public static function validateString(string $string):bool{
129129
public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):string{
130130
$eciCharset = self::parseValue($bitBuffer);
131131
$nextMode = $bitBuffer->read(4);
132-
133-
if($nextMode !== Mode::BYTE){
134-
throw new QRCodeDataException(sprintf('ECI designator followed by invalid mode: "%04b"', $nextMode));
135-
}
136-
137-
$data = Byte::decodeSegment($bitBuffer, $versionNumber);
138-
$encoding = $eciCharset->getName();
132+
$data = self::decodeModeSegment($nextMode, $bitBuffer, $versionNumber);
133+
$encoding = $eciCharset->getName();
139134

140135
if($encoding === null){
141136
// The spec isn't clear on this mode; see
142-
// section 6.4.5: t does not say which encoding to assuming
137+
// section 6.4.5: it does not say which encoding to assuming
143138
// upon decoding. I have seen ISO-8859-1 used as well as
144139
// Shift_JIS -- without anything like an ECI designator to
145140
// give a hint.
@@ -153,4 +148,18 @@ public static function decodeSegment(BitBuffer $bitBuffer, int $versionNumber):s
153148
return mb_convert_encoding($data, mb_internal_encoding(), $encoding);
154149
}
155150

151+
/**
152+
* @throws \chillerlan\QRCode\Data\QRCodeDataException
153+
*/
154+
private static function decodeModeSegment(int $mode, BitBuffer $bitBuffer, int $versionNumber):string{
155+
156+
switch(true){
157+
case $mode === Mode::NUMBER: return Number::decodeSegment($bitBuffer, $versionNumber);
158+
case $mode === Mode::ALPHANUM: return AlphaNum::decodeSegment($bitBuffer, $versionNumber);
159+
case $mode === Mode::BYTE: return Byte::decodeSegment($bitBuffer, $versionNumber);
160+
}
161+
162+
throw new QRCodeDataException(sprintf('ECI designator followed by invalid mode: "%04b"', $mode));
163+
}
164+
156165
}

tests/Data/ECITest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
use chillerlan\QRCode\QROptions;
1414
use chillerlan\QRCode\Common\{BitBuffer, ECICharset, Mode};
15-
use chillerlan\QRCode\Data\{Byte, ECI, Number, QRCodeDataException, QRData, QRDataModeInterface};
15+
use chillerlan\QRCode\Data\{Byte, ECI, Hanzi, QRCodeDataException, QRData, QRDataModeInterface};
1616
use PHPUnit\Framework\TestCase;
1717

1818
/**
@@ -125,7 +125,7 @@ public function testDecodeECISegmentFollowedByInvalidModeException():void{
125125
/** @var \chillerlan\QRCode\Data\QRDataModeInterface[] $segments */
126126
$segments = $this->getDataSegments();
127127
// follow the ECI segment by a non-8bit-byte segment
128-
$segments[1] = new Number('1');
128+
$segments[1] = new Hanzi(self::testData);
129129
$bitBuffer = (new QRData($options, $segments))->getBitBuffer();
130130
// verify the ECI mode indicator
131131
$this::assertSame(Mode::ECI, $bitBuffer->read(4));

0 commit comments

Comments
 (0)