mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-07 12:54:34 +00:00
Merge pull request #744 from TomHarte/CRCTemplate
Better templates the CRC generator.
This commit is contained in:
commit
8e094598ca
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user