use crate::error::{CaError, CaResult};
pub const DBR_STS_STRING: u16 = 7;
pub const DBR_TIME_STRING: u16 = 14;
pub const DBR_TIME_SHORT: u16 = 15;
pub const DBR_TIME_FLOAT: u16 = 16;
pub const DBR_TIME_ENUM: u16 = 17;
pub const DBR_TIME_CHAR: u16 = 18;
pub const DBR_TIME_LONG: u16 = 19;
pub const DBR_TIME_DOUBLE: u16 = 20;
pub const DBR_PUT_ACKT: u16 = 35;
pub const DBR_PUT_ACKS: u16 = 36;
pub const DBR_STSACK_STRING: u16 = 37;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)]
pub enum DbFieldType {
String = 0,
Short = 1, Float = 2,
Enum = 3,
Char = 4, Long = 5, Double = 6,
Int64 = 7,
}
impl DbFieldType {
pub fn from_u16(v: u16) -> CaResult<Self> {
match v {
0 => Ok(Self::String),
1 => Ok(Self::Short),
2 => Ok(Self::Float),
3 => Ok(Self::Enum),
4 => Ok(Self::Char),
5 => Ok(Self::Long),
6 => Ok(Self::Double),
_ => Err(CaError::UnsupportedType(v)),
}
}
pub fn element_size(&self) -> usize {
match self {
Self::String => 40, Self::Short | Self::Enum => 2,
Self::Float | Self::Long => 4,
Self::Char => 1,
Self::Double | Self::Int64 => 8,
}
}
pub fn time_dbr_type(&self) -> u16 {
let ca = match self {
Self::Int64 => Self::Double,
other => *other,
};
ca as u16 + 14
}
pub fn ctrl_dbr_type(&self) -> u16 {
let ca = match self {
Self::Int64 => Self::Double,
other => *other,
};
ca as u16 + 28
}
pub fn buffer_size(&self, count: usize) -> usize {
self.element_size() * count
}
pub fn to_dbr_type(&self) -> DbFieldType {
*self
}
}
pub fn dbr_buffer_size(dbr_type: u16, native_type: DbFieldType, count: usize) -> usize {
let value_size = native_type.element_size() * count;
let meta_size = match dbr_type / 7 {
0 => 0, 1 => 4, 2 => 12, 3 => {
match native_type {
DbFieldType::String => 4,
DbFieldType::Enum => 4 + 16 * 26, _ => 4 + 8 + 16 + 8 * 6, }
}
4 => {
match native_type {
DbFieldType::String => 4,
DbFieldType::Enum => 4 + 16 * 26,
_ => 4 + 8 + 16 + 8 * 8, }
}
_ => 0,
};
meta_size + value_size
}
fn dbr_native_index(dbr_type: u16) -> Option<u16> {
match dbr_type {
0..=6 => Some(dbr_type),
7..=13 => Some(dbr_type - 7),
14..=20 => Some(dbr_type - 14),
21..=27 => Some(dbr_type - 21),
28..=34 => Some(dbr_type - 28),
35 | 36 => Some(1), 37 => Some(0), _ => None,
}
}
pub fn native_type_for_dbr(dbr_type: u16) -> CaResult<DbFieldType> {
match dbr_native_index(dbr_type) {
Some(idx) => DbFieldType::from_u16(idx),
None => Err(CaError::UnsupportedType(dbr_type)),
}
}