// to include std in docs, need to remove later #[doc(inline)] pub use std; 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 { // // 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 { // { 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>, } pub enum SSVError { Error(u16), } struct Parseable(T); impl BinRead for Parseable where for<'a> T: BinRead = ()>, { type Args<'a> = as BinRead>::Args<'a>; fn read_options( reader: &mut R, endian: binrw::Endian, args: Self::Args<'_>, ) -> binrw::prelude::BinResult { let field = DataField::::read_options(reader, endian, args)?; Ok(Parseable(field.value)) } } #[derive(BinRead)] struct ConfigHeader { ssv_version: Parseable, galss_version: Parseable, pss_version: Parseable, } #[derive(BinRead)] struct ReaderConfig { // manufacturer_name: Parseable } 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)), } 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("")); } Ok(()) } #[cfg(test)] mod tests {}