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;
35const 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#[derive(Default)]
141enum RootFileInner {
142 Reader(RootFileReader),
143 Writer(RootFileWriter),
144 #[default]
145 None,
146}
147
148#[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 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 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 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 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 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 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 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 }
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 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!(";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 }
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 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 }
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}