1use super::*;
2
3pub struct Blob {
4 file: &'static File,
5 slice: &'static [u8],
6}
7
8impl std::ops::Deref for Blob {
9 type Target = [u8];
10
11 fn deref(&self) -> &[u8] {
12 self.slice
13 }
14}
15
16impl Blob {
17 pub fn new(file: &'static File, slice: &'static [u8]) -> Self {
18 Self { file, slice }
19 }
20
21 pub fn reader(&self) -> &'static Reader {
22 self.file.reader()
23 }
24
25 fn peek(&self) -> (usize, usize) {
26 if self[0] & 0x80 == 0 {
27 (self[0] as usize, 1)
28 } else if self[0] & 0xC0 == 0x80 {
29 ((((self[0] & 0x3F) as usize) << 8) | self[1] as usize, 2)
30 } else {
31 (
32 (((self[0] & 0x1F) as usize) << 24)
33 | ((self[1] as usize) << 16)
34 | ((self[2] as usize) << 8)
35 | self[3] as usize,
36 4,
37 )
38 }
39 }
40
41 pub fn decode<D: Decode>(&mut self) -> D {
42 D::decode(self.file, self.read_usize())
43 }
44
45 pub fn try_read(&mut self, expected: usize) -> bool {
46 let (value, offset) = self.peek();
47 if value == expected {
48 self.offset(offset);
49 true
50 } else {
51 false
52 }
53 }
54
55 pub fn read_modifiers(&mut self) -> Vec<TypeDefOrRef> {
56 let mut mods = vec![];
57 loop {
58 let (value, offset) = self.peek();
59 if value != ELEMENT_TYPE_CMOD_OPT as usize && value != ELEMENT_TYPE_CMOD_REQD as usize {
60 break;
61 } else {
62 self.offset(offset);
63 mods.push(TypeDefOrRef::decode(self.file, self.read_usize()))
64 }
65 }
66 mods
67 }
68
69 pub fn read_usize(&mut self) -> usize {
70 let (value, offset) = self.peek();
71 self.offset(offset);
72 value
73 }
74
75 pub fn read_str(&mut self) -> &'static str {
76 let len = self.read_usize();
77 let value = unsafe { std::str::from_utf8_unchecked(&self.slice[..len]) };
78 self.offset(len);
79 value
80 }
81
82 pub fn read_utf16(self) -> String {
83 let slice = self.slice;
84 if slice.as_ptr().align_offset(std::mem::align_of::<u16>()) > 0 {
85 let slice = slice
86 .chunks_exact(2)
87 .take(slice.len() / 2)
88 .map(|chunk| u16::from_le_bytes(chunk.try_into().unwrap()))
89 .collect::<Vec<u16>>();
90 String::from_utf16_lossy(&slice)
91 } else {
92 let slice = unsafe {
93 std::slice::from_raw_parts(slice.as_ptr() as *const u16, slice.len() / 2)
94 };
95 String::from_utf16_lossy(slice)
96 }
97 }
98
99 pub fn read_bool(&mut self) -> bool {
100 // A bool is specified as "a single byte with value 0 (false) or 1 (true)".
101 match self.read_u8() {
102 0 => false,
103 1 => true,
104 _ => panic!(),
105 }
106 }
107
108 pub fn read_i8(&mut self) -> i8 {
109 let value = i8::from_le_bytes(self[..1].try_into().unwrap());
110 self.offset(1);
111 value
112 }
113
114 pub fn read_u8(&mut self) -> u8 {
115 let value = u8::from_le_bytes(self[..1].try_into().unwrap());
116 self.offset(1);
117 value
118 }
119
120 pub fn read_i16(&mut self) -> i16 {
121 let value = i16::from_le_bytes(self[..2].try_into().unwrap());
122 self.offset(2);
123 value
124 }
125
126 pub fn read_u16(&mut self) -> u16 {
127 let value = u16::from_le_bytes(self[..2].try_into().unwrap());
128 self.offset(2);
129 value
130 }
131
132 pub fn read_i32(&mut self) -> i32 {
133 let value = i32::from_le_bytes(self[..4].try_into().unwrap());
134 self.offset(4);
135 value
136 }
137
138 pub fn read_u32(&mut self) -> u32 {
139 let value = u32::from_le_bytes(self[..4].try_into().unwrap());
140 self.offset(4);
141 value
142 }
143
144 pub fn read_i64(&mut self) -> i64 {
145 let value = i64::from_le_bytes(self[..8].try_into().unwrap());
146 self.offset(8);
147 value
148 }
149
150 pub fn read_u64(&mut self) -> u64 {
151 let value = u64::from_le_bytes(self[..8].try_into().unwrap());
152 self.offset(8);
153 value
154 }
155
156 pub fn read_f32(&mut self) -> f32 {
157 let value = f32::from_le_bytes(self[..4].try_into().unwrap());
158 self.offset(4);
159 value
160 }
161
162 pub fn read_f64(&mut self) -> f64 {
163 let value = f64::from_le_bytes(self[..8].try_into().unwrap());
164 self.offset(8);
165 value
166 }
167
168 pub fn read_integer(&mut self, ty: Type) -> Value {
169 match ty {
170 Type::I8 => Value::I8(self.read_i8()),
171 Type::U8 => Value::U8(self.read_u8()),
172 Type::I16 => Value::I16(self.read_i16()),
173 Type::U16 => Value::U16(self.read_u16()),
174 Type::I32 => Value::I32(self.read_i32()),
175 Type::U32 => Value::U32(self.read_u32()),
176 Type::I64 => Value::I64(self.read_i64()),
177 Type::U64 => Value::U64(self.read_u64()),
178 _ => panic!(),
179 }
180 }
181
182 fn offset(&mut self, offset: usize) {
183 self.slice = &self.slice[offset..];
184 }
185}
186