This commit is contained in:
deeaitch committed 2026-10-13 08:17:49 -04:00
1 parent 7022c84941
commit c3d3bd51fb
72 files changed
+3703 -2484

No files matched your search

+15 -6
View File
@@ -369,7 +369,16 @@ Purpose</h1>
<hr />
<h1><a class="anchor" id="autotoc_md60"></a>
&lt;tt&gt;DecodeDatabase&lt;/tt&gt;</h1>
<p>Immutable runtime snapshot with a private frame index. Build it with <code>DbcDecodeBuilder::Build(parsed)</code> or construct it from <code>std::vector&lt;<a class="el" href="structDecodeFrame.html" title="Runtime-ready frame definition.">DecodeFrame</a>&gt;</code>. Construction rejects duplicate frame keys and duplicate signal names within a frame with <code>std::invalid_argument</code>, including manually supplied metadata.</p>
<p>Immutable runtime snapshot with a private frame index. Build it with <code>DbcDecodeBuilder::Build(parsed)</code> or construct it from <code>std::vector&lt;<a class="el" href="structDecodeFrame.html" title="Runtime-ready frame definition.">DecodeFrame</a>&gt;</code>. Construction validates all definitions before publishing the snapshot and throws <code>std::invalid_argument</code> for invalid metadata, including manually supplied data:</p>
<ul>
<li>Normalized CAN IDs must fit 11 bits for standard frames or 29 bits for extended frames. DBC's bit-31 encoding flag must already be removed.</li>
<li>Frame keys must be unique; signal names must be unique within their frame.</li>
<li>Signal lengths must be 1–64 bits, with Intel/Motorola layouts entirely inside the declared payload. Bit coordinates use overflow-safe 64-bit arithmetic.</li>
<li>Byte order, numeric type, and multiplexing role must be valid enum values.</li>
<li>Factor, offset, minimum, and maximum must be finite; minimum must not exceed maximum. Zero and negative factors are allowed.</li>
<li><a class="el" href="structMultiplexing.html">Multiplexing</a> requires one unsigned selector when branches are present, with branch values in its raw range. Signals may overlap only when they are branches selected by different raw values, including mixed byte orders.</li>
</ul>
<p><code>dlc</code> remains a byte count in the storage range 0–255; construction imposes no additional CAN/CAN FD payload limit. A zero-byte frame may contain no signals. Both <code><a class="el" href="classDbcDecodeBuilder.html#a2bc6386dfb5e58976c42e22c19ec471b" title="Build runtime decode database.">DbcDecodeBuilder::Build</a></code> and the direct constructor apply these rules. Construction copies the input, including nested metadata, even for rvalue input. Saved mutable aliases into that input cannot modify definitions or invalidate the lookup index. Database copies still share the frozen snapshot; a failed construction or replacement leaves the previous snapshot and its lookups intact.</p>
<ul>
<li><code>GetFrames()</code> returns a borrowed <code>const std::vector&lt;<a class="el" href="structDecodeFrame.html" title="Runtime-ready frame definition.">DecodeFrame</a>&gt;&amp;</code>.</li>
<li><code>FindFrame(FrameKey)</code> returns <code>std::shared_ptr&lt;const <a class="el" href="structDecodeFrame.html" title="Runtime-ready frame definition.">DecodeFrame</a>&gt;</code>.</li>
@@ -449,12 +458,12 @@ Raw value representation and precision</h2>
</table>
<p>Short-payload status takes precedence over signal errors; inspect each signal's status for the individual cause. <code>valid</code> retains its existing meaning of a matched definition and does not imply <code>status == FrameDecodeStatus::Valid</code>.</p>
<p>Payload policy uses <code>dlc</code> as a byte count, including for CAN FD; it is not the encoded wire DLC. A shorter payload is never padded: all signals whose bytes are available still decode, even if other signals fail. A longer payload is accepted; bytes beyond <code>dlc</code> are ignored. Signal bit layouts must fit the declared <code>dlc</code>, so extra bytes cannot rescue an invalid definition. Empty payloads and zero-byte frame definitions follow the same rules. Results include every signal in definition order, preserving successful values and definition handles on partial failures.</p>
<p>The decoder applies factor and offset; it does not clamp physical values to the declared minimum and maximum. Non-finite conversion results (NaN or positive/ negative infinity), including overflow with finite factor/offset, produce <code>PhysicalConversionFailed</code>. The exact raw value and non-finite <code>physicalValue</code> remain available, while signal <code>valid</code> is false. Non-finite factor/offset in manually constructed definitions follow this same conversion-result check. Physical conversion failure of a selector does not prevent raw branch selection.</p>
<p>The decoder applies factor and offset; it does not clamp physical values to the declared minimum and maximum. Non-finite conversion results (NaN or positive/ negative infinity), including overflow with finite factor/offset, produce <code>PhysicalConversionFailed</code>. The exact raw value and non-finite <code>physicalValue</code> remain available, while signal <code>valid</code> is false. Non-finite numeric parameters are rejected during database construction. Finite parameters can still overflow during conversion; conversion failure of a selector does not prevent raw branch selection.</p>
<h2><a class="anchor" id="autotoc_md70"></a>
Definition ownership and reload</h2>
<p><code><a class="el" href="structDecodedFrameValue.html#a33e971ba10030506007aa201c89f351d">DecodedFrameValue::definition</a></code> and <code><a class="el" href="structDecodedSignalValue.html#a828b5ef7faefc14fbf5dbd46249bcad2">DecodedSignalValue::definition</a></code> are owning <code>std::shared_ptr&lt;const ...&gt;</code> handles. Each handle retains the immutable runtime snapshot. Definitions remain valid until the last database copy, lookup handle, or decoded result owning that snapshot is released. An independently copied signal result retains its definition even after the parent frame result is removed. Copying or moving results preserves ownership.</p>
<p>Reload by assigning a newly built database. Stored results continue to describe the old DBC, including its units, scaling, comments, and <code>VAL_</code> descriptions; subsequent decoding uses the new DBC. Removed definitions cannot be found in the new database, but old results safely retain their old definitions. Keeping even one signal handle retains the whole old snapshot; release stored results when that metadata is no longer needed.</p>
<p><code>GetFrames()</code> is a borrowed view. References, iterators, and raw pointers obtained from it or from a handle's <code>.get()</code> do not retain ownership. Keep an owning handle or an unchanged database copy while using them. Do not retain mutable aliases into a vector moved into the database constructor. The raw string pointer from <code>GetValueDescription()</code> follows the same rule: keep the signal definition handle alive while using the string.</p>
<p><code>GetFrames()</code> is a borrowed view. References, iterators, and raw pointers obtained from it or from a handle's <code>.get()</code> do not retain ownership. Keep an owning handle or an unchanged database copy while using them. Constructor input is copied and may be changed independently afterward. The raw string pointer from <code>GetValueDescription()</code> follows the same rule: keep the signal definition handle alive while using the string.</p>
<p>Parsed <code><a class="el" href="structDbcDatabase.html" title="Parsed DBC content stored in a simple internal form.">DbcDatabase</a></code>/<code><a class="el" href="structFrameInfo.html" title="Describes one CAN frame from a DBC file.">FrameInfo</a></code>/<code><a class="el" href="structSignalInfo.html" title="Describes one signal inside a DBC frame.">SignalInfo</a></code> remain ordinary mutable value containers: borrowed pointers follow standard vector invalidation rules. Builders copy their metadata, so parsed input may be changed or destroyed after building. Tree nodes own metadata copies; the Qt model owns its tree and invalidates model indexes on reset. Runtime handles do not depend on the parsed database or tree. Synchronize replacement of a shared database variable with decoding; immutable snapshots do not make concurrent assignment to the same object safe.</p>
<h2><a class="anchor" id="autotoc_md71"></a>
Stable frame and signal identifiers</h2>
@@ -472,7 +481,7 @@ Stable frame and signal identifiers</h2>
<div class="ttc" id="aclassDbcDecodeBuilder_html"><div class="ttname"><a href="classDbcDecodeBuilder.html">DbcDecodeBuilder</a></div><div class="ttdoc">Converts parsed DBC data into runtime decode database.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decode__builder_8h_source.html#l00021">dbc_decode_builder.h:21</a></div></div>
<div class="ttc" id="aclassDbcDecodeBuilder_html_a2bc6386dfb5e58976c42e22c19ec471b"><div class="ttname"><a href="classDbcDecodeBuilder.html#a2bc6386dfb5e58976c42e22c19ec471b">DbcDecodeBuilder::Build</a></div><div class="ttdeci">DecodeDatabase Build(const DbcDatabase &amp;source) const</div><div class="ttdoc">Build runtime decode database.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decode__builder_8cpp_source.html#l00015">dbc_decode_builder.cpp:15</a></div></div>
<div class="ttc" id="aclassDbcDecoder_html"><div class="ttname"><a href="classDbcDecoder.html">DbcDecoder</a></div><div class="ttdoc">Runtime CAN decoder using prebuilt decode database.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decoder_8h_source.html#l00084">dbc_decoder.h:84</a></div></div>
<div class="ttc" id="aclassDbcDecoder_html_a345951ffe5d943a70d3a1ea1f39e74f7"><div class="ttname"><a href="classDbcDecoder.html#a345951ffe5d943a70d3a1ea1f39e74f7">DbcDecoder::Decode</a></div><div class="ttdeci">DecodedFrameValue Decode(const DecodeDatabase &amp;database, const RawCanFrame &amp;frame) const</div><div class="ttdoc">Decode one raw CAN frame.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decoder_8cpp_source.html#l00022">dbc_decoder.cpp:22</a></div></div>
<div class="ttc" id="aclassDbcDecoder_html_a345951ffe5d943a70d3a1ea1f39e74f7"><div class="ttname"><a href="classDbcDecoder.html#a345951ffe5d943a70d3a1ea1f39e74f7">DbcDecoder::Decode</a></div><div class="ttdeci">DecodedFrameValue Decode(const DecodeDatabase &amp;database, const RawCanFrame &amp;frame) const</div><div class="ttdoc">Decode one raw CAN frame.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decoder_8cpp_source.html#l00023">dbc_decoder.cpp:23</a></div></div>
<div class="ttc" id="aclassDecodeDatabase_html"><div class="ttname"><a href="classDecodeDatabase.html">DecodeDatabase</a></div><div class="ttdoc">Immutable runtime snapshot. Copies share storage; reload replaces a snapshot. Owning lookup handles a...</div><div class="ttdef"><b>Definition</b> <a href="decode__database_8h_source.html#l00087">decode_database.h:87</a></div></div>
<div class="ttc" id="astructDecodedFrameValue_html"><div class="ttname"><a href="structDecodedFrameValue.html">DecodedFrameValue</a></div><div class="ttdoc">Fully decoded frame.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decoder_8h_source.html#l00071">dbc_decoder.h:71</a></div></div>
<div class="ttc" id="astructDecodedFrameValue_html_a4f51c31110dba1f73a763c596372beb0"><div class="ttname"><a href="structDecodedFrameValue.html#a4f51c31110dba1f73a763c596372beb0">DecodedFrameValue::valid</a></div><div class="ttdeci">bool valid</div><div class="ttdef"><b>Definition</b> <a href="dbc__decoder_8h_source.html#l00075">dbc_decoder.h:75</a></div></div>
@@ -622,11 +631,11 @@ Basic multiplexing</h1>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><code>InsufficientPayload</code> </td><td class="markdownTableBodyNone">Selected or unconditional signal bytes are missing </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>InvalidDefinition</code> </td><td class="markdownTableBodyNone">Invalid length, byte order, numeric type, multiplexing role, layout outside declared DLC, or missing/invalid selector in manually built runtime metadata </td></tr>
<td class="markdownTableBodyNone"><code>InvalidDefinition</code> </td><td class="markdownTableBodyNone">Defensive decoder check failed; invalid definitions are rejected during database construction </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><code>PhysicalConversionFailed</code> </td><td class="markdownTableBodyNone">Raw value is available, but the converted physical value is NaN or infinity </td></tr>
</table>
<p>All statuses except <code>Valid</code> have <code>valid == false</code> and <code>GetValueDescription()</code> returns nullptr. <code>PhysicalConversionFailed</code> preserves extracted raw data and the non-finite conversion result; other invalid statuses have no decoded numeric data. Check <code>status</code> to distinguish inactive branches from errors. Consumers constructing runtime metadata manually must obey the same non-overlap rules as the parser. Extended and nested multiplexing are outside this stage and are explicitly rejected, rather than silently decoded as unconditional signals.</p>
<p>All statuses except <code>Valid</code> have <code>valid == false</code> and <code>GetValueDescription()</code> returns nullptr. <code>PhysicalConversionFailed</code> preserves extracted raw data and the non-finite conversion result; other invalid statuses have no decoded numeric data. Check <code>status</code> to distinguish inactive branches from errors. Consumers constructing runtime metadata manually receive the same selector and non-overlap validation as parsed files. Extended and nested multiplexing are outside this stage and are explicitly rejected, rather than silently decoded as unconditional signals.</p>
<hr />
<h1><a class="anchor" id="autotoc_md89"></a>
Comments</h1>