Skip to content

Commit ab7d86b

Browse files
author
lschuetze
committed
Bug fixes and polishing
1 parent 1674268 commit ab7d86b

File tree

20 files changed

+766
-524
lines changed

20 files changed

+766
-524
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@
55
*tar.gz
66
*.clang_complete
77
*.root
8-
98
.idea/

malice/src/event.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use std::fmt::Debug;
44
use failure::Error;
55
use futures::prelude::*;
66
use itertools::izip;
7-
use nom::{combinator::map, number::complete::*, sequence::tuple, IResult};
7+
use nom::{combinator::map, number::complete::*, sequence::tuple};
88
use wasm_bindgen::prelude::*;
99

10-
use root_io::core::parsers::{parse_custom_mantissa, parse_tobjarray_of_tnameds, RootError};
10+
use root_io::core::parsers::{Span, RResult, parse_custom_mantissa, parse_tobjarray_of_tnameds, RootError};
1111
use root_io::stream_zip;
1212
use root_io::tree_reader::Tree;
1313

@@ -241,9 +241,9 @@ fn string_to_mask(s: &str, run_number: i32) -> TriggerMask {
241241
}
242242
}
243243

244-
fn parse_pid_probabilities<'s, E>(input: &'s [u8]) -> IResult<&'s [u8], PidProbabilities, E>
244+
fn parse_pid_probabilities<'s, E>(input: Span<'s>) -> RResult<'s, PidProbabilities, E>
245245
where
246-
E: RootError<&'s [u8]>,
246+
E: RootError<Span<'s>>,
247247
{
248248
let (input, electron) = parse_custom_mantissa(input, 8)?;
249249
let (input, muon) = parse_custom_mantissa(input, 8)?;

root-io/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ uuid = "0.8.2"
2424
lz4-compress = "0.1.1"
2525
nom = "7"
2626
nom-supreme = "0.6"
27+
nom_locate = "4.0.0"
2728
thiserror = "1"
29+
ouroboros = "0.14"
2830

2931
[target.'cfg(target_arch = "wasm32")'.dependencies]
3032
wasm-bindgen-futures = "0.4"

root-io/src/core/data_source.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::io::{Read, Seek, SeekFrom};
99
use std::path::Path;
1010
use std::path::PathBuf;
1111

12-
use crate::tree_reader::ReadError;
12+
use crate::core::ReadError;
1313

1414
/// The source from where the Root file is read. Construct it using
1515
/// `.into()` on a `Url` or `Path`. The latter is not availible for

root-io/src/core/file.rs

Lines changed: 92 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use nom::{self,
2-
IResult,
32
number::complete::{be_i16, be_i32, be_u128, be_u16, be_u32, be_u64, be_u8}, Parser};
43
use nom::sequence::tuple;
54
use nom_supreme::{ParserExt, tag::complete::tag};
@@ -13,7 +12,7 @@ use crate::{
1312
core::tstreamer::streamers,
1413
MAP_OFFSET,
1514
};
16-
use crate::tree_reader::{ReadError, WriteError};
15+
use crate::core::{ReadError, WriteError};
1716

1817
/// Size of serialized `FileHeader` in bytes
1918
const FILE_HEADER_SIZE: u64 = 75;
@@ -60,57 +59,60 @@ pub struct Directory {
6059
}
6160

6261
/// Parse opening part of a root file
63-
fn file_header<'s, E: RootError<&'s [u8]>>(i: &'s [u8]) -> IResult<&'s [u8], FileHeader, E> {
64-
fn version_dep_int<'s, E: RootError<&'s [u8]>>(i: &'s [u8], is_64_bit: bool) -> IResult<&'s [u8], u64, E> {
65-
if is_64_bit {
66-
be_u64(i)
67-
} else {
68-
let (i, end) = be_u32(i)?;
69-
Ok((i, end as u64))
62+
fn file_header<'s, E: RootError<Span<'s>>>(i: Span<'s>) -> RResult<'s, FileHeader, E> {
63+
let parser = |i| {
64+
fn version_dep_int<'s, E: RootError<Span<'s>>>(i: Span<'s>, is_64_bit: bool) -> RResult<'s, u64, E> {
65+
if is_64_bit {
66+
be_u64(i)
67+
} else {
68+
let (i, end) = be_u32(i)?;
69+
Ok((i, end as u64))
70+
}
7071
}
71-
}
72-
let (i, _) = tag("root")(i)?;
73-
let (i, version) = be_i32(i)?;
74-
let is_64_bit = version > 1000000;
75-
let (i, begin) = be_i32(i)?;
76-
let (i, end) = version_dep_int(i, is_64_bit)?;
77-
let (i, seek_free) = version_dep_int(i, is_64_bit)?;
78-
let (i, nbytes_free) = be_i32(i)?;
79-
let (i, n_entries_free) = be_i32(i)?;
80-
let (i, n_bytes_name) = be_i32(i)?;
81-
let (i, pointer_size) = be_u8(i)?;
82-
let (i, compression) = be_i32(i)?;
83-
let (i, seek_info) = version_dep_int(i, is_64_bit)?;
84-
let (i, nbytes_info) = be_i32(i)?;
85-
let (i, _uuid_version) = be_u16(i)?;
86-
let (i, uuid) = be_u128(i)?;
87-
88-
let uuid = Uuid::from_u128(uuid);
89-
let seek_dir = (begin + n_bytes_name) as u64;
90-
Ok((
91-
i,
92-
FileHeader {
93-
version,
94-
begin,
95-
end,
96-
seek_free,
97-
nbytes_free,
98-
n_entries_free,
99-
n_bytes_name,
100-
pointer_size,
101-
compression,
102-
seek_info,
103-
nbytes_info,
104-
uuid,
105-
seek_dir,
106-
},
107-
))
72+
let (i, _) = tag("root")(i)?;
73+
let (i, version) = be_i32(i)?;
74+
let is_64_bit = version > 1000000;
75+
let (i, begin) = be_i32(i)?;
76+
let (i, end) = version_dep_int(i, is_64_bit)?;
77+
let (i, seek_free) = version_dep_int(i, is_64_bit)?;
78+
let (i, nbytes_free) = be_i32(i)?;
79+
let (i, n_entries_free) = be_i32(i)?;
80+
let (i, n_bytes_name) = be_i32(i)?;
81+
let (i, pointer_size) = be_u8(i)?;
82+
let (i, compression) = be_i32(i)?;
83+
let (i, seek_info) = version_dep_int(i, is_64_bit)?;
84+
let (i, nbytes_info) = be_i32(i)?;
85+
let (i, _uuid_version) = be_u16(i)?;
86+
let (i, uuid) = be_u128(i)?;
87+
88+
let uuid = Uuid::from_u128(uuid);
89+
let seek_dir = (begin + n_bytes_name) as u64;
90+
Ok((
91+
i,
92+
FileHeader {
93+
version,
94+
begin,
95+
end,
96+
seek_free,
97+
nbytes_free,
98+
n_entries_free,
99+
n_bytes_name,
100+
pointer_size,
101+
compression,
102+
seek_info,
103+
nbytes_info,
104+
uuid,
105+
seek_dir,
106+
},
107+
))
108+
};
109+
parser.context("file header").parse(i)
108110
}
109111

110112
/// Parse a file-pointer based on the version of the file
111-
fn versioned_pointer<'s, E>(version: i16) -> impl nom::Parser<&'s [u8], u64, E>
113+
fn versioned_pointer<'s, E>(version: i16) -> impl RParser<'s, u64, E>
112114
where
113-
E: RootError<&'s [u8]>
115+
E: RootError<Span<'s>>
114116
{
115117
move |i| {
116118
if version > 1000 {
@@ -122,9 +124,9 @@ fn versioned_pointer<'s, E>(version: i16) -> impl nom::Parser<&'s [u8], u64, E>
122124
}
123125

124126
/// Directory within a root file; exists on ever file
125-
fn directory<'s, E>(input: &'s [u8]) -> IResult<&'s [u8], Directory, E>
127+
fn directory<'s, E>(input: Span<'s>) -> RResult<'s, Directory, E>
126128
where
127-
E: RootError<&'s [u8]>
129+
E: RootError<Span<'s>>
128130
{
129131
tuple((
130132
be_i16.context("directory version"),
@@ -158,7 +160,7 @@ impl RootFile {
158160
pub async fn new<S: Into<Source>>(source: S) -> Result<Self, ReadError> {
159161
let source = source.into();
160162
let hdr_buf = source.fetch(0, FILE_HEADER_SIZE).await?;
161-
let hdr = wrap_parser(file_header.all_consuming())(&hdr_buf)?;
163+
let hdr = wrap_parser(file_header.context("file header"))(&hdr_buf)?;
162164
//let hdr = _hdr?;
163165

164166
// Jump to the TDirectory and parse it
@@ -179,13 +181,11 @@ impl RootFile {
179181
}
180182

181183
pub async fn get_streamer_context(&self) -> Result<Context, ReadError> {
182-
let seek_info_len = (self.hdr.nbytes_info + 4) as u64;
183-
let info_key_buf = self
184-
.source
184+
let seek_info_len = (self.hdr.nbytes_info) as u64;
185+
let info_key_buf = self.source
185186
.fetch(self.hdr.seek_info, seek_info_len)
186187
.await?;
187-
let info_key = wrap_parser(tkey.all_consuming())(&info_key_buf)?;
188-
188+
let info_key = wrap_parser(tkey.all_consuming().context("streamer info key"))(&info_key_buf)?;
189189
let key_len = info_key.hdr.key_len;
190190
Ok(Context {
191191
source: self.source.clone(),
@@ -202,8 +202,7 @@ impl RootFile {
202202
/// Get the stream info of this file
203203
pub async fn streamer_infos(&self) -> Result<Vec<TStreamerInfo>, ReadError> {
204204
let ctx = self.get_streamer_context().await?;
205-
let buf = ctx.s.as_slice();
206-
let res = wrap_parser(streamers(&ctx))(buf)?;
205+
let res = wrap_parser_ctx(streamers)(&ctx)?;
207206
Ok(res)
208207
}
209208

@@ -286,7 +285,12 @@ mod test {
286285
let sources: Vec<Source> = vec![local, remote];
287286
for source in &sources {
288287
let hdr_buf = source.fetch(0, FILE_HEADER_SIZE).await?;
289-
let hdr = wrap_parser(file_header.all_consuming())(&hdr_buf)?;
288+
let hdr = match wrap_parser(file_header)(&hdr_buf) {
289+
Ok(hdr) => hdr,
290+
Err(e) => {
291+
println!("{}", e);
292+
return Err(ReadError::ParseError(e)); }
293+
};
290294

291295
let should = FileHeader {
292296
version: 60600,
@@ -315,10 +319,20 @@ mod test {
315319
let sources: Vec<Source> = vec![local, remote];
316320
for source in &sources {
317321
let hdr_buf = source.fetch(0, FILE_HEADER_SIZE).await?;
318-
let hdr = wrap_parser(file_header.all_consuming())(&hdr_buf)?;
322+
let hdr = match wrap_parser(file_header)(&hdr_buf) {
323+
Ok(hdr) => hdr,
324+
Err(e) => {
325+
println!("{}", e);
326+
return Err(ReadError::ParseError(e)); }
327+
};
319328

320329
let dir_buf = source.fetch(hdr.seek_dir, TDIRECTORY_MAX_SIZE).await?;
321-
let dir = wrap_parser(directory)(&dir_buf)?;
330+
let dir = match wrap_parser(directory)(&dir_buf) {
331+
Ok(dir) => dir,
332+
Err(e) => {
333+
println!("{}", e);
334+
return Err(ReadError::ParseError(e)); }
335+
};
322336

323337
assert_eq!(
324338
dir,
@@ -348,7 +362,12 @@ mod test {
348362
let sources: Vec<Source> = vec![local, remote];
349363
for source in &sources {
350364
let key_buf = source.fetch(1117, 4446).await?;
351-
let key = wrap_parser(tkey.all_consuming())(&key_buf)?;
365+
let key = match wrap_parser(tkey)(&key_buf) {
366+
Ok(key) => key,
367+
Err(e) => {
368+
println!("{}", e);
369+
return Err(ReadError::ParseError(e)); }
370+
};
352371

353372
assert_eq!(key.hdr.obj_name, "StreamerInfo");
354373

@@ -360,9 +379,17 @@ mod test {
360379
s: key.obj,
361380
};
362381

363-
let l = wrap_parser(length_value(checked_byte_count, |i| {
364-
tlist::<VerboseError<_>>(&context).parse(i)
365-
}).all_consuming())(&context.s)?;
382+
let mut parser = wrap_parser_ctx(|ctx| {
383+
length_value(checked_byte_count, move |i| {
384+
tlist::<VerboseError<_>>(&ctx).parse(i)
385+
}).all_consuming()
386+
});
387+
let l = match parser(&context) {
388+
Ok(l) => l,
389+
Err(e) => {
390+
println!("{}", e);
391+
return Err(ReadError::ParseError(e)); }
392+
};
366393

367394
assert_eq!(l.len(), 19);
368395
}

root-io/src/core/file_item.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use nom_supreme::ParserExt;
33

44
use crate::core::{checked_byte_count, Context, Source, TKeyHeader, wrap_parser};
55
use crate::core::compression::decompress;
6-
use crate::tree_reader::{ReadError, Tree, ttree};
6+
use crate::core::ReadError;
7+
use crate::tree_reader::{Tree, ttree};
78

89
/// Describes a single item within this file (e.g. a `Tree`)
910
#[derive(Debug)]
@@ -61,8 +62,10 @@ impl FileItem {
6162
let ctx = self.get_context().await?;
6263
let buf = ctx.s.as_slice();
6364

64-
let res = wrap_parser(
65-
length_value(checked_byte_count, ttree(&ctx)).all_consuming()
65+
let res = wrap_parser(length_value(checked_byte_count, ttree(&ctx))
66+
.complete()
67+
.all_consuming()
68+
.context("ttree wrapper")
6669
)(buf)?;
6770
Ok(res)
6871
}
@@ -73,15 +76,15 @@ mod tests {
7376
use std::path::Path;
7477

7578
use crate::core::RootFile;
79+
use crate::core::UnwrapPrint;
7680

7781
#[tokio::test]
7882
async fn open_simple() {
7983
let path = Path::new("./src/test_data/simple.root");
80-
let f = RootFile::new(path).await.expect("Failed to open file");
84+
let f = RootFile::new(path).await.unwrap_print();
8185
assert_eq!(f.items().len(), 1);
8286
assert_eq!(f.items()[0].tkey_hdr.obj_name, "tree");
83-
// Only streamers; not rules
84-
assert_eq!(f.streamer_infos().await.unwrap().len(), 18);
87+
assert_eq!(f.streamer_infos().await.unwrap_print().len(), 18);
8588
}
8689

8790
// Skip this test on MacOs since the downloaded file is not working on Travis
@@ -91,13 +94,11 @@ mod tests {
9194
use alice_open_data;
9295
let path = alice_open_data::test_file().unwrap();
9396

94-
let f = RootFile::new(path.as_path())
95-
.await
96-
.expect("Failed to open file");
97+
let f = RootFile::new(path.as_path()).await.unwrap_print();
9798

9899
assert_eq!(f.items().len(), 2);
99100
assert_eq!(f.items()[0].tkey_hdr.obj_name, "esdTree");
100101
assert_eq!(f.items()[1].tkey_hdr.obj_name, "HLTesdTree");
101-
assert_eq!(f.streamer_infos().await.unwrap().len(), 87);
102+
assert_eq!(f.streamer_infos().await.unwrap_print().len(), 87);
102103
}
103104
}

0 commit comments

Comments
 (0)