Krys4lide/crates/services-sesam-vitale-sys/src/lib.rs

124 lines
3.5 KiB
Rust
Raw Normal View History

2024-08-10 12:10:21 +02:00
// to include std in docs, need to remove later
#[doc(inline)]
pub use std;
2024-08-10 12:10:21 +02:00
mod bindings;
pub mod types;
use std::io::Cursor;
use bindings::SSV_LireConfig;
use binrw::BinRead;
use std::ptr;
use types::serialization_types::{DataBlock, DataField};
//pub fn read_carte_professionnel_sante() -> Result<CarteProfessionnelSante, _> {
// // how to init buffer and give it to library
// // https://stackoverflow.com/questions/58231215/what-is-proper-rust-way-to-allocate-opaque-buffer-for-external-c-library
// //
// // when init memory zones and they are too large to be a single memory zone -> https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0c1f0fca7d98a97bbc70dba786bbedd9
// unsafe {
// let nom_ressource_ps;
// let nom_ressource_lecteur;
// let code_porteur_ps;
// let p_zdata_out;
// let p_taille_zone;
// let status_code: u16 = SSV_LireCartePS(
// nom_ressource_ps,
// nom_ressource_lecteur,
// code_porteur_ps,
// p_zdata_out,
// p_taille_zone,
// );
//
// if status_code != 0 {
// return Err(());
// }
// };
//}
// To parse the data
// allocate the multiple buffers
// chain them to make a single buffer
// use the parse_data_size function to get a size
// use take method to limit number of bytes read
// use binread implementaiton on each struct/enum de structure it
// do this recursively until there is no more data
// Memory has three embricked concepts:
// Memory Zone(s) -Contains-> DataBlock(s) -Contains-> DataField(s)
// DataBlocks (and DataFields) can be cut off by the end of a memory zone
// the data continues on the following memory zone
//#[binread]
pub struct DataBlock2 {
//<T> {
data_struct_id: u16,
// #[br(temp, parse_with = parse_data_size)]
memory_size: u32,
// spec indicates the DataBlock can be very large (up to 4GB)
// in this case, we can use memmap2 to use the disk to store the data
// pub data: Vec<DataField<T>>,
2024-08-03 17:23:23 +02:00
}
2024-08-10 12:10:21 +02:00
pub enum SSVError {
Error(u16),
}
struct Parseable<T: BinRead>(T);
impl<T> BinRead for Parseable<T>
where
for<'a> T: BinRead<Args<'a> = ()>,
{
type Args<'a> = <DataField<T> as BinRead>::Args<'a>;
fn read_options<R: std::io::prelude::Read + std::io::prelude::Seek>(
reader: &mut R,
endian: binrw::Endian,
args: Self::Args<'_>,
) -> binrw::prelude::BinResult<Self> {
let field = DataField::<T>::read_options(reader, endian, args)?;
Ok(Parseable(field.value))
}
}
#[derive(BinRead)]
struct ConfigHeader {
ssv_version: Parseable<u16>,
galss_version: Parseable<u16>,
pss_version: Parseable<u16>,
}
#[derive(BinRead)]
struct ReaderConfig {
// manufacturer_name: Parseable<String>
}
pub fn read_config() -> Result<(), SSVError> {
let mut buffer_ptr: *mut libc::c_void = ptr::null_mut();
let mut size: libc::size_t = 0;
let buffer: &[u8] = unsafe {
match SSV_LireConfig(&mut buffer_ptr, &mut size) {
0 => (),
error_code => return Err(SSVError::Error(error_code)),
}
2024-08-03 17:23:23 +02:00
2024-08-10 12:10:21 +02:00
std::slice::from_raw_parts(buffer_ptr as *const u8, size)
};
unsafe { libc::free(buffer_ptr) };
println!("Buffer data: {:?}", buffer);
let cursor = &mut Cursor::new(buffer);
while size > 0 {
let data_block = DataBlock::read(cursor).expect("");
size -= data_block.data.len();
println!("{}", String::from_utf8(data_block.data).expect(""));
2024-08-03 17:23:23 +02:00
}
2024-08-10 12:10:21 +02:00
Ok(())
2024-08-03 17:23:23 +02:00
}
2024-08-10 12:10:21 +02:00
#[cfg(test)]
mod tests {}