Browse Source

refactored crc module and added simple unittests

stefan 3 years ago
parent
commit
ebf0e28843

+ 3 - 1
makefile

@@ -43,7 +43,9 @@ UNITTEST_SOURCES := test/unittest/test_main.cpp
                     test/unittest/shellmatta_autocomplete/test_autocomplete_run.cpp     \
                     test/unittest/shellmatta_escape/test_escape_processArrowKeys.cpp    \
                     test/unittest/shellmatta_history/test_appendHistoryByte.cpp         \
-                    test/unittest/shellmatta/test_shellmatta_doInit.cpp
+                    test/unittest/shellmatta/test_shellmatta_doInit.cpp                 \
+                    test/unittest/shellmatta_crc/test_crc32Slow.cpp                     \
+                    test/unittest/shellmatta_crc/test_crc32Fast.cpp
 
 INTEGRATIONTEST_SOURCES :=  test/integrationtest/test_main.cpp                  \
                             test/integrationtest/test_integration.cpp           \

+ 54 - 39
src/shellmatta_crc.c

@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2019 - 2021 Stefan Strobel <stefan.strobel@shimatta.net>
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
 /**
  * @file    shellmatta_crc.c
  * @brief   cyclic redundancy check functions of shellmatta
@@ -6,9 +14,9 @@
 
 #include "shellmatta_crc.h"
 
-#ifndef CRC_NO_LOOKUP
+#ifndef SHELLMATTA_TRANSPORT_CRC_NO_LOOKUP
+/** \brief CRC Lookup table for 0x04c11db7 reflected */
 uint32_t crc32Table[] = {
-    /* 0x04c11db7 reflected */
     0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
     0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
     0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
@@ -44,91 +52,98 @@ uint32_t crc32Table[] = {
 };
 #endif
 
+#ifdef SHELLMATTA_TRANSPORT_CRC_NO_LOOKUP
 /**
  * @brief       Reverses bits of a value.
  * @param[in]   x       input value
  * @param[in]   size    amount of bits used in value
+ * @return      reversed data
  */
-uint32_t reverse(uint32_t x, int bits)
+static uint32_t reverse(uint32_t x, uint32_t bits)
 {
-    x = ((x & 0x55555555) << 1)  | ((x & 0xAAAAAAAA) >> 1);
-    x = ((x & 0x33333333) << 2)  | ((x & 0xCCCCCCCC) >> 2);
-    x = ((x & 0x0F0F0F0F) << 4)  | ((x & 0xF0F0F0F0) >> 4);
-    x = ((x & 0x00FF00FF) << 8)  | ((x & 0xFF00FF00) >> 8);
-    x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16);
-    return x >> (32 - bits);
+    x = ((x & 0x55555555u) << 1u)  | ((x & 0xAAAAAAAAu) >> 1u);
+    x = ((x & 0x33333333u) << 2u)  | ((x & 0xCCCCCCCCu) >> 2u);
+    x = ((x & 0x0F0F0F0Fu) << 4u)  | ((x & 0xF0F0F0F0u) >> 4u);
+    x = ((x & 0x00FF00FFu) << 8u)  | ((x & 0xFF00FF00u) >> 8u);
+    x = ((x & 0x0000FFFFu) << 16u) | ((x & 0xFFFF0000u) >> 16u);
+    return x >> (32u - bits);
 }
 
-/**
- * @brief       Computes the crc32-checksum of a buffer.
- * @param[in]   data            pointer to data buffer
- * @param[in]   size            amount of bytes to be processed
- */
-uint32_t crc32Calc(char* data, uint16_t size)
-{
-    #ifdef  CRC_NO_LOOKUP
-        return crc32Slow(data, size);
-    #else
-        return crc32Fast(data, size, crc32Table);
-    #endif
-}
 
 /**
  * @brief       Computes the crc32-checksum of a buffer. O(4n)
  * @param[in]   data            pointer to data buffer
  * @param[in]   size            amount of bytes to be processed
+ * @return      crc             calculated crc32 value
  */
