• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h"
6 
7 #include "testing/gtest/include/gtest/gtest.h"
8 
TEST(PDF417HighLevelEncoderTest,EncodeHighLevel)9 TEST(PDF417HighLevelEncoderTest, EncodeHighLevel) {
10   static constexpr struct EncodeHighLevelCase {
11     const wchar_t* input;
12     const wchar_t* expected;
13     int expected_length;
14   } kEncodeHighLevelCases[] = {
15       // Empty string encodes as empty string.
16       {L"", L"", 0},
17 
18       // Binary mode with digit.
19       {L"\x000b\x000b\x0030", L"\x0385\x000b\x000b\x0030", 4},
20 
21       // Text mode.
22       {L"xxxxxxXx", L"\x0384\x0341\x02c9\x02c9\x02cd\x02c9", 6},
23 
24       // Text mode with punctuation.
25       {L"xxxxxx!x", L"\x0384\x0341\x02c9\x02c9\x02cf\x0143", 6},
26 
27       // Text mode with mixed submode.
28       {L"xxxxxx0x", L"\x0384\x0341\x02c9\x02c9\x02ce\x001b\x02cf", 7},
29 
30       // Text mode with mixed submode, and space in alpha submode.
31       {L"xxxxxx0X ", L"\x0384\x0341\x02c9\x02c9\x02ce\x001c\x02cc", 7},
32 
33       // Text mode to binary mode.
34       {L"xxxxxx\x0b", L"\x0384\x0341\x02c9\x02c9\x02cf\x0391\x0385\x000b", 8},
35 
36       // 13 consecutive digits triggers numeric encoding.
37       {L"0000000000000", L"\x0386\x000f\x00d9\x017b\x000b\x0064", 6},
38   };
39 
40   size_t i = 0;
41   for (const EncodeHighLevelCase& testcase : kEncodeHighLevelCases) {
42     WideStringView input(testcase.input);
43     auto expected =
44         UNSAFE_TODO(WideString(testcase.expected, testcase.expected_length));
45     std::optional<WideString> result =
46         CBC_PDF417HighLevelEncoder::EncodeHighLevel(input);
47     ASSERT_TRUE(result.has_value());
48     EXPECT_EQ(expected, result.value()) << " for case number " << i;
49     ++i;
50   }
51 }
52 
TEST(PDF417HighLevelEncoderTest,EncodeText)53 TEST(PDF417HighLevelEncoderTest, EncodeText) {
54   // TODO(tsepez): implement test cases.
55 }
56 
TEST(PDF417HighLevelEncoderTest,EncodeBinary)57 TEST(PDF417HighLevelEncoderTest, EncodeBinary) {
58   static constexpr struct EncodeBinaryCase {
59     const char* input;
60     int offset;
61     int count;
62     CBC_PDF417HighLevelEncoder::EncodingMode startmode;
63     const wchar_t* expected;
64     int expected_length;
65   } kEncodeBinaryCases[] = {
66       // Empty string encodes as empty string.
67       {"", 0, 0, CBC_PDF417HighLevelEncoder::EncodingMode::kText, L"", 0},
68 
69       // Single digit encodes with a shift-to byte.
70       {"x", 0, 1, CBC_PDF417HighLevelEncoder::EncodingMode::kText,
71        L"\x0391\x0385x", 3},
72 
73       // Fewer than 6 characters encodes as prefix without compaction.
74       {"xxxxx", 0, 5, CBC_PDF417HighLevelEncoder::EncodingMode::kText,
75        L"\x0385xxxxx", 6},
76 
77       // 6 charcters triggers text encoding compaction.
78       {"xxxxxx", 0, 6, CBC_PDF417HighLevelEncoder::EncodingMode::kText,
79        L"\u039c\u00c9\u031f\u012a\u00d2\u02d0", 6},
80 
81       // Same result if initially in numeric compaction mode.
82       {"xxxxxx", 0, 6, CBC_PDF417HighLevelEncoder::EncodingMode::kNumeric,
83        L"\u039c\u00c9\u031f\u012a\u00d2\u02d0", 6},
84   };
85 
86   size_t i = 0;
87   for (const EncodeBinaryCase& testcase : kEncodeBinaryCases) {
88     WideString result;
89     CBC_PDF417HighLevelEncoder::EncodeBinary(
90         ByteStringView(testcase.input).unsigned_span(), testcase.offset,
91         testcase.count, testcase.startmode, &result);
92     auto expected =
93         UNSAFE_TODO(WideString(testcase.expected, testcase.expected_length));
94     EXPECT_EQ(expected, result) << " for case number " << i;
95     ++i;
96   }
97 }
98 
TEST(PDF417HighLevelEncoderTest,EncodeNumeric)99 TEST(PDF417HighLevelEncoderTest, EncodeNumeric) {
100   static constexpr struct EncodeNumericCase {
101     const wchar_t* input;
102     int offset;
103     int count;
104     const wchar_t* expected;
105     int expected_length;
106   } kEncodeNumericCases[] = {
107       // Empty string encodes as empty string.
108       {L"", 0, 0, L"", 0},
109 
110       // Single 0 should encode as 10 base-900 == a.
111       {L"0", 0, 1, L"\x000a", 1},
112 
113       // 800 should encode as 1800 base-900 == 2,0.
114       {L"800", 0, 3, L"\x0002\x0000", 2},
115 
116       // Test longer strings and sub-strings.
117       {L"123456", 0, 6, L"\x0001\x015c\x0100", 3},
118       {L"123456", 0, 5, L"\x007c\x02e9", 2},
119       {L"123456", 1, 5, L"\x0089\x009c", 2},
120       {L"123456", 2, 2, L"\x0086", 1},
121 
122       // Up to 44 characters encodes as 15 base-900 words.
123       {L"00000000000000000000000000000000000000000000", 0, 44,
124        L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
125        L"\x0090\x020b\x019b\x0064",
126        15},
127 
128       // 45 characters should encode as same 15 words followed by one additional
129       // word.
130       {L"000000000000000000000000000000000000000000000", 0, 45,
131        L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
132        L"\x0090\x020b\x019b\x0064\x000a",
133        16},
134 
135       // 44 characters followed by 800 should encode as 15 words followed by
136       // 1800 base-900 == 2,0.
137       {L"00000000000000000000000000000000000000000000800", 0, 47,
138        L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
139        L"\x0090\x020b\x019b\x0064\x0002\x0000",
140        17},
141 
142       // Even longer input.
143       {L"10000000000000000000000000000000000000000000000000", 0, 50,
144        L"\x01e0\x02f0\x036d\x02ad\x029c\x01ea\x0011\x000b\x02d6\x023c\x0108"
145        L"\x02bb\x0023\x02d2\x00c8\x0001\x00d3\x0064",
146        18},
147   };
148 
149   size_t i = 0;
150   for (const EncodeNumericCase& testcase : kEncodeNumericCases) {
151     WideString input(testcase.input);
152     auto expected =
153         UNSAFE_TODO(WideString(testcase.expected, testcase.expected_length));
154     WideString result;
155     CBC_PDF417HighLevelEncoder::EncodeNumeric(input, testcase.offset,
156                                               testcase.count, &result);
157     EXPECT_EQ(expected, result) << " for case number " << i;
158     ++i;
159   }
160 }
161 
TEST(PDF417HighLevelEncoderTest,ConsecutiveDigitCount)162 TEST(PDF417HighLevelEncoderTest, ConsecutiveDigitCount) {
163   static constexpr struct ConsecutiveDigitCase {
164     const wchar_t* input;
165     int offset;
166     int expected_count;
167   } kConsecutiveDigitCases[] = {
168       // Empty string contains 0 consecutive digits.
169       {L"", 0, 0},
170 
171       // Single non-digit character contains 0 consecutive digits.
172       {L"X", 0, 0},
173 
174       // Leading non-digit followed by digits contains 0 consecutive.
175       {L"X123", 0, 0},
176 
177       // Single digit contains 1 consecutive digit.
178       {L"1", 0, 1},
179 
180       // Single digit followe by non-digit contains 1 consecutive digit.
181       {L"1Z", 0, 1},
182 
183       // Test longer strings.
184       {L"123FOO45678", 0, 3},
185 
186       // Test subtring starting in digits field.
187       {L"123FOO45678", 3, 0},
188 
189       // Test subtring starting in non-digits field.
190       {L"123FOO45678", 3, 0},
191 
192       // Test substring starting in digits field following non-digit field.
193       {L"123FOO45678", 6, 5},
194   };
195   size_t i = 0;
196   for (const ConsecutiveDigitCase& testcase : kConsecutiveDigitCases) {
197     WideString input(testcase.input);
198     int actual_count =
199         CBC_PDF417HighLevelEncoder::DetermineConsecutiveDigitCount(
200             input, testcase.offset);
201     EXPECT_EQ(testcase.expected_count, actual_count)
202         << " for case number " << i;
203     ++i;
204   }
205 }
206 
TEST(PDF417HighLevelEncoderTest,ConsecutiveTextCount)207 TEST(PDF417HighLevelEncoderTest, ConsecutiveTextCount) {
208   static constexpr struct ConsecutiveTextCase {
209     const wchar_t* input;
210     int offset;
211     int expected_count;
212   } kConsecutiveTextCases[] = {
213       // Empty string contains 0 consecutive text characters.
214       {L"", 0, 0},
215 
216       // Single text character is 1 consecutive text characters.
217       {L"X", 0, 1},
218 
219       // Trailing numbers count as text characters.
220       {L"X123", 0, 4},
221 
222       // Leading numbers count as text characters.
223       {L"123X", 0, 4},
224 
225       // Embedded lo-value binary characters terminate text runs.
226       {L"ABC\x0001XXXX", 0, 3},
227 
228       // Embedded hi-value binary characters terminate text runs.
229       {L"ABC\x0100XXXX", 0, 3},
230 
231       // Text run still found after indexing past lo-value character.
232       {L"ABC\x0001XXXX", 4, 4},
233 
234       // Text run still found after indexing past hi-value character.
235       {L"ABC\x0100XXXX", 4, 4},
236 
237       // Leading hi-value character results in 0 consecutive characters.
238       {L"\x0100XXX", 0, 0},
239 
240       // Up to 12 numbers count as text.
241       {L"123456789012", 0, 12},
242 
243       // 13 or more numbers are compresssed using numeric compression, not text.
244       {L"1234567890123", 0, 0},
245 
246       // Leading Text character doesn't affect the 12 character case.
247       {L"X123456789012", 0, 13},
248 
249       // Leading Text character doesn't affect the 13 character case.
250       {L"X1234567890123", 0, 1},
251 
252       // Jumping between numbers and letters works properly.
253       {L"XXX121XXX12345678901234", 0, 9},
254   };
255 
256   size_t i = 0;
257   for (const ConsecutiveTextCase& testcase : kConsecutiveTextCases) {
258     WideString input(testcase.input);
259     int actual_count =
260         CBC_PDF417HighLevelEncoder::DetermineConsecutiveTextCount(
261             input, testcase.offset);
262     EXPECT_EQ(testcase.expected_count, actual_count)
263         << " for case number " << i;
264     ++i;
265   }
266 }
267 
TEST(PDF417HighLevelEncoderTest,ConsecutiveBinaryCount)268 TEST(PDF417HighLevelEncoderTest, ConsecutiveBinaryCount) {
269   // TODO(tsepez): implement test cases.
270 }
271