///|
pub struct SignalReference {
message_id_value : Int
message_name_value : String
signal_value : DbcSignal
} derive(Eq, Debug)
///|
pub(all) struct MessageFilter {
transmitter : String?
receiver : String?
name_contains : String?
minimum_size : Int?
maximum_size : Int?
}
///|
pub fn MessageFilter::all() -> MessageFilter {
{
transmitter: None,
receiver: None,
name_contains: None,
minimum_size: None,
maximum_size: None,
}
}
///|
pub fn SignalReference::message_id(self : SignalReference) -> Int {
self.message_id_value
}
///|
pub fn SignalReference::message_name(self : SignalReference) -> String {
self.message_name_value
}
///|
pub fn SignalReference::signal(self : SignalReference) -> DbcSignal {
self.signal_value
}
///|
fn string_contains_case_insensitive(value : String, needle : String) -> Bool {
if needle == "" {
return true
}
let lower_value = value.to_lower()
let lower_needle = needle.to_lower()
if lower_needle.length() > lower_value.length() {
return false
}
for index in 0..<(lower_value.length() - lower_needle.length() + 1) {
if lower_value[index:index + lower_needle.length()].to_owned() ==
lower_needle {
return true
}
}
false
}
///|
fn signal_has_receiver(signal : DbcSignal, receiver : String) -> Bool {
for candidate in signal.receivers() {
if candidate == receiver {
return true
}
}
false
}
///|
fn message_has_receiver(message : DbcMessage, receiver : String) -> Bool {
for signal in message.signals() {
if signal_has_receiver(signal, receiver) {
return true
}
}
false
}
///|
fn message_matches_filter(message : DbcMessage, filter : MessageFilter) -> Bool {
match filter.transmitter {
Some(value) if message.transmitter() != value => return false
_ => ()
}
match filter.receiver {
Some(value) if !message_has_receiver(message, value) => return false
_ => ()
}
match filter.name_contains {
Some(value) if !string_contains_case_insensitive(message.name(), value) =>
return false
_ => ()
}
match filter.minimum_size {
Some(value) if message.size() < value => return false
_ => ()
}
match filter.maximum_size {
Some(value) if message.size() > value => return false
_ => ()
}
true
}
///|
pub fn select_messages(
database : DbcDatabase,
filter : MessageFilter,
) -> Array[DbcMessage] {
let selected : Array[DbcMessage] = []
for message in database.messages() {
if message_matches_filter(message, filter) {
selected.push(message)
}
}
selected
}
///|
pub fn find_signals_by_name(
database : DbcDatabase,
query : String,
) -> Array[SignalReference] {
let found : Array[SignalReference] = []
for message in database.messages() {
for signal in message.signals() {
if string_contains_case_insensitive(signal.name(), query) {
found.push({
message_id_value: message.id(),
message_name_value: message.name(),
signal_value: signal,
})
}
}
}
found
}
///|
pub fn messages_transmitted_by(
database : DbcDatabase,
node : String,
) -> Array[DbcMessage] {
select_messages(database, { ..MessageFilter::all(), transmitter: Some(node) })
}
///|
pub fn messages_received_by(
database : DbcDatabase,
node : String,
) -> Array[DbcMessage] {
select_messages(database, { ..MessageFilter::all(), receiver: Some(node) })
}