• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
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   for (size_t i = 0; i < FX_ArraySize(kEncodeHighLevelCases); ++i) {
41     const EncodeHighLevelCase& testcase = kEncodeHighLevelCases[i];
42     WideStringView input(testcase.input);
43     WideString expected(testcase.expected, testcase.expected_length);
44     Optional<WideString> result =
45         CBC_PDF417HighLevelEncoder::EncodeHighLevel(input);
46     ASSERT_TRUE(result.has_value());
47     EXPECT_EQ(expected, result.value()) << " for case number " << i;
48   }
49 }
50 
TEST(PDF417HighLevelEncoderTest,EncodeText)51 TEST(PDF417HighLevelEncoderTest, EncodeText) {
52   // TODO(tsepez): implement test cases.
53 }
54 
TEST(PDF417HighLevelEncoderTest,EncodeBinary)55 TEST(PDF417HighLevelEncoderTest, EncodeBinary) {
56   static constexpr struct EncodeBinaryCase {
57     const char* input;
58     int offset;
59     int count;
60     CBC_PDF417HighLevelEncoder::EncodingMode startmode;
61     const wchar_t* expected;
62     int expected_length;
63   } kEncodeBinaryCases[] = {
64       // Empty string encodes as empty string.
65       {"", 0, 0, CBC_PDF417HighLevelEncoder::EncodingMode::kText, L"", 0},
66 
67       // Single digit encodes with a shift-to byte.
68       {"x", 0, 1, CBC_PDF417HighLevelEncoder::EncodingMode::kText,
69        L"\x0391\x0385x", 3},
70 
71       // Fewer than 6 characters encodes as prefix without compaction.
72       {"xxxxx", 0, 5, CBC_PDF417HighLevelEncoder::EncodingMode::kText,
73        L"\x0385xxxxx", 6},
74 
75       // 6 charcters triggers text encoding compaction.
76       {"xxxxxx", 0, 6, CBC_PDF417HighLevelEncoder::EncodingMode::kText,
77        L"\u039c\u00c9\u031f\u012a\u00d2\u02d0", 6},
78 
79       // Same result if initially in numeric compaction mode.
80       {"xxxxxx", 0, 6, CBC_PDF417HighLevelEncoder::EncodingMode::kNumeric,
81        L"\u039c\u00c9\u031f\u012a\u00d2\u02d0", 6},
82   };
83 
84   for (size_t i = 0; i < FX_ArraySize(kEncodeBinaryCases); ++i) {
85     const EncodeBinaryCase& testcase = kEncodeBinaryCases[i];
86     std::vector<uint8_t> input_array;
87     size_t input_length = strlen(testcase.input);
88     input_array.resize(input_length);
89     for (size_t j = 0; j < input_length; ++j) {
90       input_array[j] = testcase.input[j];
91     }
92     WideString expected(testcase.expected, testcase.expected_length);
93     WideString result;
94     CBC_PDF417HighLevelEncoder::EncodeBinary(input_array, testcase.offset,
95                                              testcase.count, testcase.startmode,
96                                              &result);
97     EXPECT_EQ(expected, result) << " for case number " << i;
98   }
99 }
100 
TEST(PDF417HighLevelEncoderTest,EncodeNumeric)101 TEST(PDF417HighLevelEncoderTest, EncodeNumeric) {
102   static constexpr struct EncodeNumericCase {
103     const wchar_t* input;
104     int offset;
105     int count;
106     const wchar_t* expected;
107     int expected_length;
108   } kEncodeNumericCases[] = {
109       // Empty string encodes as empty string.
110       {L"", 0, 0, L"", 0},
111 
112       // Single 0 should encode as 10 base-900 == a.
113       {L"0", 0, 1, L"\x000a", 1},
114 
115       // 800 should encode as 1800 base-900 == 2,0.
116       {L"800", 0, 3, L"\x0002\x0000", 2},
117 
118       // Test longer strings and sub-strings.
119       {L"123456", 0, 6, L"\x0001\x015c\x0100", 3},
120       {L"123456", 0, 5, L"\x007c\x02e9", 2},
121       {L"123456", 1, 5, L"\x0089\x009c", 2},
122       {L"123456", 2, 2, L"\x0086", 1},
123 
124       // Up to 44 characters encodes as 15 base-900 words.
125       {L"00000000000000000000000000000000000000000000", 0, 44,
126        L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
127        L"\x0090\x020b\x019b\x0064",
128        15},
129 
130       // 45 characters should encode as same 15 words followed by one additional
131       // word.
132       {L"000000000000000000000000000000000000000000000", 0, 45,
133        L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
134        L"\x0090\x020b\x019b\x0064\x000a",
135        16},
136 
137       // 44 characters followed by 800 should encode as 15 words followed by
138       // 1800 base-900 == 2,0.
139       {L"00000000000000000000000000000000000000000000800", 0, 47,
140        L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6"
141        L"\x0090\x020b\x019b\x0064\x0002\x0000",
142        17},
143 
144       // Even longer input.
145       {L"10000000000000000000000000000000000000000000000000", 0, 50,
146        L"\x01e0\x02f0\x036d\x02ad\x029c\x01ea\x0011\x000b\x02d6\x023c\x0108"
147        L"\x02bb\x0023\x02d2\x00c8\x0001\x00d3\x0064",
148        18},
149   };
150 
151   for (size_t i = 0; i < FX_ArraySize(kEncodeNumericCases); ++i) {
152     const EncodeNumericCase& testcase = kEncodeNumericCases[i];
153     WideString input(testcase.input);
154     WideString expected(testcase.expected, testcase.expected_length);
155     WideString result;
156     CBC_PDF417HighLevelEncoder::EncodeNumeric(input, testcase.offset,
157                                               testcase.count, &result);
158     EXPECT_EQ(expected, result) << " for case number " << 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 
196   for (size_t i = 0; i < FX_ArraySize(kConsecutiveDigitCases); ++i) {
197     const ConsecutiveDigitCase& testcase = kConsecutiveDigitCases[i];
198     WideString input(testcase.input);
199     int actual_count =
200         CBC_PDF417HighLevelEncoder::DetermineConsecutiveDigitCount(
201             input, testcase.offset);
202     EXPECT_EQ(testcase.expected_count, actual_count)
203         << " for case number " << 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   for (size_t i = 0; i < FX_ArraySize(kConsecutiveTextCases); ++i) {
257     const ConsecutiveTextCase& testcase = kConsecutiveTextCases[i];
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   }
265 }
266 
TEST(PDF417HighLevelEncoderTest,ConsecutiveBinaryCount)267 TEST(PDF417HighLevelEncoderTest, ConsecutiveBinaryCount) {
268   // TODO(tsepez): implement test cases.
269 }
270