#pragma once #include #include namespace radio_controller { struct sample { uint16_t period_us; uint16_t pulse_us; }; class sample_iterator { public: virtual int size() = 0; virtual void reset() = 0; virtual bool next() = 0; virtual bool has_next() const = 0; virtual const sample &value() const = 0; }; class bit_string final { uint32_t a_ = 0; uint32_t b_ = 0; int size_ = 0; public: int size() const { return size_; } __attribute__((noinline)) uint32_t extract_bits(int start, int count) { if (start + count > 32) { halt(); } uint32_t value = a_ >> start; auto mask = uint32_t((1 << count + 1) - 1); return value & mask; } uint32_t u32(int i) { switch (i) { case 0: return a_; case 1: return b_; default: return 0; } } void append(bool value) { if (size_ < 32) { if (value) { a_ |= 1 << size_; } } else if (size_ < 64) { if (value) { b_ |= 1 << size_ - 32; } } else { return; } size_++; } }; enum class decoding_state { OK, TOO_SHORT, BAD_START, SHORT_BODY }; class decoding_result { public: decoding_state state; bit_string data; decoding_result(decoding_state state) : state(state), data() {} decoding_result(decoding_state state, bit_string data) : state(state), data(data) {} }; class decoder { public: virtual decoding_result decode(sample_iterator *it) = 0; }; } // namespace radio_controller