1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-14 20:10:02 +00:00

Merge pull request #744 from TomHarte/CRCTemplate

Better templates the CRC generator.
This commit is contained in:
Thomas Harte 2020-01-27 21:54:32 -05:00 committed by GitHub
commit 8e094598ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 22 deletions

View File

@ -15,19 +15,19 @@
namespace CRC { namespace CRC {
/*! Provides a class capable of generating a CRC from source data. */ /*! Provides a class capable of generating a CRC from source data. */
template <typename T, T reset_value, T xor_output, bool reflect_input, bool reflect_output> class Generator { template <typename IntType, IntType reset_value, IntType output_xor, bool reflect_input, bool reflect_output> class Generator {
public: public:
/*! /*!
Instantiates a CRC16 that will compute the CRC16 specified by the supplied Instantiates a CRC16 that will compute the CRC16 specified by the supplied
@c polynomial and @c reset_value. @c polynomial and @c reset_value.
*/ */
Generator(T polynomial): value_(reset_value) { Generator(IntType polynomial): value_(reset_value) {
const T top_bit = T(~(T(~0) >> 1)); const IntType top_bit = IntType(~(IntType(~0) >> 1));
for(int c = 0; c < 256; c++) { for(int c = 0; c < 256; c++) {
T shift_value = static_cast<T>(c << multibyte_shift); IntType shift_value = IntType(c << multibyte_shift);
for(int b = 0; b < 8; b++) { for(int b = 0; b < 8; b++) {
T exclusive_or = (shift_value&top_bit) ? polynomial : 0; IntType exclusive_or = (shift_value&top_bit) ? polynomial : 0;
shift_value = static_cast<T>(shift_value << 1) ^ exclusive_or; shift_value = IntType(shift_value << 1) ^ exclusive_or;
} }
xor_table[c] = shift_value; xor_table[c] = shift_value;
} }
@ -38,17 +38,17 @@ template <typename T, T reset_value, T xor_output, bool reflect_input, bool refl
/// Updates the CRC to include @c byte. /// Updates the CRC to include @c byte.
void add(uint8_t byte) { void add(uint8_t byte) {
if(reflect_input) byte = reverse_byte(byte); if constexpr (reflect_input) byte = reverse_byte(byte);
value_ = static_cast<T>((value_ << 8) ^ xor_table[(value_ >> multibyte_shift) ^ byte]); value_ = IntType((value_ << 8) ^ xor_table[(value_ >> multibyte_shift) ^ byte]);
} }
/// @returns The current value of the CRC. /// @returns The current value of the CRC.
inline T get_value() const { inline IntType get_value() const {
T result = value_^xor_output; IntType result = value_ ^ output_xor;
if(reflect_output) { if constexpr (reflect_output) {
T reflected_output = 0; IntType reflected_output = 0;
for(std::size_t c = 0; c < sizeof(T); ++c) { for(std::size_t c = 0; c < sizeof(IntType); ++c) {
reflected_output = T(reflected_output << 8) | T(reverse_byte(result & 0xff)); reflected_output = IntType(reflected_output << 8) | IntType(reverse_byte(result & 0xff));
result >>= 8; result >>= 8;
} }
return reflected_output; return reflected_output;
@ -57,7 +57,7 @@ template <typename T, T reset_value, T xor_output, bool reflect_input, bool refl
} }
/// Sets the current value of the CRC. /// Sets the current value of the CRC.
inline void set_value(T value) { value_ = value; } inline void set_value(IntType value) { value_ = value; }
/*! /*!
A compound for: A compound for:
@ -66,16 +66,30 @@ template <typename T, T reset_value, T xor_output, bool reflect_input, bool refl
[add all data from @c data] [add all data from @c data]
get_value() get_value()
*/ */
T compute_crc(const std::vector<uint8_t> &data) { template <typename Collection> IntType compute_crc(const Collection &data) {
return compute_crc(data.begin(), data.end());
}
/*!
A compound for:
reset()
[add all data from @c begin to @c end]
get_value()
*/
template <typename Iterator> IntType compute_crc(Iterator begin, Iterator end) {
reset(); reset();
for(const auto &byte: data) add(byte); while(begin != end) {
add(*begin);
++begin;
}
return get_value(); return get_value();
} }
private: private:
static constexpr int multibyte_shift = (sizeof(T) * 8) - 8; static constexpr int multibyte_shift = (sizeof(IntType) * 8) - 8;
T xor_table[256]; IntType xor_table[256];
T value_; IntType value_;
constexpr uint8_t reverse_byte(uint8_t byte) const { constexpr uint8_t reverse_byte(uint8_t byte) const {
return return

View File

@ -32,9 +32,8 @@ class DigitalPhaseLockedLoopDelegate {
- (instancetype)initWithClocksPerBit:(NSUInteger)clocksPerBit { - (instancetype)initWithClocksPerBit:(NSUInteger)clocksPerBit {
self = [super init]; self = [super init];
if(self) { if(self) {
_digitalPhaseLockedLoop = std::make_unique<Storage::DigitalPhaseLockedLoop<DigitalPhaseLockedLoopDelegate>>((unsigned int)clocksPerBit); _digitalPhaseLockedLoop = std::make_unique<Storage::DigitalPhaseLockedLoop<DigitalPhaseLockedLoopDelegate>>((unsigned int)clocksPerBit, _delegate);
_delegate.bridge = self; _delegate.bridge = self;
_digitalPhaseLockedLoop->set_delegate(&_delegate);
} }
return self; return self;
} }