2024-08-10 12:10:21 +02:00
// to include std in docs, need to remove later
#[ doc(inline) ]
pub use std ;
2024-08-04 01:24:42 +02:00
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 { }