CRC16_test.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include "catch.hpp"
  2. #include "CRC16.hh"
  3. using namespace openmsx;
  4. TEST_CASE("CRC16")
  5. {
  6. CRC16 crc;
  7. REQUIRE(crc.getValue() == 0xFFFF);
  8. // Test a simple sequence
  9. SECTION("'3 x A1' in a loop") {
  10. for (int i = 0; i < 3; ++i) crc.update(0xA1);
  11. CHECK(crc.getValue() == 0xCDB4);
  12. }
  13. SECTION("'3 x A1' in one chunk") {
  14. static constexpr uint8_t buf[3] = { 0xA1, 0xA1, 0xA1 };
  15. crc.update(buf, 3);
  16. CHECK(crc.getValue() == 0xCDB4);
  17. }
  18. SECTION("'3 x A1' via init") {
  19. crc.init({0xA1, 0xA1, 0xA1});
  20. CHECK(crc.getValue() == 0xCDB4);
  21. }
  22. // Internally the block-update method works on chunks of 8 bytes,
  23. // so also try a few bigger examples
  24. // not (an integer) multiple of 8
  25. SECTION("'123456789' in a loop") {
  26. for (char c : {'1', '2', '3', '4', '5', '6', '7', '8', '9'}) crc.update(c);
  27. CHECK(crc.getValue() == 0x29B1);
  28. }
  29. SECTION("'123456789' in one chunk") {
  30. static constexpr const char* const digits = "123456789";
  31. crc.update(reinterpret_cast<const uint8_t*>(digits), 9);
  32. CHECK(crc.getValue() == 0x29B1);
  33. }
  34. // same as disk sector size
  35. SECTION("512 bytes") {
  36. uint8_t buf[512];
  37. for (int i = 0; i < 512; ++i) buf[i] = i & 255;
  38. SECTION("in a loop") {
  39. for (char c : buf) crc.update(c);
  40. CHECK(crc.getValue() == 0x56EE);
  41. }
  42. SECTION("in one chunk") {
  43. crc.update(buf, sizeof(buf));
  44. CHECK(crc.getValue() == 0x56EE);
  45. }
  46. }
  47. // Tests for init<..>()
  48. // It's possible to pass up-to 4 parameters. Verify that this gives
  49. // the same result as the other 2 CRC calculation methods.
  50. SECTION("'11' in a loop") {
  51. for (char c : {0x11}) crc.update(c);
  52. CHECK(crc.getValue() == 0xE3E0);
  53. }
  54. SECTION("'11' in one chunk") {
  55. static constexpr uint8_t buf[] = {0x11};
  56. crc.update(buf, sizeof(buf));
  57. CHECK(crc.getValue() == 0xE3E0);
  58. }
  59. SECTION("'11' via init") {
  60. crc.init({0x11});
  61. CHECK(crc.getValue() == 0xE3E0);
  62. }
  63. SECTION("'11 22' in a loop") {
  64. for (char c : {0x11, 0x22}) crc.update(c);
  65. CHECK(crc.getValue() == 0x296D);
  66. }
  67. SECTION("'11 22' in one chunk") {
  68. static constexpr uint8_t buf[] = {0x11, 0x22};
  69. crc.update(buf, sizeof(buf));
  70. CHECK(crc.getValue() == 0x296D);
  71. }
  72. SECTION("'11 22' via init") {
  73. crc.init({0x11, 0x22});
  74. CHECK(crc.getValue() == 0x296D);
  75. }
  76. SECTION("'11 22 33' in a loop") {
  77. for (char c : {0x11, 0x22, 0x33}) crc.update(c);
  78. CHECK(crc.getValue() == 0xDE7B);
  79. }
  80. SECTION("'11 22 33' in one chunk") {
  81. static constexpr uint8_t buf[] = {0x11, 0x22, 0x33};
  82. crc.update(buf, sizeof(buf));
  83. CHECK(crc.getValue() == 0xDE7B);
  84. }
  85. SECTION("'11 22 33' via init") {
  86. crc.init({0x11, 0x22, 0x33});
  87. CHECK(crc.getValue() == 0xDE7B);
  88. }
  89. SECTION("'11 22 33 44' in a loop") {
  90. for (char c : {0x11, 0x22, 0x33, 0x44}) crc.update(c);
  91. CHECK(crc.getValue() == 0x59F3);
  92. }
  93. SECTION("'11 22 33 44' in one chunk") {
  94. static constexpr uint8_t buf[] = {0x11, 0x22, 0x33, 0x44};
  95. crc.update(buf, sizeof(buf));
  96. CHECK(crc.getValue() == 0x59F3);
  97. }
  98. SECTION("'11 22 33 44' via init") {
  99. crc.init({0x11, 0x22, 0x33, 0x44});
  100. CHECK(crc.getValue() == 0x59F3);
  101. }
  102. }
  103. #if 0
  104. // Functions to inspect the quality of the generated code
  105. uint16_t test_init()
  106. {
  107. // I verified that gcc is capable of optimizing this to 'return 0xcdb4'.
  108. CRC16 crc;
  109. crc.init({0xA1, 0xA1, 0xA1});
  110. return crc.getValue();
  111. }
  112. #endif