From 85e5bfa543cf1e2402a8af89de6e0145e08119da Mon Sep 17 00:00:00 2001 From: Marcus Comstedt Date: Sun, 2 Feb 2020 22:50:11 +0100 Subject: [PATCH] LogicSegment: Use portable code for raw sample access This removes unaligned accesses and endianness assumptions. Also, the code does not access bytes outside the buffer anymore. --- pv/data/logicsegment.cpp | 16 ++++++++++++++-- pv/data/logicsegment.hpp | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/pv/data/logicsegment.cpp b/pv/data/logicsegment.cpp index 4a700adc..6e039798 100644 --- a/pv/data/logicsegment.cpp +++ b/pv/data/logicsegment.cpp @@ -507,6 +507,18 @@ LogicSegment::Edge* LogicSegment::add_state_to_sub_signal(RLEData* rle_data, return e; } +uint64_t LogicSegment::get_64_samples(const uint8_t *ptr, uint64_t sample_mask) +{ + uint64_t r = 0; + int n = 0; + while (sample_mask != 0) { + r |= (((uint64_t)*ptr++) & sample_mask) << n; + n += 8; + sample_mask >>= 8; + } + return r; +} + void LogicSegment::process_new_samples(void *data, uint64_t samples) { // To iterate over the sample data, we use uint64 to compare up to 64 signals at a time @@ -533,7 +545,7 @@ void LogicSegment::process_new_samples(void *data, uint64_t samples) if (sub_signals_.at(start_signal).edge_count == 0) { // Sub-signals are empty, use the current state as initial state - const uint64_t sample_value = (*(uint64_t*)ptr) & sample_mask; + const uint64_t sample_value = get_64_samples(ptr, sample_mask); prev_sample_value_.push_back(sample_value); prev_value = sample_value; @@ -568,7 +580,7 @@ void LogicSegment::process_new_samples(void *data, uint64_t samples) uint64_t same_sample_count = 0; for (uint64_t i = 0; i < samples; i++) { - const uint64_t sample_value = (*(uint64_t*)ptr) & sample_mask; + const uint64_t sample_value = get_64_samples(ptr, sample_mask); if (sample_value == prev_value) { // Sample value hasn't changed diff --git a/pv/data/logicsegment.hpp b/pv/data/logicsegment.hpp index 679019bb..ec1b8253 100644 --- a/pv/data/logicsegment.hpp +++ b/pv/data/logicsegment.hpp @@ -112,6 +112,9 @@ class LogicSegment : public Segment Edge* add_state_to_sub_signal(RLEData* rle_data, uint64_t samplenum, bool state, uint64_t length); + static inline uint64_t get_64_samples(const uint8_t *ptr, + uint64_t sample_mask); + void process_new_samples(void *data, uint64_t samples); private: