MCDecoderTest.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright 2021 gitlost
  3. */
  4. // SPDX-License-Identifier: Apache-2.0
  5. #include "ByteArray.h"
  6. #include "DecoderResult.h"
  7. #include "gtest/gtest.h"
  8. #include <utility>
  9. namespace ZXing::MaxiCode::DecodedBitStreamParser {
  10. DecoderResult Decode(ByteArray&& bytes, const int mode);
  11. }
  12. using namespace ZXing;
  13. // Pad out to max data length 93 (mode 4)
  14. static void pad(ByteArray& padded)
  15. {
  16. while (padded.size() < 93 + 1) { // 93 + mode
  17. padded.push_back(33);
  18. }
  19. }
  20. // Helper to call Decode()
  21. static DecoderResult parse(ByteArray bytes, const int mode, ByteArray *mode2or3 = nullptr)
  22. {
  23. ByteArray padded;
  24. padded.reserve(93 + 1); // 93 + mode
  25. if (mode == 2) {
  26. if (mode2or3) {
  27. padded = *mode2or3;
  28. } else {
  29. // Mode 2, Postcode 152382802, Country 840, Class 001 example from ISO/IEC 16023:2000 Annex B.2
  30. padded = {34, 20, 45, 20, 17, 18, 2, 18, 7, 0};
  31. }
  32. } else if (mode == 3) {
  33. if (mode2or3) {
  34. padded = *mode2or3;
  35. } else {
  36. // Mode 3, Postcode B1050, Country 056, Class 999 example from ISO/IEC 16023:2000 Annex B.1
  37. padded = {3, 8, 28, 13, 28, 44, 0, 14, 28, 62};
  38. }
  39. } else {
  40. padded.push_back(mode);
  41. }
  42. padded.insert(padded.end(), bytes.begin(), bytes.end());
  43. pad(padded);
  44. return MaxiCode::DecodedBitStreamParser::Decode(std::move(padded), mode);
  45. }
  46. // Helper to return Structured Append
  47. static StructuredAppendInfo info(ByteArray bytes, const int mode)
  48. {
  49. return parse(bytes, mode).structuredAppend();
  50. }
  51. TEST(MCDecoderTest, StructuredAppendSymbologyIdentifier)
  52. {
  53. // Null
  54. EXPECT_EQ(info({49}, 2).index, -1); // Mode 2
  55. EXPECT_EQ(info({49}, 2).count, -1);
  56. EXPECT_TRUE(info({49}, 2).id.empty());
  57. EXPECT_EQ(parse({49}, 2).symbologyIdentifier(), "]U1");
  58. EXPECT_EQ(info({49}, 3).index, -1); // Mode 3
  59. EXPECT_EQ(info({49}, 3).count, -1);
  60. EXPECT_TRUE(info({49}, 3).id.empty());
  61. EXPECT_EQ(parse({49}, 3).symbologyIdentifier(), "]U1");
  62. EXPECT_EQ(info({49}, 4).index, -1); // Mode 4
  63. EXPECT_EQ(info({49}, 4).count, -1);
  64. EXPECT_TRUE(info({49}, 4).id.empty());
  65. EXPECT_EQ(parse({49}, 4).symbologyIdentifier(), "]U0");
  66. EXPECT_EQ(info({49}, 5).index, -1); // Mode 5
  67. EXPECT_EQ(info({49}, 5).count, -1);
  68. EXPECT_TRUE(info({49}, 5).id.empty());
  69. EXPECT_EQ(parse({49}, 5).symbologyIdentifier(), "]U0");
  70. EXPECT_EQ(info({49}, 6).index, -1); // Mode 6
  71. EXPECT_EQ(info({49}, 6).count, -1);
  72. EXPECT_TRUE(info({49}, 6).id.empty());
  73. // EXPECT_TRUE(parse({49}, 6).symbologyIdentifier().empty()); // Not defined for reader initialisation/programming
  74. // ISO/IEC 16023:2000 4.9.1 example
  75. EXPECT_EQ(info({33, 22, 49}, 2).index, 2); // Mode 2 - 3rd position 1-based == index 2
  76. EXPECT_EQ(info({33, 22, 49}, 2).count, 7);
  77. EXPECT_TRUE(info({33, 22, 49}, 2).id.empty());
  78. EXPECT_EQ(info({33, 22, 49}, 3).index, 2); // Mode 3
  79. EXPECT_EQ(info({33, 22, 49}, 3).count, 7);
  80. EXPECT_TRUE(info({33, 22, 49}, 3).id.empty());
  81. EXPECT_EQ(info({33, 22, 49}, 4).index, 2); // Mode 4
  82. EXPECT_EQ(info({33, 22, 49}, 4).count, 7);
  83. EXPECT_TRUE(info({33, 22, 49}, 4).id.empty());
  84. EXPECT_EQ(info({33, 22, 49}, 5).index, 2); // Mode 5
  85. EXPECT_EQ(info({33, 22, 49}, 5).count, 7);
  86. EXPECT_TRUE(info({33, 22, 49}, 5).id.empty());
  87. EXPECT_EQ(info({33, 22, 49}, 6).index, 2); // Mode 6
  88. EXPECT_EQ(info({33, 22, 49}, 6).count, 7);
  89. EXPECT_TRUE(info({33, 22, 49}, 6).id.empty());
  90. // Various
  91. EXPECT_EQ(info({33, 007, 49}, 2).index, 0); // Mode 2
  92. EXPECT_EQ(info({33, 007, 49}, 2).count, 8);
  93. EXPECT_EQ(info({33, 007, 49}, 4).index, 0); // Mode 4
  94. EXPECT_EQ(info({33, 007, 49}, 4).count, 8);
  95. EXPECT_EQ(info({33, 067, 49}, 2).index, 6); // Mode 2
  96. EXPECT_EQ(info({33, 067, 49}, 2).count, 8);
  97. EXPECT_EQ(info({33, 067, 49}, 4).index, 6); // Mode 4
  98. EXPECT_EQ(info({33, 067, 49}, 4).count, 8);
  99. EXPECT_EQ(info({33, 077, 49}, 2).index, 7); // Mode 2
  100. EXPECT_EQ(info({33, 077, 49}, 2).count, 8);
  101. EXPECT_EQ(info({33, 077, 49}, 4).index, 7); // Mode 4
  102. EXPECT_EQ(info({33, 077, 49}, 4).count, 8);
  103. EXPECT_EQ(info({33, 001, 49}, 2).index, 0); // Mode 2
  104. EXPECT_EQ(info({33, 001, 49}, 2).count, 2);
  105. EXPECT_EQ(info({33, 001, 49}, 4).index, 0); // Mode 4
  106. EXPECT_EQ(info({33, 001, 49}, 4).count, 2);
  107. EXPECT_EQ(info({33, 011, 49}, 2).index, 1); // Mode 2
  108. EXPECT_EQ(info({33, 011, 49}, 2).count, 2);
  109. EXPECT_EQ(info({33, 011, 49}, 4).index, 1); // Mode 4
  110. EXPECT_EQ(info({33, 011, 49}, 4).count, 2);
  111. // Invalid
  112. EXPECT_EQ(info({33, 000, 49}, 2).index, 0); // Mode 2
  113. EXPECT_EQ(info({33, 000, 49}, 2).count, 0); // Count 1 set to 0
  114. EXPECT_EQ(info({33, 000, 49}, 4).index, 0); // Mode 4
  115. EXPECT_EQ(info({33, 000, 49}, 4).count, 0);
  116. EXPECT_EQ(info({33, 032, 49}, 2).index, 3); // Mode 2
  117. EXPECT_EQ(info({33, 032, 49}, 2).count, 0); // Count 3 <= index 3 so set to 0
  118. EXPECT_EQ(info({33, 032, 49}, 4).index, 3); // Mode 4
  119. EXPECT_EQ(info({33, 032, 49}, 4).count, 0);
  120. }
  121. TEST(MCDecoderTest, ReaderInit)
  122. {
  123. // Null
  124. EXPECT_FALSE(parse({49}, 2).readerInit()); // Mode 2
  125. EXPECT_TRUE(parse({49}, 2).isValid());
  126. // Set
  127. EXPECT_TRUE(parse({49}, 6).readerInit()); // Mode 6
  128. EXPECT_TRUE(parse({49}, 6).isValid());
  129. }
  130. TEST(MCDecoderTest, Mode2)
  131. {
  132. // Good data
  133. {
  134. // Postcode 1234, Postcode Length 4, Country 999, Class 999
  135. ByteArray mode2 = { 34, 52, 4, 0, 0, 0, 49, 57, 31, 62 };
  136. EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "1234\035999\035999\0351");
  137. }
  138. {
  139. // Postcode 0123, Postcode Length 4, Country 999, Class 999
  140. ByteArray mode2 = { 50, 30, 0, 0, 0, 0, 49, 57, 31, 62 };
  141. EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "0123\035999\035999\0351");
  142. }
  143. // Dodgy data (postcode length mismatch)
  144. {
  145. // Postcode 123456789, Postcode Length 4, Country 999, Class 999
  146. ByteArray mode2 = { 18, 5, 13, 47, 53, 1, 49, 57, 31, 62 };
  147. EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "1234\035999\035999\0351"); // Postcode truncated
  148. }
  149. {
  150. // Postcode 123, Postcode Length 4, Country 999, Class 999
  151. ByteArray mode2 = { 50, 30, 0, 0, 0, 0, 49, 57, 31, 62 };
  152. EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "0123\035999\035999\0351"); // Postcode zero-filled to len 4
  153. }
  154. // Out-of-range data
  155. {
  156. // Postcode 1, Postcode Length 10, Country 999, Class 999
  157. ByteArray mode2 = { 18, 0, 0, 0, 0, 32, 50, 57, 31, 62 };
  158. EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "000000001\035999\035999\0351"); // Postcode capped to len 9 & zero-filled
  159. }
  160. {
  161. // Postcode 1073741823 (0x3FFFFFFF, 30-bit max), Postcode Length 10, Country 999, Class 999
  162. ByteArray mode2 = { 50, 63, 63, 63, 63, 47, 50, 57, 31, 62 };
  163. EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "107374182\035999\035999\0351"); // Postcode truncated
  164. }
  165. {
  166. // Postcode 12345, Postcode Length 5, Country 1023 (0x3FF, 10-bit max), Class 999
  167. ByteArray mode2 = { 18, 14, 48, 0, 0, 16, 49, 63, 31, 62 };
  168. EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "12345\035999\035999\0351"); // Country capped to 999
  169. }
  170. {
  171. // Postcode 123456, Postcode Length 8, Country 999, Class 1000 (0x3E8)
  172. ByteArray mode2 = { 2, 16, 34, 7, 0, 0, 50, 57, 35, 62 };
  173. EXPECT_EQ(parse({49}, 2, &mode2).content().utf8(), "00123456\035999\035999\0351"); // Class capped to 999
  174. }
  175. }