1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
// Author: cirakg & claude ai
// Summary: Tests for the Data Matrix encoder: ppf.datamatrix references (ASCII), Base256 and upper-shift decoding dumps, limits.
import Toybox.Lang;
import Toybox.Test;
(:test)
module MatrixFixtures {
function packedHex(m as Codes.Matrix) as String {
var bits = m.modules;
var out = new [(bits.size() + 7) / 8]b;
for (var i = 0; i < bits.size(); i++) {
if (bits[i] == 1) {
out[i / 8] = out[i / 8] | (0x80 >> (i % 8));
}
}
return Bytes.toHex(out);
}
// A line tools/check_codes.py decodes with zxing-cpp.
function dump(logger as Test.Logger, symbology as Number, text as String, m as Codes.Matrix) as Void {
logger.debug("MATRIXDUMP " + symbology + " " + m.width + " " + m.height + " " + m.rowHeight + " " + m.quiet + " "
+ Bytes.toHex(Bytes.fromUtf8(text)) + " " + packedHex(m));
}
}
// README 12.4 check 1: identical to ppf.datamatrix in ASCII mode, from
// 10 x 10 to 144 x 144 (multi-region and multi-block sizes).
(:test)
function dataMatrixMatchesReference(logger as Test.Logger) as Boolean {
var rows = CodeVectors.DATAMATRIX;
for (var i = 0; i < rows.size(); i++) {
var row = rows[i] as Array;
var payload = row[0] as String;
var result = DataMatrix.encode(payload);
if (result instanceof Codes.CodeError) {
logger.error("row " + i + ": " + result.message);
return false;
}
var expectedSize = row[1] as Number;
var expected = row[2] as String;
var got = MatrixFixtures.packedHex(result);
if (result.width != expectedSize || !got.equals(expected)) {
logger.error("row " + i + " '" + Text.clip(payload, 20) + "': size " + result.width + ", reference " + expectedSize);
return false;
}
}
logger.debug("CODES datamatrix reference rows=" + rows.size());
return true;
}
// README 12.4 check 2: Base256 (UTF-8), Upper Shift and plain payloads,
// decoded by tools/check_codes.py.
(:test)
function dataMatrixDumpForDecoding(logger as Test.Logger) as Boolean {
var payloads = ["Zürich", "Ünïcödé 😀 fake card 0042", "é", "1234567890", "Member: fake-0042, valid 2027-12-31",
"ÄÖÜäöüß" + "ÄÖÜäöüß" + "ÄÖÜäöüß", "abc"];
var long = "";
for (var i = 0; i < 30; i++) {
long += "é0123456789";
}
payloads.add(long);
var xs = "";
for (var i = 0; i < 50; i++) {
xs += "xxxxxxxxxx";
}
payloads.add(xs); // 88 x 88: 4 x 4 regions, 4 interleaved blocks
var digits = "";
for (var i = 0; i < 110; i++) {
digits += "0123456789";
}
payloads.add(digits); // 88 x 88 in digit pairs, comparable with zint
for (var i = 0; i < payloads.size(); i++) {
var text = payloads[i] as String;
var result = DataMatrix.encode(text);
if (result instanceof Codes.CodeError) {
logger.error("'" + text + "': " + result.message);
return false;
}
MatrixFixtures.dump(logger, Codes.DATAMATRIX, text, result);
}
return true;
}
(:test)
function dataMatrixLimits(logger as Test.Logger) as Boolean {
var big = "";
for (var i = 0; i < 160; i++) {
big += "abcdefghij";
}
// (Separate checks: one long && chain of instanceof tests made the
// compiler run out of memory.)
if (!(DataMatrix.encode(big) instanceof Codes.CodeError)) {
logger.error("too long text was accepted");
return false;
}
if (!(DataMatrix.encode("") instanceof Codes.CodeError)) {
logger.error("empty text was accepted");
return false;
}
// Base256 is chosen when cheaper than Upper Shift for every byte.
var b256 = DataMatrix.codewords(Bytes.fromUtf8("ÄÖÜ"));
if (b256[0] != DataMatrix.BASE256_LATCH) {
logger.error("Base256 not chosen");
return false;
}
var ascii = DataMatrix.codewords(Bytes.fromUtf8("A1234"));
return ascii.size() == 3 && ascii[0] == 66 && ascii[1] == 142;
}
|