DecoderTestCase.java
/*
* Copyright 2024 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.maxicode.decoder;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DecoderResult;
import java.util.Locale;
import org.junit.Test;
import org.junit.Assert;
/**
* Tests {@link Decoder}.
*/
public final class DecoderTestCase extends Assert {
@Test
public void testOversizedMatrix() throws ChecksumException {
// A matrix larger than the 30x33 MaxiCode size must be rejected as a format error,
// not indexed past the fixed bit-number table.
BitMatrix bits = new BitMatrix(40, 40);
for (int y = 0; y < 40; y++) {
for (int x = 0; x < 40; x++) {
if (((x * 7 + y * 13) & 1) == 0) {
bits.set(x, y);
}
}
}
try {
new Decoder().decode(bits);
fail("Expected FormatException");
} catch (FormatException expected) {
// good
}
}
@Test
public void testStructuredCarrierMessageLocaleIndependent() throws FormatException {
// Mode 2 prepends a numeric postcode, country code and service class. These must decode to
// Latin digits regardless of the JVM default locale (e.g. Arabic-Indic digits otherwise).
byte[] datawords = new byte[94];
Locale defaultLocale = Locale.getDefault();
String expected;
try {
Locale.setDefault(Locale.ENGLISH);
expected = DecodedBitStreamParser.decode(datawords, 2).getText();
Locale.setDefault(new Locale("ar", "EG"));
DecoderResult result = DecodedBitStreamParser.decode(datawords, 2);
assertEquals(expected, result.getText());
assertTrue(result.getText().startsWith("0"));
} finally {
Locale.setDefault(defaultLocale);
}
}
@Test
public void testTruncatedStructuredCarrierMessageHeader() {
// A mode 2/3 secondary message that starts with the structured append header "[)>RS01GS"
// but is shorter than the 9 characters the postcode/country/service splice assumes must be
// rejected as a format error, not insert past the end of the buffer.
byte[] datawords = new byte[94];
// SHIFTB '[' ')' SHIFTB '>' RS '0' '1' GS -> decodes to exactly "[)>01" (7 chars)
int[] message = {59, 42, 41, 59, 40, 30, 48, 49, 29};
for (int i = 0; i < message.length; i++) {
datawords[10 + i] = (byte) message[i];
}
for (int i = 10 + message.length; i < datawords.length; i++) {
datawords[i] = 33; // PAD, trimmed off the decoded message
}
try {
DecodedBitStreamParser.decode(datawords, 2);
fail("Expected FormatException");
} catch (FormatException expected) {
// good
}
}
@Test
public void testWrongDimensions() throws ChecksumException {
for (int[] wh : new int[][] {{31, 33}, {30, 34}, {29, 33}, {30, 32}}) {
try {
new Decoder().decode(new BitMatrix(wh[0], wh[1]));
fail("Expected FormatException for " + wh[0] + "x" + wh[1]);
} catch (FormatException expected) {
// good
}
}
}
}