openMSX
CRC16_test.cc
Go to the documentation of this file.
1#include "catch.hpp"
2#include "CRC16.hh"
3#include "xrange.hh"
4#include <array>
5
6using namespace openmsx;
7
8TEST_CASE("CRC16")
9{
10 CRC16 crc;
11 REQUIRE(crc.getValue() == 0xFFFF);
12
13 // Test a simple sequence
14 SECTION("'3 x A1' in a loop") {
15 repeat(3, [&] { crc.update(0xA1); });
16 CHECK(crc.getValue() == 0xCDB4);
17 }
18 SECTION("'3 x A1' in one chunk") {
19 static constexpr std::array<uint8_t, 3> buf = { 0xA1, 0xA1, 0xA1 };
20 crc.update(buf);
21 CHECK(crc.getValue() == 0xCDB4);
22 }
23 SECTION("'3 x A1' via init") {
24 crc.init({0xA1, 0xA1, 0xA1});
25 CHECK(crc.getValue() == 0xCDB4);
26 }
27
28 // Internally the block-update method works on chunks of 8 bytes,
29 // so also try a few bigger examples
30 // not (an integer) multiple of 8
31 SECTION("'123456789' in a loop") {
32 for (char c : {'1', '2', '3', '4', '5', '6', '7', '8', '9'}) crc.update(c);
33 CHECK(crc.getValue() == 0x29B1);
34 }
35 SECTION("'123456789' in one chunk") {
36 static constexpr const char* const digits = "123456789";
37 crc.update(std::span{reinterpret_cast<const uint8_t*>(digits), 9});
38 CHECK(crc.getValue() == 0x29B1);
39 }
40 // same as disk sector size
41 SECTION("512 bytes") {
42 std::array<uint8_t, 512> buf;
43 for (auto i : xrange(512)) buf[i] = i & 255;
44 SECTION("in a loop") {
45 for (char c : buf) crc.update(c);
46 CHECK(crc.getValue() == 0x56EE);
47 }
48 SECTION("in one chunk") {
49 crc.update(buf);
50 CHECK(crc.getValue() == 0x56EE);
51 }
52 }
53
54 // Tests for init<..>()
55 // It's possible to pass up-to 4 parameters. Verify that this gives
56 // the same result as the other 2 CRC calculation methods.
57 SECTION("'11' in a loop") {
58 for (char c : {0x11}) crc.update(c);
59 CHECK(crc.getValue() == 0xE3E0);
60 }
61 SECTION("'11' in one chunk") {
62 static constexpr std::array<uint8_t, 1> buf = {0x11};
63 crc.update(buf);
64 CHECK(crc.getValue() == 0xE3E0);
65 }
66 SECTION("'11' via init") {
67 crc.init({0x11});
68 CHECK(crc.getValue() == 0xE3E0);
69 }
70
71 SECTION("'11 22' in a loop") {
72 for (char c : {0x11, 0x22}) crc.update(c);
73 CHECK(crc.getValue() == 0x296D);
74 }
75 SECTION("'11 22' in one chunk") {
76 static constexpr std::array<uint8_t, 2> buf = {0x11, 0x22};
77 crc.update(buf);
78 CHECK(crc.getValue() == 0x296D);
79 }
80 SECTION("'11 22' via init") {
81 crc.init({0x11, 0x22});
82 CHECK(crc.getValue() == 0x296D);
83 }
84
85 SECTION("'11 22 33' in a loop") {
86 for (char c : {0x11, 0x22, 0x33}) crc.update(c);
87 CHECK(crc.getValue() == 0xDE7B);
88 }
89 SECTION("'11 22 33' in one chunk") {
90 static constexpr std::array<uint8_t, 3> buf = {0x11, 0x22, 0x33};
91 crc.update(buf);
92 CHECK(crc.getValue() == 0xDE7B);
93 }
94 SECTION("'11 22 33' via init") {
95 crc.init({0x11, 0x22, 0x33});
96 CHECK(crc.getValue() == 0xDE7B);
97 }
98
99 SECTION("'11 22 33 44' in a loop") {
100 for (char c : {0x11, 0x22, 0x33, 0x44}) crc.update(c);
101 CHECK(crc.getValue() == 0x59F3);
102 }
103 SECTION("'11 22 33 44' in one chunk") {
104 static constexpr std::array<uint8_t, 4> buf = {0x11, 0x22, 0x33, 0x44};
105 crc.update(buf);
106 CHECK(crc.getValue() == 0x59F3);
107 }
108 SECTION("'11 22 33 44' via init") {
109 crc.init({0x11, 0x22, 0x33, 0x44});
110 CHECK(crc.getValue() == 0x59F3);
111 }
112}
113
114
115#if 0
116
117// Functions to inspect the quality of the generated code
118
119uint16_t test_init()
120{
121 // I verified that gcc is capable of optimizing this to 'return 0xcdb4'.
122 CRC16 crc;
123 crc.init({0xA1, 0xA1, 0xA1});
124 return crc.getValue();
125}
126
127#endif
TEST_CASE("CRC16")
Definition: CRC16_test.cc:8
This class calculates CRC numbers for the polygon x^16 + x^12 + x^5 + 1.
Definition: CRC16.hh:18
constexpr void update(uint8_t value)
Update CRC with one byte.
Definition: CRC16.hh:44
constexpr uint16_t getValue() const
Get current CRC value.
Definition: CRC16.hh:88
constexpr void init(uint16_t initialCRC)
(Re)initialize the current value
Definition: CRC16.hh:29
CHECK(m3==m3)
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr void repeat(T n, Op op)
Repeat the given operation 'op' 'n' times.
Definition: xrange.hh:148
constexpr auto xrange(T e)
Definition: xrange.hh:133