ms_codeview/types/
iter.rs1use super::Leaf;
4use crate::parser::{Parser, ParserError, ParserMut};
5use crate::utils::iter::{HasRestLen, IteratorWithRangesExt};
6use std::mem::take;
7
8#[derive(Clone)]
10pub struct TypesIter<'a> {
11 buffer: &'a [u8],
12}
13
14impl<'a> TypesIter<'a> {
15 pub fn new(buffer: &'a [u8]) -> Self {
17 Self { buffer }
18 }
19}
20
21impl<'a> HasRestLen for TypesIter<'a> {
22 fn rest_len(&self) -> usize {
23 self.buffer.len()
24 }
25}
26
27impl<'a> Iterator for TypesIter<'a> {
28 type Item = TypeRecord<'a>;
29
30 fn next(&mut self) -> Option<TypeRecord<'a>> {
31 if self.buffer.is_empty() {
32 return None;
33 }
34
35 let mut p = Parser::new(self.buffer);
36
37 let record_len = p.u16().ok()?;
38 if record_len < 2 {
39 return None;
41 }
42
43 let type_kind = p.u16().ok()?;
44
45 let Ok(record_data) = p.bytes(record_len as usize - 2) else {
46 return None;
48 };
49
50 self.buffer = p.into_rest();
51
52 Some(TypeRecord {
53 data: record_data,
54 kind: Leaf(type_kind),
55 })
56 }
57}
58
59#[derive(Clone)]
61pub struct TypeRecord<'a> {
62 pub kind: Leaf,
64 pub data: &'a [u8],
66}
67
68impl<'a> TypeRecord<'a> {
69 pub fn parse(&self) -> Result<crate::types::TypeData<'a>, ParserError> {
71 crate::types::TypeData::parse(self.kind, &mut Parser::new(self.data))
72 }
73}
74
75pub fn build_types_starts(num_records_expected: usize, type_records: &[u8]) -> Vec<u32> {
77 let mut starts: Vec<u32> = Vec::with_capacity(num_records_expected + 1);
78 let mut iter = TypesIter::new(type_records).with_ranges();
79
80 loop {
84 let pos = iter.pos();
85 starts.push(pos as u32);
86
87 if iter.next().is_none() {
88 break;
89 }
90 }
91
92 starts.shrink_to_fit();
93 starts
94}
95
96pub struct TypesIterMut<'a> {
98 buffer: &'a mut [u8],
99}
100
101impl<'a> TypesIterMut<'a> {
102 pub fn new(buffer: &'a mut [u8]) -> Self {
104 Self { buffer }
105 }
106}
107
108impl<'a> HasRestLen for TypesIterMut<'a> {
109 fn rest_len(&self) -> usize {
110 self.buffer.len()
111 }
112}
113
114impl<'a> Iterator for TypesIterMut<'a> {
115 type Item = TypeRecordMut<'a>;
116
117 fn next(&mut self) -> Option<TypeRecordMut<'a>> {
118 if self.buffer.is_empty() {
119 return None;
120 }
121
122 let mut parser = ParserMut::new(take(&mut self.buffer));
123
124 let record_len = parser.u16().ok()?;
125 if record_len < 2 {
126 return None;
128 }
129
130 let type_kind = parser.u16().ok()?;
131
132 let Ok(record_data) = parser.bytes_mut(record_len as usize - 2) else {
133 return None;
135 };
136
137 self.buffer = parser.into_rest();
138
139 Some(TypeRecordMut {
140 data: record_data,
141 kind: Leaf(type_kind),
142 })
143 }
144}
145
146pub struct TypeRecordMut<'a> {
149 pub kind: Leaf,
151 pub data: &'a mut [u8],
153}