oxyroot/riofs/
file.rs

1use crate::rdict::streamers::db::streamer_info;
2use crate::riofs::consts;
3use crate::rtree::tree::reader::ReaderTree;
4use crate::utils::is_cxx_builtin;
5use std::fmt::{Debug, Display, Formatter};
6use std::fs::File;
7use std::io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write};
8use std::path::{Path, PathBuf};
9use std::ptr::addr_of;
10use std::rc::Rc;
11
12use crate::rbytes::rbuffer::RBuffer;
13use crate::rbytes::wbuffer::WBuffer;
14use crate::rbytes::{Marshaler, StreamerInfoContext};
15use crate::rcont::list::{ReaderList, WriterList};
16use crate::rdict::streamers::db::streamer_info_from;
17use crate::rdict::{Streamer, StreamerInfo, Visitor};
18use crate::riofs::blocks::{FreeList, FreeSegments};
19use crate::riofs::consts::kStartBigFile;
20use crate::riofs::dir::TDirectoryFile;
21use crate::riofs::key::Key;
22use crate::riofs::{Error, Result};
23use crate::rmeta::ESTLType;
24use crate::root::traits::Named;
25use crate::rtypes::factory::FactoryItemWrite;
26use crate::rtypes::FactoryItemRead;
27use crate::utils::is_core_type;
28use crate::{rvers, Object};
29use log::{debug, trace};
30use regex::Regex;
31use uuid::Uuid;
32
33const HEADER_LEN: u64 = 64;
34const HEADER_EXTRA_LEN: u64 = 12;
35// 64: small file + extra space for big file
36const ROOT_MAGIC: &str = "root";
37
38#[derive(Default, Debug)]
39struct RootFileHeader {
40    version: i32,
41    begin: i64,
42    end: i64,
43    seek_free: i64,
44    n_bytes_free: i32,
45    n_free: i32,
46    n_bytes_name: i32,
47    units: u8,
48    compression: i32,
49    seek_info: i64,
50    n_bytes_info: i32,
51    uuid: Uuid,
52}
53
54impl RootFileHeader {
55    pub fn compression(&self) -> i32 {
56        self.compression
57    }
58}
59
60#[derive(Default, Debug)]
61pub(crate) struct RootFileReader {
62    path: PathBuf,
63    reader: Option<BufReader<File>>,
64}
65
66impl Display for RootFileReader {
67    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68        f.write_str(self.path.to_str().unwrap())?;
69        Ok(())
70    }
71}
72
73impl RootFileReader {
74    pub(crate) fn new<P>(path: P) -> Result<Self>
75    where
76        P: AsRef<Path>,
77    {
78        let f = File::open(path.as_ref())?;
79        let buf_reader = BufReader::new(f);
80        let reader = Self {
81            path: path.as_ref().to_path_buf(),
82            reader: Some(buf_reader),
83        };
84        Ok(reader)
85    }
86
87    pub(crate) fn read_at(&mut self, start: u64, len: u64) -> Result<Vec<u8>> {
88        self.reader
89            .as_mut()
90            .expect("ERROR")
91            .seek(SeekFrom::Start(start))?;
92        let mut buf = vec![0; len as usize];
93        self.reader.as_mut().expect("ERROR").read_exact(&mut buf)?;
94        Ok(buf)
95    }
96}
97
98impl Clone for RootFileReader {
99    fn clone(&self) -> Self {
100        RootFileReader::new(&self.path).unwrap()
101    }
102}
103
104#[derive(Default, Debug)]
105pub(crate) struct RootFileWriter {
106    path: PathBuf,
107    writer: Option<BufWriter<File>>,
108}
109
110impl RootFileWriter {
111    pub(crate) fn new<P>(path: P) -> Result<Self>
112    where
113        P: AsRef<Path>,
114    {
115        let f = File::create(path.as_ref())?;
116        let buf_writer = BufWriter::new(f);
117        let reader = Self {
118            path: path.as_ref().to_path_buf(),
119            writer: Some(buf_writer),
120        };
121        Ok(reader)
122    }
123
124    pub(crate) fn write_at(&mut self, buf: &[u8], start: u64) -> Result<()> {
125        self.writer
126            .as_mut()
127            .expect("ERROR")
128            .seek(SeekFrom::Start(start))?;
129        self.writer.as_mut().expect("ERROR").write_all(buf)?;
130        Ok(())
131    }
132}
133
134// impl Clone for RootFileWriter {
135//     fn clone(&self) -> Self {
136//         RootFileWriter::new(&self.path).unwrap()
137//     }
138// }
139
140#[derive(Default)]
141enum RootFileInner {
142    Reader(RootFileReader),
143    Writer(RootFileWriter),
144    #[default]
145    None,
146}
147
148/// Rust equivalent of [`TFile`](https://root.cern/doc/master/classTFile.html).
149///
150/// Can only read for now. Aims to be constructed with [open](crate::RootFile::open) method.
151#[derive(Default)]
152pub struct RootFile {
153    inner: RootFileInner,
154    header: RootFileHeader,
155    spans: FreeList,
156    sinfos: RootFileStreamerInfoContext,
157    dir: TDirectoryFile,
158    id: String,
159}
160
161impl RootFile {
162    pub(crate) fn n_bytes_name(&self) -> i32 {
163        self.header.n_bytes_name
164    }
165
166    pub(crate) fn version(&self) -> i32 {
167        self.header.version
168    }
169
170    pub(crate) fn begin(&self) -> i64 {
171        self.header.begin
172    }
173
174    pub(crate) fn end(&self) -> i64 {
175        self.header.end
176    }
177
178    /// Open file, use [std::io::BufReader] for reading, so it can only handle local files for now.
179    pub fn open<P>(path: P) -> Result<Self>
180    where
181        P: AsRef<Path>,
182    {
183        let reader = RootFileReader::new(path)?;
184
185        let inner = RootFileInner::Reader(reader);
186
187        let mut f = RootFile {
188            inner,
189            ..Default::default()
190        };
191
192        f.read_header()?;
193
194        Ok(f)
195    }
196
197    pub fn create<P>(path: P) -> Result<Self>
198    where
199        P: AsRef<Path>,
200    {
201        let s = path.as_ref().to_str().unwrap().to_string();
202        let writer = RootFileWriter::new(path)?;
203
204        let inner = RootFileInner::Writer(writer);
205
206        let header = RootFileHeader {
207            version: rvers::ROOT,
208            begin: consts::kBEGIN,
209            end: consts::kBEGIN,
210            units: 4,
211            compression: 1,
212            ..Default::default()
213        };
214
215        let mut spans = FreeList::default();
216        spans.append(FreeSegments::new(header.begin, consts::kStartBigFile));
217
218        let dir = TDirectoryFile::new(s.clone());
219
220        let mut f = RootFile {
221            inner,
222            header,
223            spans,
224            dir,
225            id: s.clone(),
226            ..Default::default()
227        };
228
229        let name_len = f.dir.dir().named().size_of();
230        trace!(";RootFile.create.f.dir.dir.named.Sizeof:{}", name_len);
231        trace!(
232            ";RootFile.create.f.dir.dir.named.name:{}",
233            f.dir.dir().named().name
234        );
235        trace!(
236            ";RootFile.create.f.dir.dir.named.title:{}",
237            f.dir.dir().named().title
238        );
239        trace!(";RootFile.create.f.version:{}", f.version());
240        trace!(
241            ";RootFile.create.f.dir.recordSize:{}",
242            TDirectoryFile::record_size(f.version())
243        );
244
245        let obj_len = name_len + TDirectoryFile::record_size(f.version()) as i32;
246        trace!(";RootFile.create.f.objlen:{}", obj_len);
247
248        let mut key = Key::new(
249            f.dir.dir().named().name.clone(),
250            f.dir.dir().named().title.clone(),
251            "TFile".to_string(),
252            obj_len,
253            &mut f,
254        )?;
255
256        f.header.n_bytes_name = key.key_len() + name_len;
257        trace!(
258            ";RootFile.create.f.header.n_bytes_name:{}",
259            f.header.n_bytes_name
260        );
261        f.dir.n_bytes_name = key.key_len() + name_len;
262
263        f.dir.seek_dir = key.seek_key();
264        trace!(";RootFile.create.f.dir.seek_dir:{}", f.dir.seek_dir);
265
266        f.write_header()?;
267
268        let mut buf = WBuffer::new(0);
269        buf.write_string(&f.id)?;
270        buf.write_string(f.title())?;
271
272        f.dir().marshal(&mut buf)?;
273
274        let buf = buf.buffer();
275        trace!(";RootFile.create.buf_for_key.len:{:?}", buf.len());
276
277        key.set_buffer(buf, false);
278
279        key.write_to_file(f.writer()?)?;
280
281        Ok(f)
282    }
283
284    pub(crate) fn put<T>(&mut self, name: &str, obj: &T) -> Result<()>
285    where
286        T: FactoryItemWrite,
287    {
288        trace!(";TDirectoryFile.put.name:{:?}", name);
289        if name.contains('/') {
290            return Err(Error::NameContainsSlash(name.to_string()));
291        }
292
293        let name = if name.is_empty() { obj.name() } else { name };
294        let title = obj.title();
295
296        trace!(";TDirectoryFile.put.name:{:?}", name);
297        trace!(";TDirectoryFile.put.title:{:?}", title);
298
299        let mut cycle = 0;
300
301        for key in self.dir().keys().iter() {
302            if key.name() != name {
303                continue;
304            }
305            if key.class_name() != obj.class() {
306                return Err(Error::KeyClassMismatch {
307                    key: key.name().to_string(),
308                    key_class: key.class_name().to_string(),
309                    obj_class: obj.class().to_string(),
310                });
311            }
312
313            if key.cycle() > cycle {
314                cycle = key.cycle();
315            }
316        }
317
318        cycle += 1;
319        let typename = obj.class();
320        trace!(";TDirectoryFile.put.typename:{:?}", typename);
321        trace!(
322            ";TDirectoryFile.put.is_core_type:{:?}",
323            is_core_type(typename)
324        );
325
326        if !is_core_type(typename) {
327            let _cxx = typename;
328            let streamer = streamer_info_from(obj, &mut self.dir)?;
329            self.add_streamer_info(streamer);
330        }
331
332        // trace!(";TDirectoryFile.put.file.sinfos:{:?}", self.sinfos);
333
334        let mut key = Key::new_from_object(name, title, obj.class(), obj, self)?;
335        key.set_cycle(cycle as i16);
336        key.write_to_file(self.writer()?)?;
337        self.dir.keys.push(key);
338        Ok(())
339    }
340
341    pub(crate) fn add_streamer_info(&mut self, si: StreamerInfo) {
342        if self.sinfos.list().iter().any(|s| s.name() == si.name()) {
343            return;
344        }
345
346        self.sinfos.push(si);
347        trace!(
348            ";TDirectoryFile.put.file.sinfos.len:{:?}",
349            self.sinfos.list.len()
350        );
351    }
352
353    pub fn close(&mut self) -> Result<()> {
354        let mut dir = self.dir().clone();
355        dir.close(self)?;
356        let _ = std::mem::replace(&mut self.dir, dir);
357        self.write_streamer_info()?;
358        self.write_free_segments()?;
359        self.write_header()?;
360
361        Ok(())
362    }
363
364    fn reader(&self) -> Result<&RootFileReader> {
365        match &self.inner {
366            RootFileInner::Reader(r) => Ok(r),
367            RootFileInner::Writer(_) => Err(Error::FileIsOpenedWriteOnly),
368            _ => Err(Error::FileIsNotOpened),
369        }
370    }
371
372    pub(crate) fn writer(&mut self) -> Result<&mut RootFileWriter> {
373        match &mut self.inner {
374            RootFileInner::Writer(w) => Ok(w),
375            RootFileInner::Reader(_) => Err(Error::FileIsOpenedReadOnly),
376            _ => Err(Error::FileIsNotOpened),
377        }
378    }
379
380    pub(crate) fn read_at(&self, start: u64, len: u64) -> Result<Vec<u8>> {
381        let mut reader = self.reader()?.clone();
382        reader.read_at(start, len)
383    }
384
385    pub(crate) fn write_at(&mut self, buf: &[u8], start: u64) -> Result<()> {
386        let writer = self.writer()?;
387        writer.write_at(buf, start)
388    }
389
390    fn read_header(&mut self) -> Result<()> {
391        trace!("start to read header");
392        let buf = self.read_at(0, HEADER_LEN + HEADER_EXTRA_LEN)?;
393        let mut r = RBuffer::new(&buf, 0);
394        // let mut magic: [u8; 4] = [0; 4];
395        let magic = r.read_array_u8(4)?;
396
397        trace!("magic = {:?}", magic);
398
399        assert_eq!(magic, ROOT_MAGIC.as_bytes());
400
401        let version = r.read_i32()?;
402        trace!("version = {}", version);
403
404        self.header.begin = r.read_i32()? as i64;
405        let is_64 = version > 1000000;
406
407        self.header.end = if is_64 {
408            r.read_i64()?
409        } else {
410            r.read_i32()? as i64
411        };
412
413        self.header.seek_free = if is_64 {
414            r.read_i64()?
415        } else {
416            r.read_i32()? as i64
417        };
418
419        self.header.n_bytes_free = r.read_i32()?;
420        self.header.n_free = r.read_i32()?;
421        self.header.n_bytes_name = r.read_i32()?;
422        self.header.units = r.read_u8()?;
423        self.header.compression = r.read_i32()?;
424
425        self.header.seek_info = if is_64 {
426            r.read_i64()?
427        } else {
428            r.read_i32()? as i64
429        };
430
431        self.header.n_bytes_info = r.read_i32()?;
432
433        self.header.version = version % 1000000;
434        trace!("version = {}", version);
435
436        let _ = r.read_u16()?;
437        // let mut uuid: [u8; 16] = [0; 16];
438        let uuid = r.read_array_u8(16)?;
439        let uuid = <&[u8; 16]>::try_from(uuid)?;
440        self.header.uuid = Uuid::from_bytes(*uuid);
441
442        trace!("uuid = {}", self.header.uuid);
443
444        let mut dir = TDirectoryFile::read_dir_info(self)?;
445
446        if self.header.seek_free > 0 {
447            self.read_free_segments()?;
448        }
449
450        if self.header.seek_info > 0 {
451            self.read_streamer_info()?;
452        }
453
454        dir.read_keys(self)?;
455
456        self.dir = dir;
457
458        // f.version %= 1000000
459
460        Ok(())
461    }
462
463    pub(crate) fn set_end(&mut self, pos: i64) -> Result<()> {
464        trace!(";RootFile.set_end.pos:{:?}", pos);
465        self.header.end = pos;
466        if self.spans.len() == 0 {
467            panic!("self.spans.len()")
468        }
469        let blk = self.spans.vec().last_mut().unwrap();
470        if blk.last != kStartBigFile {
471            panic!("blk.last")
472        }
473        blk.first = pos;
474        Ok(())
475    }
476
477    fn write_header(&mut self) -> Result<()> {
478        self.header.n_free = self.spans.len() as i32;
479
480        let mut w = WBuffer::new(self.begin() as u32);
481
482        let mut version = self.version();
483        if self.is_big_file()
484            || self.header.seek_free > kStartBigFile
485            || self.header.seek_info > kStartBigFile
486        {
487            if version < 1000000 {
488                version += 1000000;
489            }
490            self.header.units = 8
491        }
492
493        w.write_array_u8(ROOT_MAGIC.as_bytes())?;
494        w.write_i32(version)?;
495        w.write_i32(self.header.begin as i32)?;
496
497        if version < 1000000 {
498            w.write_i32(self.header.end as i32)?;
499            w.write_i32(self.header.seek_free as i32)?;
500            w.write_i32(self.header.n_bytes_free)?;
501            w.write_i32(self.header.n_free)?;
502            w.write_i32(self.header.n_bytes_name)?;
503            w.write_u8(self.header.units)?;
504            w.write_i32(self.header.compression)?;
505            w.write_i32(self.header.seek_info as i32)?;
506            w.write_i32(self.header.n_bytes_info)?;
507        } else {
508            w.write_i64(self.header.end)?;
509            w.write_i64(self.header.seek_free)?;
510            w.write_i32(self.header.n_bytes_free)?;
511            w.write_i32(self.header.n_free)?;
512            w.write_i32(self.header.n_bytes_name)?;
513            w.write_u8(self.header.units)?;
514            w.write_i32(self.header.compression)?;
515            w.write_i64(self.header.seek_info)?;
516            w.write_i32(self.header.n_bytes_info)?;
517        }
518
519        // TODO: marshal uuid version
520        w.write_i16(rvers::UUID)?;
521        w.write_array_u8(self.header.uuid.as_ref())?;
522
523        let buf = vec![0; self.header.begin as usize];
524        self.write_at(&buf, 0)?;
525
526        let buf = w.buffer();
527        trace!(";RootFile.write_header.buf.len:{:?}", buf.len());
528        self.write_at(&buf, 0)?;
529
530        //
531
532        Ok(())
533    }
534
535    fn read_free_segments(&mut self) -> Result<()> {
536        trace!("read_free_segments");
537        let buf = self.read_at(
538            self.header.seek_free as u64,
539            self.header.n_bytes_free as u64,
540        )?;
541        if buf.len() != self.header.n_bytes_free as usize {
542            return Err(Error::CantReadAmountOfBytesFromFile {
543                requested: self.header.n_bytes_free as usize,
544                read: buf.len(),
545            });
546        }
547
548        let mut r = RBuffer::new(&buf, 0);
549        let key = r.read_object_into::<Key>()?;
550        debug!("key = {:?}", key);
551
552        let mut reader = self.reader()?.clone();
553
554        let buf = key.bytes(&mut reader, None)?;
555        trace!("buf = {:?}", buf);
556
557        let mut rbuf = RBuffer::new(&buf, 0);
558        trace!("rbuf len = {}", rbuf.len());
559
560        while !rbuf.is_empty() {
561            let span = rbuf.read_object_into::<FreeSegments>()?;
562
563            self.spans.append(span);
564        }
565
566        Ok(())
567    }
568
569    fn read_streamer_info(&mut self) -> Result<()> {
570        if self.header.seek_info <= 0 || self.header.seek_info >= self.end() {
571            return Err(Error::InvalidPointerToStreamerInfo {
572                seek: self.header.seek_info,
573                min_allowed: 0,
574                max_allowed: self.end(),
575            });
576        }
577
578        let buf = self.read_at(
579            self.header.seek_info as u64,
580            self.header.n_bytes_info as u64,
581        )?;
582
583        if buf.len() != self.header.n_bytes_info as usize {
584            return Err(Error::CantReadAmountOfBytesFromFile {
585                requested: self.header.n_bytes_info as usize,
586                read: buf.len(),
587            });
588        }
589
590        let si_key = RBuffer::new(&buf, 0).read_object_into::<Key>()?;
591        let mut reader = self.reader()?.clone();
592
593        let ogj = si_key.object(&mut reader, None)?.unwrap();
594
595        let mut objs: Box<ReaderList> = ogj.downcast::<ReaderList>().unwrap();
596
597        for i in (0..objs.len()).rev() {
598            let obj = objs.remove(i);
599
600            if obj.class() == "TStreamerInfo" {
601                let obj: Box<StreamerInfo> = obj.downcast::<StreamerInfo>().unwrap();
602                self.sinfos.push(*obj);
603            } else {
604                let mut list: Box<ReaderList> = obj.downcast::<ReaderList>().unwrap();
605                for j in (0..list.len()).rev() {
606                    let _jobj = list.remove(j);
607                    // let obj: Box<StreamerInfo> = jobj.downcast::<StreamerInfo>().unwrap();
608                    // trace!("\tobj.name = {}", obj.name());
609                }
610            }
611        }
612
613        Ok(())
614    }
615
616    fn write_streamer_info(&mut self) -> Result<()> {
617        trace!(
618            ";RootFile.write_streamer_info.f.sinfos.init.len:{}",
619            self.sinfos.list().len()
620        );
621
622        self.find_deep_streamer()?;
623
624        trace!(
625            ";RootFile.write_streamer_info.f.sinfos.after_find_deep_streamer.len:{}",
626            self.sinfos.list().len()
627        );
628
629        let mut sinfos = WriterList::new();
630        let binding = self.sinfos.list.clone();
631        for si in binding.as_ref() {
632            trace!(";RootFile.write_streamer_info.for_loop.add:{:?}", si.name());
633            sinfos.push(si, addr_of!(*si) as usize);
634        }
635
636        if self.header.seek_info != 0 {
637            unimplemented!("f.seek_info != 0")
638        }
639
640        trace!(
641            ";RootFile.write_streamer_info.sinfos.title:{}",
642            sinfos.title()
643        );
644        trace!(
645            ";RootFile.write_streamer_info.sinfos.class:{}",
646            sinfos.class()
647        );
648
649        let key = Key::new(
650            "StreamerInfo".to_string(),
651            sinfos.title().to_string(),
652            sinfos.class().to_string(),
653            0,
654            self,
655        )?;
656        let offset = key.key_len();
657        trace!(";RootFile.write_streamer_info.offset:{}", offset);
658
659        let mut buf = WBuffer::new(offset as u32);
660
661        sinfos.marshal(&mut buf)?;
662
663        trace!(
664            ";RootFile.write_streamer_info.buf.after_sinfos.len:{:?}",
665            buf.p().len()
666        );
667
668        let key = Key::new_from_buffer(
669            "StreamerInfo".to_string(),
670            sinfos.title().to_string(),
671            sinfos.class().to_string(),
672            1,
673            buf.buffer(),
674            self,
675        )?;
676
677        self.header.seek_info = key.seek_key();
678        self.header.n_bytes_info = key.n_bytes();
679
680        trace!(
681            ";RootFile.write_streamer_info.f.seek_info:{}",
682            self.header.seek_info
683        );
684        trace!(
685            ";RootFile.write_streamer_info.f.n_bytes_info:{}",
686            self.header.n_bytes_info
687        );
688
689        key.write_to_file(self.writer()?)?;
690
691        Ok(())
692    }
693
694    fn write_free_segments(&mut self) -> Result<()> {
695        trace!(";RootFile.write_free_segments.call:{}", true);
696        if self.header.seek_free != 0 {
697            unimplemented!("self.header.seek_free != 0")
698        }
699
700        let mut nbytes = 0;
701        for span in self.spans.vec() {
702            nbytes += span.size_of();
703        }
704        trace!(";RootFile.write_free_segments.nbytes:{}", nbytes);
705
706        let mut key = Key::new(
707            self.dir.dir().named().name.clone(),
708            self.dir.dir().named().title.clone(),
709            "TFile".to_string(),
710            nbytes,
711            self,
712        )?;
713
714        assert_ne!(key.seek_key(), 0);
715
716        if !self.is_big_file() && self.end() > kStartBigFile {
717            unimplemented!("!self.is_big_file() && self.end() > kStartBigFile")
718        }
719
720        let nbytes = key.obj_len();
721        let mut buf = WBuffer::new(0);
722
723        for span in self.spans.vec() {
724            span.marshal(&mut buf)?;
725        }
726
727        if buf.pos() != nbytes.into() {
728            unimplemented!("buf.pos() != nbytes as usize")
729        }
730
731        self.header.n_bytes_free = key.n_bytes();
732        self.header.seek_free = key.seek_key();
733        key.set_buffer(buf.buffer(), false);
734        key.write_to_file(self.writer()?)?;
735
736        Ok(())
737    }
738
739    fn find_deep_streamer(&mut self) -> Result<()> {
740        trace!(";Rootfile.find_deep_streamer.call:true");
741        trace!(
742            ";Rootfile.find_deep_streamer.f.sinfos.len:{}",
743            self.sinfos.list().len()
744        );
745
746        // let mut visited = Vec::new();
747        let mut v = Vec::new();
748
749        #[derive(Debug)]
750        struct DepsType {
751            name: String,
752            vers: i16,
753        }
754
755        for (i, si) in self.sinfos.list().iter().enumerate() {
756            trace!(
757                ";Rootfile.find_deep_streamer.for_loop.{i}.si.name:{:?}",
758                si.name()
759            );
760
761            let mut visitor = Visitor::new(|_depth, se| {
762                trace!(";Rootfile.find_deep_streamer.fnmut.se.name:{}", se.name());
763                let name = se.name().to_string();
764                match se {
765                    Streamer::String(o) => {
766                        let d = DepsType {
767                            name: o.element.ename.to_string(),
768                            vers: -1,
769                        };
770                        v.push(d)
771                    }
772                    Streamer::STLstring(o) => {
773                        let d = DepsType {
774                            name: o.streamer_stl.element.ename.to_string(),
775                            vers: -1,
776                        };
777                        v.push(d)
778                    }
779                    Streamer::BasicType(_) => {}
780                    Streamer::BasicPointer(_) => {}
781                    Streamer::Stl(stl) => {
782                        match &stl.vtype {
783                            ESTLType::STLvector => {
784                                let etn = se.item_type_name();
785                                let reg = Regex::new(r"vector<([A-Za-z_0123456789]+)>").unwrap();
786                                let cap = reg.captures(etn).unwrap();
787                                let etn = &cap[1];
788
789                                // trace!(";StreamerInfo.visit.se.etn:{} {}", etn, depth);
790                                trace!(";Rootfile.find_deep_streamer.fnmut.etn:{}", etn);
791
792                                let d = DepsType {
793                                    name: etn.to_string(),
794                                    vers: -1,
795                                };
796                                v.push(d)
797
798                                // itt.push(Box::new(empty::<StreamerInfo>()));
799                                // todo!("Streamer::Stl");
800                            }
801                            _ => {
802                                todo!("Streamer::Stl, vtype = {:?}", &stl.vtype);
803                            }
804                        }
805                    }
806                    Streamer::Base(o) => {
807                        let d = DepsType {
808                            name,
809                            vers: o.vbase() as i16,
810                        };
811
812                        v.push(d);
813                    }
814                    Streamer::Object(o) => {
815                        let d = DepsType {
816                            name: o.element.ename.to_string(),
817                            vers: -1,
818                        };
819                        v.push(d)
820                    }
821                    Streamer::ObjectAny(o) => {
822                        let d = DepsType {
823                            name: o.element.ename.to_string(),
824                            vers: -1,
825                        };
826                        v.push(d)
827                    }
828                    Streamer::ObjectPointer(o) => {
829                        let tname = o.element.ename.trim_end_matches('*').to_string();
830                        let d = DepsType {
831                            name: tname,
832                            vers: -1,
833                        };
834                        v.push(d)
835                    }
836                }
837            });
838            visitor.run(0, si)?;
839        }
840
841        trace!(";Rootfile.find_deep_streamer.v.len:{}", v.len());
842        v.iter().for_each(|d| {
843            trace!(
844                ";Rootfile.find_deep_streamer.v.{}.name:{:?} {}",
845                d.name,
846                d.name,
847                d.vers
848            );
849            trace!(
850                ";Rootfile.find_deep_streamer.v.{}.is_core_type:{:?}",
851                d.name,
852                is_core_type(&d.name),
853            );
854            trace!(
855                ";Rootfile.find_deep_streamer.v.{}.is_cxx_builtin:{:?}",
856                d.name,
857                is_cxx_builtin(&d.name),
858            );
859
860            if is_core_type(&d.name) || is_cxx_builtin(&d.name) {
861                return;
862            }
863
864            let si = streamer_info(&d.name, d.vers).unwrap();
865            self.add_streamer_info(si);
866        });
867
868        // self.sinfos.extend(v);
869        //
870        // self.sinfos.list().iter().for_each(|si| {
871        //     trace!(";Rootfile.find_deep_streamer.f.sinfos.name:{:?}", si.name());
872        // });
873
874        trace!(
875            ";Rootfile.find_deep_streamer.f.sinfos.len:{}",
876            self.sinfos.list().len()
877        );
878
879        Ok(())
880    }
881
882    fn get_object(&mut self, name: &str) -> Result<Box<dyn FactoryItemRead>> {
883        let mut reader = self.reader()?.clone();
884        self.dir.get_object(name, &mut reader, Some(&self.sinfos))
885
886        // let a = &(&*self).dir;
887        // let b = self.reader()?;
888        //
889        // a.get_object(name, b, Some(&self.sinfos))
890
891        // Ok(obj)
892    }
893
894    pub fn get_tree(&mut self, name: &str) -> Result<ReaderTree> {
895        let objet = self.get_object(name)?;
896        let mut objet: ReaderTree = *objet.downcast::<ReaderTree>().expect("");
897
898        objet.set_reader(Some(self.reader()?.clone()));
899        objet.set_streamer_info(self.sinfos.clone());
900        Ok(objet)
901    }
902
903    pub fn keys_name(&self) -> impl Iterator<Item = &str> {
904        self.dir.keys().iter().map(|e| e.name())
905    }
906
907    pub fn keys(&self) -> Vec<Key> {
908        self.dir.keys().clone()
909    }
910    pub fn dir(&self) -> &TDirectoryFile {
911        &self.dir
912    }
913    pub(crate) fn mut_dir(&mut self) -> &mut TDirectoryFile {
914        &mut self.dir
915    }
916
917    pub(crate) fn is_big_file(&self) -> bool {
918        self.end() > consts::kStartBigFile
919    }
920
921    fn title(&self) -> &str {
922        self.dir().dir().named().title()
923    }
924    pub fn compression(&self) -> i32 {
925        self.header.compression()
926    }
927}
928
929#[derive(Default, Clone, Debug)]
930pub(crate) struct RootFileStreamerInfoContext {
931    list: Rc<Vec<StreamerInfo>>,
932}
933
934impl RootFileStreamerInfoContext {
935    pub(crate) fn new() -> Self {
936        Self {
937            list: Rc::new(Vec::new()),
938        }
939    }
940
941    pub(crate) fn push(&mut self, info: StreamerInfo) {
942        let v = Rc::get_mut(&mut self.list).expect("Do not panic ! ");
943        v.push(info);
944    }
945
946    fn extend(&mut self, infos: Vec<StreamerInfo>) {
947        let v = Rc::get_mut(&mut self.list).expect("Do not panic ! ");
948        v.extend(infos);
949    }
950
951    pub(crate) fn list(&self) -> &Rc<Vec<StreamerInfo>> {
952        &self.list
953    }
954
955    pub(crate) fn get(&self, name: &str) -> Option<&StreamerInfo> {
956        self.list()
957            .iter()
958            .rev()
959            .find(|&streamer| streamer.name() == name)
960    }
961}
962
963impl StreamerInfoContext for RootFileStreamerInfoContext {
964    fn streamer_info(&self, name: &str, _version: i32) -> Option<&StreamerInfo> {
965        if self.list.len() == 0 {
966            return None;
967        }
968
969        for si in self.list.iter() {
970            if si.name() == name {
971                return Some(si);
972            }
973        }
974
975        if name.find('<').is_some() {
976            todo!()
977        }
978
979        None
980    }
981}