use crate::dec_context::DecContext;
use crate::dec_single_c::*;
use libc::c_char;
use std::ffi::{CStr, CString};
use std::fmt::Debug;
pub const DEC_SINGLE_BYTES: usize = 4;
pub const DEC_SINGLE_STRING: usize = 16;
pub const DEC_SINGLE_STRING_BUFFER: [c_char; DEC_SINGLE_STRING] = [0; DEC_SINGLE_STRING];
pub const DEC_SINGLE_ZERO: DecSingle = {
#[cfg(target_endian = "little")]
{
DecSingle {
bytes: [0x00, 0x00, 0x50, 0x22],
}
}
#[cfg(target_endian = "big")]
{
DecSingle {
bytes: [0x22, 0x50, 0x00, 0x00],
}
}
};
#[repr(C)]
#[derive(Copy, Clone)]
pub union DecSingle {
pub bytes: [u8; DEC_SINGLE_BYTES],
pub shorts: [u16; DEC_SINGLE_BYTES / 2],
pub words: [u32; DEC_SINGLE_BYTES / 4],
}
impl Default for DecSingle {
fn default() -> Self {
DEC_SINGLE_ZERO
}
}
impl Debug for DecSingle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"[{}]",
(0..DEC_SINGLE_BYTES)
.rev()
.fold("".to_string(), |s, i| format!("{} {:02X}", s, unsafe { self.bytes[i] }))
.trim_start()
)
}
}
pub fn dec_single_from_string(s: &str, dc: &mut DecContext) -> DecSingle {
let c_s = CString::new(s).unwrap();
let mut ds = DEC_SINGLE_ZERO;
unsafe {
decSingleFromString(&mut ds, c_s.as_ptr(), dc);
}
ds
}
pub fn dec_single_to_string(ds1: &DecSingle) -> String {
unsafe {
let mut buf = DEC_SINGLE_STRING_BUFFER;
decSingleToString(ds1, buf.as_mut_ptr() as *mut c_char);
CStr::from_ptr(buf.as_ptr() as *const c_char)
.to_string_lossy()
.into_owned()
}
}
pub fn dec_single_zero(ds1: &mut DecSingle) {
unsafe {
decSingleZero(ds1);
}
}