115 lines
3.7 KiB
C++
115 lines
3.7 KiB
C++
/**
|
|
* @file decode_database.h
|
|
* @brief
|
|
*
|
|
* Created: 2026-03-13
|
|
* Author: Deeaitch (Dim. Himro)
|
|
*
|
|
* Licensed under the MIT License.
|
|
* See LICENSE file in the project root for full license text.
|
|
*/
|
|
|
|
#ifndef DECODE_DATABASE_H
|
|
#define DECODE_DATABASE_H
|
|
|
|
#include "definition_key.h"
|
|
#include "multiplexing.h"
|
|
#include "value_descriptions.h"
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
/**
|
|
* @brief Signal byte order used for runtime decoding.
|
|
*/
|
|
enum class ByteOrder {
|
|
Intel,
|
|
Motorola
|
|
};
|
|
|
|
/**
|
|
* @brief Signal numeric type.
|
|
*/
|
|
enum class ValueType {
|
|
Unsigned,
|
|
Signed
|
|
};
|
|
|
|
/**
|
|
* @brief Runtime-ready signal definition.
|
|
*/
|
|
struct DecodeSignal {
|
|
Multiplexing multiplexing;
|
|
std::string name; /**< Signal name. */
|
|
std::uint32_t startBit = 0U; /**< DBC start bit. */
|
|
std::uint32_t length = 0U; /**< Signal length in bits. */
|
|
ByteOrder byteOrder = ByteOrder::Intel; /**< Intel or Motorola. */
|
|
ValueType valueType = ValueType::Unsigned; /**< Signed or unsigned. */
|
|
double factor = 1.0; /**< Scaling factor. */
|
|
double offset = 0.0; /**< Physical offset. */
|
|
double minimum = 0.0; /**< Minimum physical value. */
|
|
double maximum = 0.0; /**< Maximum physical value. */
|
|
std::string unit; /**< Physical unit. */
|
|
std::vector<std::string> receivers; /**< Receivers. */
|
|
ValueDescriptions valueDescriptions; /**< Raw integer state descriptions. */
|
|
std::string comment; /**< Comment. */
|
|
|
|
DecodeSignal() = default;
|
|
};
|
|
|
|
/**
|
|
* @brief Runtime-ready frame definition.
|
|
*/
|
|
struct DecodeFrame {
|
|
std::string name; /**< Frame name. */
|
|
std::uint32_t canId = 0U; /**< Normalized CAN ID. */
|
|
bool isExtended = false; /**< true for extended frame. */
|
|
std::uint8_t dlc = 0U; /**< Payload length. */
|
|
std::uint32_t pgn = 0U; /**< PGN if available. */
|
|
bool hasPgn = false; /**< true if PGN is valid. */
|
|
std::string transmitter; /**< Transmitter ECU. */
|
|
std::string comment; /**< Frame comment. */
|
|
std::vector<DecodeSignal> signals; /**< Signal definitions. */
|
|
|
|
DecodeFrame() = default;
|
|
|
|
FrameKey GetKey() const {
|
|
return FrameKey(canId, isExtended);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief Immutable runtime snapshot. Copies share storage; reload replaces a snapshot.
|
|
* Owning lookup handles and decoded results keep old definitions alive.
|
|
*/
|
|
class DecodeDatabase {
|
|
public:
|
|
DecodeDatabase() = default;
|
|
/**
|
|
* Copy and validate definitions before building the frame index.
|
|
* Input aliases cannot modify the snapshot, even for rvalue input.
|
|
* @throws std::invalid_argument for invalid metadata or duplicate keys.
|
|
*/
|
|
explicit DecodeDatabase(const std::vector<DecodeFrame> &frames);
|
|
|
|
/** Borrowed view, valid while this snapshot remains alive and unchanged. */
|
|
const std::vector<DecodeFrame> &GetFrames() const;
|
|
/** Owning handles retain the entire snapshot across reload or destruction. */
|
|
std::shared_ptr<const DecodeFrame> FindFrame(const FrameKey &key) const;
|
|
std::shared_ptr<const DecodeSignal> FindSignal(const SignalKey &key) const;
|
|
|
|
private:
|
|
struct Storage {
|
|
std::vector<DecodeFrame> frames;
|
|
std::unordered_map<FrameKey, std::size_t, FrameKeyHasher> frameIndexByKey;
|
|
|
|
explicit Storage(const std::vector<DecodeFrame> &definitions);
|
|
};
|
|
|
|
std::shared_ptr<const Storage> storage;
|
|
};
|
|
|
|
#endif /* DECODE_DATABASE_H */
|