@@ -163,7 +163,7 @@ read_rust!(dmap);
163163/// Generates two functions: `read_[type]` and `read_[type]_lax`, for strict and lax
164164/// reading, respectively.
165165macro_rules! read_py {
166- ( $name: ident, $py_name: literal, $lax_name: literal, $bytes_name: literal) => {
166+ ( $name: ident, $py_name: literal, $lax_name: literal, $bytes_name: literal, $lax_bytes_name : literal ) => {
167167 paste! {
168168 #[ doc = "Reads a `" $name: upper "` file, returning a list of dictionaries containing the fields." ]
169169 #[ pyfunction]
@@ -204,27 +204,44 @@ macro_rules! read_py {
204204 . collect( )
205205 )
206206 }
207+
208+ #[ doc = "Reads a `" $name: upper "` file, returning a tuple of" ]
209+ #[ doc = "(list of dictionaries containing the fields, byte where first corrupted record starts). " ]
210+ #[ pyfunction]
211+ #[ pyo3( name = $lax_bytes_name) ]
212+ #[ pyo3( text_signature = "(buf: bytes, /)" ) ]
213+ fn [ < read_ $name _bytes_lax_py >] (
214+ bytes: & [ u8 ] ,
215+ ) -> PyResult <( Vec <IndexMap <String , DmapField >>, Option <usize >) > {
216+ let result = [ < $name: camel Record >] :: read_records_lax( bytes) . map_err( PyErr :: from) ?;
217+ Ok ( (
218+ result. 0 . into_iter( ) . map( |rec| rec. inner( ) ) . collect( ) ,
219+ result. 1 ,
220+ ) )
221+ }
207222 }
208223 }
209224}
210225
211- read_py ! ( iqdat, "read_iqdat" , "read_iqdat_lax" , "read_iqdat_bytes" ) ;
226+ read_py ! ( iqdat, "read_iqdat" , "read_iqdat_lax" , "read_iqdat_bytes" , "read_iqdat_bytes_lax" ) ;
212227read_py ! (
213228 rawacf,
214229 "read_rawacf" ,
215230 "read_rawacf_lax" ,
216- "read_rawacf_bytes"
231+ "read_rawacf_bytes" ,
232+ "read_rawacf_bytes_lax"
217233) ;
218234read_py ! (
219235 fitacf,
220236 "read_fitacf" ,
221237 "read_fitacf_lax" ,
222- "read_fitacf_bytes"
238+ "read_fitacf_bytes" ,
239+ "read_fitacf_bytes_lax"
223240) ;
224- read_py ! ( grid, "read_grid" , "read_grid_lax" , "read_grid_bytes" ) ;
225- read_py ! ( map, "read_map" , "read_map_lax" , "read_map_bytes" ) ;
226- read_py ! ( snd, "read_snd" , "read_snd_lax" , "read_snd_bytes" ) ;
227- read_py ! ( dmap, "read_dmap" , "read_dmap_lax" , "read_dmap_bytes" ) ;
241+ read_py ! ( grid, "read_grid" , "read_grid_lax" , "read_grid_bytes" , "read_grid_bytes_lax" ) ;
242+ read_py ! ( map, "read_map" , "read_map_lax" , "read_map_bytes" , "read_map_bytes_lax" ) ;
243+ read_py ! ( snd, "read_snd" , "read_snd_lax" , "read_snd_bytes" , "read_snd_bytes_lax" ) ;
244+ read_py ! ( dmap, "read_dmap" , "read_dmap_lax" , "read_dmap_bytes" , "read_dmap_bytes_lax" ) ;
228245
229246/// Checks that a list of dictionaries contains DMAP records, then appends to outfile.
230247///
@@ -315,6 +332,15 @@ fn dmap(m: &Bound<'_, PyModule>) -> PyResult<()> {
315332 m. add_function ( wrap_pyfunction ! ( read_grid_bytes_py, m) ?) ?;
316333 m. add_function ( wrap_pyfunction ! ( read_map_bytes_py, m) ?) ?;
317334
335+ // Lax read functions from byte buffer
336+ m. add_function ( wrap_pyfunction ! ( read_dmap_bytes_lax_py, m) ?) ?;
337+ m. add_function ( wrap_pyfunction ! ( read_iqdat_bytes_lax_py, m) ?) ?;
338+ m. add_function ( wrap_pyfunction ! ( read_rawacf_bytes_lax_py, m) ?) ?;
339+ m. add_function ( wrap_pyfunction ! ( read_fitacf_bytes_lax_py, m) ?) ?;
340+ m. add_function ( wrap_pyfunction ! ( read_snd_bytes_lax_py, m) ?) ?;
341+ m. add_function ( wrap_pyfunction ! ( read_grid_bytes_lax_py, m) ?) ?;
342+ m. add_function ( wrap_pyfunction ! ( read_map_bytes_lax_py, m) ?) ?;
343+
318344 // Write functions
319345 m. add_function ( wrap_pyfunction ! ( write_dmap_py, m) ?) ?;
320346 m. add_function ( wrap_pyfunction ! ( write_iqdat_py, m) ?) ?;
0 commit comments