@@ -25,6 +25,9 @@ struct SignalLayoutEntry {
2525 }
2626
2727 SignalLayoutEntry (const SignalLayoutEntry&) = default ;
28+ SignalLayoutEntry& operator =(const SignalLayoutEntry&) = default ;
29+ SignalLayoutEntry (SignalLayoutEntry&&) = default ;
30+ SignalLayoutEntry& operator =(SignalLayoutEntry&&) = default ;
2831
2932 const CANSignal* src_signal;
3033 SignalRanges ranges;
@@ -65,9 +68,21 @@ SignalRanges little_endian_ranges(const CANSignal& src) {
6568 // which does not really represent anything in terms of layout. So we need
6669 // to compute the ranges for each byte individually anyway.
6770
68- unsigned byteAnalyzed = 0 ;
71+ unsigned bitsLeft = src. length () ;
6972 bool is_start_byte = 0 ;
7073
74+ for (unsigned current_byte = src.start_bit () / 8 ; bitsLeft > 0 ; current_byte++, is_start_byte = false ) {
75+ unsigned lbit = 7 -( src.start_bit () + bitsLeft);
76+ unsigned rbit = 7 - src.start_bit ();
77+
78+ // The static_cast are not "necessary" but it removes some warnings
79+ result.push_back ({ static_cast <uint8_t >(current_byte),
80+ static_cast <uint8_t >(lbit),
81+ static_cast <uint8_t >(rbit) });
82+
83+ bitsLeft -= (rbit - lbit);
84+ }
85+
7186 return result;
7287}
7388
@@ -91,32 +106,34 @@ std::vector<SignalLayoutEntry> compute_layout(const CANFrame& src) {
91106 return result;
92107}
93108
109+ bool overlap (const SignalLayoutEntry& e1 , const SignalLayoutEntry& e2 ) {
110+ for (const SignalRange& r1 : e1 .ranges ) {
111+ for (const SignalRange& r2: e2 .ranges ) {
112+ // Find if r2 shares a SignalRange with the same byte with r1
113+ if (r1.byte != r2.byte )
114+ continue ;
115+
116+ // Now we know that the SignalRange(s) share a common byte
117+
118+ // ordered.first is the leftmost SignalRange in the byte
119+ // ordered.second is the rightmost SignalRange in the byte
120+ auto ordered = std::minmax (r1, r2, [](const SignalRange& r, const SignalRange& rr) {
121+ return r.lr_start_bit < rr.lr_start_bit ;
122+ });
123+
124+ // No overlapping if the last bit of the leftmost is before the first
125+ // bit of the rightmost.
126+ if (ordered.first .lr_end_bit < ordered.second .lr_start_bit )
127+ return true ;
128+ }
129+ }
130+
131+ return false ;
132+ }
133+
94134bool CppCAN::analysis::is_frame_layout_ok (const CANFrame& src) {
95135 auto layout = compute_layout (src);
96136
97- auto overlap = [](const SignalLayoutEntry& e1 , const SignalLayoutEntry& e2 ) -> bool {
98- return std::any_of (e1 .ranges .begin (), e1 .ranges .end (), [&e2 ](const SignalRange& r1) {
99- // Find if r2 shares a SignalRange with the same byte with r1
100- auto r2 = std::find_if (e2 .ranges .begin (), e2 .ranges .end (), [&r1](const SignalRange& e_range) {
101- return r1.byte == e_range.byte ;
102- });
103-
104- // The signals are on completely different bytes
105- if (r2 == e2 .ranges .end ())
106- return false ;
107-
108- // ordered.first is the leftmost SignalRange in the byte
109- // ordered.second is the rightmost SignalRange in the byte
110- auto ordered = std::minmax (r1, *r2, [](const SignalRange& r, const SignalRange& rr) {
111- return r.lr_start_bit < rr.lr_start_bit ;
112- });
113-
114- // No overlapping if the last bit of the leftmost is before the first
115- // bit of the rightmost.
116- return ordered.first .lr_end_bit < ordered.second .lr_start_bit ;
117- });
118- };
119-
120137 for (size_t i = 0 ; i < layout.size (); i++) {
121138 const SignalLayoutEntry& e = layout[i];
122139
0 commit comments