-uint32_t crc32Slow(char* data, uint16_t size)
+static uint32_t crc32Slow(char* data, uint16_t size)
 {
     uint16_t i;
     uint8_t j;
     uint8_t pivotByte;
-    uint32_t polynom = reverse(CRC32_POLYNOM, 32);
+    uint32_t polynom = reverse(CRC32_POLYNOM, 32u);
 
-    /* start with 0xffffffff */
-    uint32_t crcTemp = 0xffffffff;
+    /* start with 0xffffffffu */
+    uint32_t crcTemp = 0xffffffffu;
 
-    for (i = 0; i < size; i++)
+    for (i = 0u; i < size; i++)
     {
         pivotByte = data[i];
-        for (j = 0; j < BITS_PER_BYTE; j++)
+        for (j = 0u; j < BITS_PER_BYTE; j++)
         {
-            if ((crcTemp & 1) != (pivotByte & 1))
+            if ((crcTemp & 1u) != (pivotByte & 1u))
             {
-                crcTemp = (crcTemp >> 1) ^ polynom;
+                crcTemp = (crcTemp >> 1u) ^ polynom;
             }
             else
             {
-                crcTemp >>= 1;
+                crcTemp >>= 1u;
             }
-            pivotByte >>= 1;
+            pivotByte >>= 1u;
         }
     }
 
     /* final xor */
-    crcTemp ^= 0xffffffff;
+    crcTemp ^= 0xffffffffu;
 
     return crcTemp;
 }
 
-#ifndef CRC_NO_LOOKUP
+#else
 /**
  * @brief       Computes the crc32-checksum of a buffer. O(n)
  * @param[in]   data            pointer to data buffer
  * @param[in]   size            amount of bytes to be processed
  * @param[in]   lookupTable     pointer to uint32_t lookup table for crc computation
+ * @return      crc             calculated crc32 value
  */
-uint32_t crc32Fast(char* data, uint16_t size, uint32_t* lookupTable)
+static uint32_t crc32Fast(char* data, uint16_t size, uint32_t* lookupTable)
 {
     uint16_t i;
-    uint32_t crcTemp = 0xffffffff;
+    uint32_t crcTemp = 0xffffffffu;
 
-    for (i = 0; i < size; i++)
+    for (i = 0u; i < size; i++)
     {
-        uint8_t index = data[i] ^ (crcTemp & 0xff);
-        crcTemp = lookupTable[index] ^ (crcTemp >> 8);
+        uint8_t index = data[i] ^ (crcTemp & 0xffu);
+        crcTemp = lookupTable[index] ^ (crcTemp >> 8u);
     }
 
     return ~crcTemp;
 }
 #endif
+
+
+/**
+ * @brief       Computes the crc32-checksum of a buffer.
+ * @param[in]   data            pointer to data buffer
+ * @param[in]   size            amount of bytes to be processed
+ * @return      crc             calculated crc32 value
+ */
+uint32_t crc32Calc(char* data, uint16_t size)
+{
+    #ifdef  SHELLMATTA_TRANSPORT_CRC_NO_LOOKUP
+        return crc32Slow(data, size);
+    #else
+        return crc32Fast(data, size, crc32Table);
+    #endif
+}

+ 10 - 7
src/shellmatta_crc.h

@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2019 - 2021 Stefan Strobel <stefan.strobel@shimatta.net>
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
 /**
  * @file    shellmatta_crc.h
  * @brief   cyclic redundancy check functions of shellmatta
@@ -9,14 +17,9 @@
 
 #include <stdint.h>
 
-#define CRC32_POLYNOM   0x04c11db7      /* crc-32 ethernet 802.3 */
-#define BITS_PER_BYTE   ((uint8_t)8)    /* amount of bits per byte; to avoid magic number */
+#define CRC32_POLYNOM   0x04c11db7u     /**< crc-32 ethernet 802.3                          */
+#define BITS_PER_BYTE   ((uint8_t)8)    /**< amount of bits per byte; to avoid magic number */
 
 uint32_t crc32Calc(char* data, uint16_t size);
-uint32_t crc32Slow(char* data, uint16_t size);
-
-#ifndef CRC_NO_LOOKUP
-uint32_t crc32Fast(char* data, uint16_t size, uint32_t* lookupTable);
-#endif
 
 #endif /* _SHELLMATTA_CRC_H_ */

+ 12 - 0
test/unittest/shellmatta_crc/test_crc32Fast.cpp

@@ -0,0 +1,12 @@
+#include "test/framework/catch.hpp"
+#include <string.h>
+
+#undef SHELLMATTA_TRANSPORT_CRC_NO_LOOKUP
+#include "src/shellmatta_crc.c"
+
+TEST_CASE( "shellmatta_crc crc32Fast" ) {
+
+    uint32_t crc = crc32Fast((char*)"123456789", 9, crc32Table);
+
+    REQUIRE( crc == 0xCBF43926u);
+}

+ 12 - 0
test/unittest/shellmatta_crc/test_crc32Slow.cpp

@@ -0,0 +1,12 @@
+#include "test/framework/catch.hpp"
+#include <string.h>
+
+#define SHELLMATTA_TRANSPORT_CRC_NO_LOOKUP
+#include "src/shellmatta_crc.c"
+
+TEST_CASE( "shellmatta_crc crc32Slow" ) {
+
+    uint32_t crc = crc32Slow((char*)"123456789", 9);
+
+    REQUIRE( crc == 0xCBF43926u);
+}