Line data Source code
1 : // Copyright 2024 Accenture. 2 : 3 : /** 4 : * Contains BitFieldFilter class. 5 : * \file BitFieldFilter.h 6 : * \ingroup filter 7 : */ 8 : #pragma once 9 : 10 : #include "can/canframes/CANFrame.h" 11 : #include "can/filter/AbstractStaticBitFieldFilter.h" 12 : #include "can/filter/IFilter.h" 13 : #include "can/filter/IMerger.h" 14 : #include "can/filter/IntervalFilter.h" 15 : 16 : #include <platform/estdint.h> 17 : 18 : #include <cstring> 19 : 20 : namespace can 21 : { 22 : /** 23 : * Cpp2CAN BitFieldFilter 24 : * 25 : * 26 : * A BitFieldFilter for 11-bit CAN ids allows to filter an id range 27 : * on CAN (0 - MAX_ID). 28 : * 29 : * \see IFilter 30 : * \see IMerger 31 : */ 32 : class BitFieldFilter 33 : : public IFilter 34 : , public IMerger 35 : { 36 : public: 37 : /** maximum id storable in this filter */ 38 : static uint16_t const MAX_ID = static_cast<uint16_t>(CANFrame::MAX_FRAME_ID); 39 : /** number of bits occupied by this filter */ 40 : static uint16_t const NUMBER_OF_BITS = MAX_ID + 1U; 41 : /** size (in byte) of filters bitmask */ 42 : static uint16_t const MASK_SIZE = NUMBER_OF_BITS / 8U; 43 : 44 : /** 45 : * default constructor 46 : */ 47 : BitFieldFilter(); 48 : 49 : /** 50 : * \see IFilter::add() 51 : * \pre filterId <= MAX_ID 52 : * \post match(filterId) 53 : * \throws assertion 54 : */ 55 : void add(uint32_t filterId) override; 56 : 57 : /** 58 : * \see IFilter::add() 59 : * \pre from <= MAX_ID 60 : * \pre to <= MAX_ID 61 : * \post match(from...to) 62 : * \throws assertion 63 : * 64 : * \note 65 : * Range includes both from and to. 66 : */ 67 : void add(uint32_t from, uint32_t to) override; 68 : 69 : /** 70 : * \see IFilter::match() 71 : * \param filterId id to check 72 : * \return 73 : * - true if internal mask matches filterId 74 : * - false else 75 : */ 76 : bool match(uint32_t filterId) const override; 77 : 78 : /** 79 : * \see IFilter::clear() 80 : */ 81 88 : void clear() override { (void)memset(_mask, 0x0, static_cast<size_t>(MASK_SIZE)); } 82 : 83 : /** 84 : * \see IFilter::open() 85 : */ 86 2 : void open() override { (void)memset(_mask, 0xFF, static_cast<size_t>(MASK_SIZE)); } 87 : 88 : /** 89 : * \see IFilter::acceptMerger() 90 : */ 91 4 : void acceptMerger(IMerger& merger) override { merger.mergeWithBitField(*this); } 92 : 93 : /** 94 : * merges with a BitFieldFilter 95 : * \param filter BitFieldFilter to merge with 96 : */ 97 4 : void mergeWithBitField(BitFieldFilter const& filter) override 98 : { 99 1285 : for (uint16_t i = 0U; i < MASK_SIZE; ++i) 100 : { 101 1280 : _mask[i] |= filter._mask[i]; 102 : } 103 4 : } 104 : 105 : /** 106 : * merges with a AbstractStaticBitFieldFilter 107 : * \param filter AbstractStaticBitFieldFilter to merge with 108 : */ 109 1 : void mergeWithStaticBitField(AbstractStaticBitFieldFilter const& filter) override 110 : { 111 257 : for (uint16_t i = 0U; i < MASK_SIZE; ++i) 112 : { 113 256 : _mask[i] |= filter.getMaskValue(i); 114 : } 115 1 : } 116 : 117 : /** 118 : * merges with an IntervalFilter 119 : * \param filter IntervalFilter to merge with 120 : */ 121 9 : void mergeWithInterval(IntervalFilter const& filter) override 122 : { 123 9 : if (filter.getLowerBound() <= filter.getUpperBound()) 124 : { 125 5 : uint32_t const toId 126 5 : = (filter.getUpperBound() <= MAX_ID) ? filter.getUpperBound() : MAX_ID; 127 5 : add(filter.getLowerBound(), toId); 128 : } 129 9 : } 130 : 131 2 : uint8_t const* getRawBitField() const { return &_mask[0]; } 132 : 133 : private: 134 : friend bool operator==(BitFieldFilter const& x, BitFieldFilter const& y); 135 : BitFieldFilter(BitFieldFilter const&); 136 : BitFieldFilter& operator=(BitFieldFilter const&); 137 : uint8_t _mask[MASK_SIZE]{}; 138 : }; 139 : 140 : /** 141 : * compares two BitFieldFilter objects 142 : * \param x first operand of comparison 143 : * \param y second operand of comparison 144 : * \return 145 : * - true: both filters are equal 146 : * - false: filters are not equal 147 : */ 148 : inline bool operator==(BitFieldFilter const& x, BitFieldFilter const& y) 149 : { 150 396 : for (uint16_t i = 0U; i < BitFieldFilter::MASK_SIZE; ++i) 151 : { 152 395 : if (x._mask[i] != y._mask[i]) 153 : { 154 : return false; 155 : } 156 : } 157 : return true; 158 : } 159 : 160 : } // namespace can