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 pub fn rest(&self) -> &'a [u8] {
22 self.buffer
23 }
24}
25
26impl<'a> HasRestLen for TypesIter<'a> {
27 fn rest_len(&self) -> usize {
28 self.buffer.len()
29 }
30}
31
32impl<'a> Iterator for TypesIter<'a> {
33 type Item = TypeRecord<'a>;
34
35 fn next(&mut self) -> Option<TypeRecord<'a>> {
41 if self.buffer.is_empty() {
42 return None;
43 }
44
45 let mut p = Parser::new(self.buffer);
46
47 let record_len = p.u16().ok()?;
48 if record_len < 2 {
49 return None;
51 }
52
53 let type_kind = p.u16().ok()?;
54
55 let Ok(record_data) = p.bytes(record_len as usize - 2) else {
56 return None;
58 };
59
60 self.buffer = p.into_rest();
61
62 Some(TypeRecord {
63 data: record_data,
64 kind: Leaf(type_kind),
65 })
66 }
67}
68
69#[derive(Clone)]
71pub struct TypeRecord<'a> {
72 pub kind: Leaf,
74 pub data: &'a [u8],
76}
77
78impl<'a> TypeRecord<'a> {
79 pub fn parse(&self) -> Result<crate::types::TypeData<'a>, ParserError> {
81 crate::types::TypeData::parse(self.kind, &mut Parser::new(self.data))
82 }
83}
84
85pub fn build_types_starts(num_records_expected: usize, type_records: &[u8]) -> Vec<u32> {
87 let mut starts: Vec<u32> = Vec::with_capacity(num_records_expected + 1);
88 let mut iter = TypesIter::new(type_records).with_ranges();
89
90 loop {
94 let pos = iter.pos();
95 starts.push(pos as u32);
96
97 if iter.next().is_none() {
98 break;
99 }
100 }
101
102 starts.shrink_to_fit();
103 starts
104}
105
106pub struct TypesIterMut<'a> {
108 buffer: &'a mut [u8],
109}
110
111impl<'a> TypesIterMut<'a> {
112 pub fn new(buffer: &'a mut [u8]) -> Self {
114 Self { buffer }
115 }
116}
117
118impl<'a> HasRestLen for TypesIterMut<'a> {
119 fn rest_len(&self) -> usize {
120 self.buffer.len()
121 }
122}
123
124impl<'a> Iterator for TypesIterMut<'a> {
125 type Item = TypeRecordMut<'a>;
126
127 fn next(&mut self) -> Option<TypeRecordMut<'a>> {
128 if self.buffer.is_empty() {
129 return None;
130 }
131
132 let mut parser = ParserMut::new(take(&mut self.buffer));
133
134 let record_len = parser.u16().ok()?;
135 if record_len < 2 {
136 return None;
138 }
139
140 let type_kind = parser.u16().ok()?;
141
142 let Ok(record_data) = parser.bytes_mut(record_len as usize - 2) else {
143 return None;
145 };
146
147 self.buffer = parser.into_rest();
148
149 Some(TypeRecordMut {
150 data: record_data,
151 kind: Leaf(type_kind),
152 })
153 }
154}
155
156pub struct TypeRecordMut<'a> {
159 pub kind: Leaf,
161 pub data: &'a mut [u8],
163}