Files
fluxengine/lib/decoders/fluxmapreader.h
David Given ce4cabde96 Rework the kmedian code to do all arithmetic in ticks rather than us. This
apparently improves things --- precision related, maybe?
2020-07-04 14:35:04 +01:00

121 lines
2.8 KiB
C++

#ifndef FLUXMAPREADER_H
#define FLUXMAPREADER_H
#include "fluxmap.h"
#include "protocol.h"
#include "flags.h"
extern FlagGroup fluxmapReaderFlags;
class FluxMatcher;
struct FluxMatch
{
const FluxMatcher* matcher;
unsigned intervals;
double clock;
unsigned zeroes;
};
class FluxMatcher
{
public:
virtual ~FluxMatcher() {}
/* Returns the number of intervals matched */
virtual bool matches(const unsigned* intervals, FluxMatch& match) const = 0;
virtual unsigned intervals() const = 0;
};
class FluxPattern : public FluxMatcher
{
public:
FluxPattern(unsigned bits, uint64_t patterns);
bool matches(const unsigned* intervals, FluxMatch& match) const override;
unsigned intervals() const override
{ return _intervals.size(); }
private:
std::vector<unsigned> _intervals;
unsigned _length;
unsigned _bits;
uint64_t _pattern;
unsigned _highzeroes;
bool _lowzero = false;
public:
friend void test_patternconstruction();
friend void test_patternmatching();
};
class FluxMatchers : public FluxMatcher
{
public:
FluxMatchers(const std::initializer_list<const FluxMatcher*> matchers);
bool matches(const unsigned* intervals, FluxMatch& match) const override;
unsigned intervals() const override
{ return _intervals; }
private:
unsigned _intervals;
std::vector<const FluxMatcher*> _matchers;
};
class FluxmapReader
{
public:
FluxmapReader(const Fluxmap& fluxmap);
FluxmapReader(const Fluxmap& fluxmap, int bands, bool isInterleaved);
FluxmapReader(const Fluxmap&& fluxmap) = delete;
void rewind()
{
_pos.bytes = 0;
_pos.ticks = 0;
_pos.zeroes = 0;
}
bool eof() const
{ return _pos.bytes == _size; }
Fluxmap::Position tell() const
{ return _pos; }
/* Important! You can only reliably seek to 1 bits. */
void seek(const Fluxmap::Position& pos)
{
_pos = pos;
}
uint8_t getNextEvent(unsigned& ticks);
unsigned findEvent(uint8_t bits);
unsigned readInterval(); /* with debounce support */
/* Important! You can only reliably seek to 1 bits. */
void seek(nanoseconds_t ns);
void seekToIndexMark();
nanoseconds_t seekToPattern(const FluxMatcher& pattern);
nanoseconds_t seekToPattern(const FluxMatcher& pattern, const FluxMatcher*& matching);
bool readRawBit();
std::vector<bool> readRawBits(unsigned count);
std::vector<bool> readRawBits(const Fluxmap::Position& until);
const std::vector<nanoseconds_t> intervals() const { return _intervals; };
private:
const Fluxmap& _fluxmap;
const uint8_t* _bytes;
const size_t _size;
Fluxmap::Position _pos;
std::vector<nanoseconds_t> _intervals;
const bool _isInterleaved;
};
#endif