53 lines
1.9 KiB
C++
53 lines
1.9 KiB
C++
// SPDX-License-Identifier: MIT
|
|
// Copyright (c) 2026 Dim Himro
|
|
|
|
#include "decode_database.h"
|
|
#include <stdexcept>
|
|
#include <unordered_set>
|
|
#include <utility>
|
|
|
|
DecodeDatabase::Storage::Storage(std::vector<DecodeFrame> definitions)
|
|
: frames(std::move(definitions)) {
|
|
frameIndexByKey.reserve(frames.size());
|
|
for (std::size_t index = 0U; index < frames.size(); ++index) {
|
|
const DecodeFrame &frame = frames[index];
|
|
if (!frameIndexByKey.emplace(frame.GetKey(), index).second)
|
|
throw std::invalid_argument("Duplicate runtime frame key");
|
|
std::unordered_set<std::string> names;
|
|
for (const DecodeSignal &signal: frame.signals) {
|
|
if (!names.insert(signal.name).second)
|
|
throw std::invalid_argument("Duplicate runtime signal key");
|
|
}
|
|
}
|
|
}
|
|
|
|
DecodeDatabase::DecodeDatabase(std::vector<DecodeFrame> frames)
|
|
: storage(std::make_shared<const Storage>(std::move(frames))) {
|
|
}
|
|
|
|
const std::vector<DecodeFrame> &DecodeDatabase::GetFrames() const {
|
|
static const std::vector<DecodeFrame> empty;
|
|
return storage ? storage->frames : empty;
|
|
}
|
|
|
|
std::shared_ptr<const DecodeFrame> DecodeDatabase::FindFrame(const FrameKey &key) const {
|
|
if (!storage)
|
|
return nullptr;
|
|
const std::unordered_map<FrameKey, std::size_t, FrameKeyHasher>::const_iterator it =
|
|
storage->frameIndexByKey.find(key);
|
|
if (it == storage->frameIndexByKey.end())
|
|
return nullptr;
|
|
return std::shared_ptr<const DecodeFrame>(storage, &storage->frames[it->second]);
|
|
}
|
|
|
|
std::shared_ptr<const DecodeSignal> DecodeDatabase::FindSignal(const SignalKey &key) const {
|
|
const std::shared_ptr<const DecodeFrame> frame = FindFrame(key.frame);
|
|
if (!frame)
|
|
return nullptr;
|
|
for (const DecodeSignal &signal: frame->signals) {
|
|
if (signal.name == key.name)
|
|
return std::shared_ptr<const DecodeSignal>(frame, &signal);
|
|
}
|
|
return nullptr;
|
|
}
|