1use alloc::borrow::ToOwned;
2use alloc::string::String;
3use alloc::vec;
4use core::cell::RefCell;
5use zerocopy::IntoBytes;
6
7use crate::{
8 ISO9660, ISODirectoryEntry, ISODirectoryRecord, ISOInternalFlags, PRIMARY_VOLUME_DESCRIPTOR_POSITION, Read, descriptors::{Descriptor, DescriptorType}
9};
10
11pub struct DirectoryIter<'iso> {
12 iso: RefCell<&'iso mut ISO9660>,
13 byte_offset: RefCell<usize>,
14}
15
16impl<'iso> DirectoryIter<'iso> {
17 pub fn new(iso: &'iso mut ISO9660, byte_offset: usize) -> Self {
18 Self {
19 iso: iso.into(),
20 byte_offset: byte_offset.into(),
21 }
22 }
23}
24
25impl Iterator for &DirectoryIter<'_> {
26 type Item = ISODirectoryEntry;
27
28 fn next(&mut self) -> Option<Self::Item> {
29 let mut record = ISODirectoryRecord::default();
30 let ptr = record.as_mut_bytes();
31
32 self.iso
33 .borrow_mut()
34 .device
35 .read(*self.byte_offset.borrow() as _, ptr);
36
37 if record.length == 0 {
38 return None;
39 }
40
41 let main_part_size = size_of::<ISODirectoryRecord>();
42
43 let name: String;
44
45 if self.iso.borrow().flags.contains(ISOInternalFlags::HasJoliet) {
46 name = self.iso.borrow_mut().read_joliet_name(
47 *self.byte_offset.borrow() + main_part_size,
48 record.file_identifier_length as _
49 ).expect("Expected a valid UCS-2 name");
50 } else {
51 let main_part_size = main_part_size + record.file_identifier_length as usize;
52 let extension_size = record.length as usize - main_part_size;
53
54 let rr_name = self.iso.borrow_mut().read_rock_ridge_name(
57 *self.byte_offset.borrow(),
58 main_part_size,
59 extension_size,
60 );
61
62 name = if let Some(n) = rr_name {
63 n
64 } else {
65 let size = record.file_identifier_length as usize;
66
67 let mut result = vec![0; size];
68
69 self.iso.borrow_mut().device.read(
70 *self.byte_offset.borrow() + size_of::<ISODirectoryRecord>(),
71 &mut result,
72 );
73
74 let final_name = if result[0] == 0 {
75 "."
76 } else if result[0] == 1 {
77 ".."
78 } else {
79 str::from_utf8(&result).unwrap()
80 };
81
82 final_name.to_owned()
83 };
84 }
85
86 *self.byte_offset.borrow_mut() += record.length as usize;
87
88 Some(ISODirectoryEntry { record, name })
89 }
90}
91
92pub struct DescriptorIterator<'dev> {
93 device: &'dev mut dyn Read,
94 position: usize,
95}
96
97impl<'a> DescriptorIterator<'a> {
98 pub fn new(dev: &'a mut dyn Read) -> Self {
99 Self {
100 device: dev,
101 position: PRIMARY_VOLUME_DESCRIPTOR_POSITION,
102 }
103 }
104}
105
106impl<'a> Iterator for DescriptorIterator<'a> {
107 type Item = Descriptor;
108
109 fn next(&mut self) -> Option<Self::Item> {
110 let mut buffer = [0u8; 2048];
111
112 self.device.read(self.position, &mut buffer)?;
113
114 loop {
115 let Ok(descriptor): Result<Self::Item, _> = zerocopy::try_transmute!(buffer) else {
116 self.position += core::mem::size_of::<Descriptor>();
118 continue;
119 };
120
121 break if descriptor.desc_type == DescriptorType::Terminator {
122 None
123 } else {
124 self.position += core::mem::size_of::<Descriptor>();
125 Some(descriptor)
126 };
127 }
128 }
129}