1 use super::*;
2 use std::convert::TryInto;
3 
4 pub struct Blob {
5     pub file: &'static File,
6     pub offset: usize,
7     pub size: usize,
8 }
9 
10 impl Blob {
bytes(&self) -> &'static [u8]11     fn bytes(&self) -> &'static [u8] {
12         &self.file.bytes[self.offset..]
13     }
14 
peek_unsigned(&self) -> (u32, usize)15     pub fn peek_unsigned(&self) -> (u32, usize) {
16         let bytes = self.bytes();
17 
18         if bytes[0] & 0x80 == 0 {
19             (bytes[0] as u32, 1)
20         } else if bytes[0] & 0xC0 == 0x80 {
21             ((((bytes[0] & 0x3F) as u32) << 8) | bytes[1] as u32, 2)
22         } else {
23             (
24                 (((bytes[0] & 0x1F) as u32) << 24)
25                     | (bytes[1] as u32) << 16
26                     | (bytes[2] as u32) << 8
27                     | bytes[3] as u32,
28                 4,
29             )
30         }
31     }
32 
read_unsigned(&mut self) -> u3233     pub fn read_unsigned(&mut self) -> u32 {
34         let (value, offset) = self.peek_unsigned();
35         self.offset += offset;
36         value
37     }
38 
read_expected(&mut self, expected: u32) -> bool39     pub fn read_expected(&mut self, expected: u32) -> bool {
40         let (value, offset) = self.peek_unsigned();
41         if value == expected {
42             self.offset += offset;
43             true
44         } else {
45             false
46         }
47     }
48 
read_modifiers(&mut self) -> Vec<TypeDefOrRef>49     pub fn read_modifiers(&mut self) -> Vec<TypeDefOrRef> {
50         let mut mods = vec![];
51 
52         loop {
53             let (value, offset) = self.peek_unsigned();
54             if value != 32 && value != 31 {
55                 break;
56             } else {
57                 self.offset += offset;
58                 mods.push(TypeDefOrRef::decode(self.file, self.read_unsigned()))
59             }
60         }
61 
62         mods
63     }
64 
read_str(&mut self) -> &'static str65     pub fn read_str(&mut self) -> &'static str {
66         let len = self.read_unsigned() as usize;
67         self.offset += len;
68         std::str::from_utf8(&self.file.bytes[self.offset - len..self.offset]).unwrap()
69     }
70 
read_utf16(&self) -> String71     pub fn read_utf16(&self) -> String {
72         let bytes = &self.file.bytes[self.offset..];
73         if bytes.as_ptr().align_offset(std::mem::align_of::<u16>()) > 0 {
74             let bytes = bytes
75                 .chunks_exact(2)
76                 .take(self.size / 2)
77                 .map(|chunk| u16::from_le_bytes(chunk.try_into().unwrap()))
78                 .collect::<Vec<u16>>();
79             String::from_utf16(&bytes).unwrap()
80         } else {
81             assert!(
82                 bytes.len() >= self.size,
83                 "Attempt to read from end of memory"
84             );
85             let bytes =
86                 unsafe { std::slice::from_raw_parts(bytes.as_ptr() as *const u16, self.size / 2) };
87             String::from_utf16(bytes).unwrap()
88         }
89     }
90 
read_i8(&mut self) -> i891     pub fn read_i8(&mut self) -> i8 {
92         let value = i8::from_le_bytes(self.bytes()[..1].try_into().unwrap());
93         self.offset += 1;
94         value
95     }
96 
read_u8(&mut self) -> u897     pub fn read_u8(&mut self) -> u8 {
98         let value = u8::from_le_bytes(self.bytes()[..1].try_into().unwrap());
99         self.offset += 1;
100         value
101     }
102 
read_i16(&mut self) -> i16103     pub fn read_i16(&mut self) -> i16 {
104         let value = i16::from_le_bytes(self.bytes()[..2].try_into().unwrap());
105         self.offset += 2;
106         value
107     }
108 
read_u16(&mut self) -> u16109     pub fn read_u16(&mut self) -> u16 {
110         let value = u16::from_le_bytes(self.bytes()[..2].try_into().unwrap());
111         self.offset += 2;
112         value
113     }
114 
read_i32(&mut self) -> i32115     pub fn read_i32(&mut self) -> i32 {
116         let value = i32::from_le_bytes(self.bytes()[..4].try_into().unwrap());
117         self.offset += 4;
118         value
119     }
120 
read_u32(&mut self) -> u32121     pub fn read_u32(&mut self) -> u32 {
122         let value = u32::from_le_bytes(self.bytes()[..4].try_into().unwrap());
123         self.offset += 4;
124         value
125     }
126 
read_i64(&mut self) -> i64127     pub fn read_i64(&mut self) -> i64 {
128         let value = i64::from_le_bytes(self.bytes()[..8].try_into().unwrap());
129         self.offset += 8;
130         value
131     }
132 
read_u64(&mut self) -> u64133     pub fn read_u64(&mut self) -> u64 {
134         let value = u64::from_le_bytes(self.bytes()[..8].try_into().unwrap());
135         self.offset += 8;
136         value
137     }
138 
read_f32(&mut self) -> f32139     pub fn read_f32(&mut self) -> f32 {
140         let value = f32::from_le_bytes(self.bytes()[..4].try_into().unwrap());
141         self.offset += 4;
142         value
143     }
144 
read_f64(&mut self) -> f64145     pub fn read_f64(&mut self) -> f64 {
146         let value = f64::from_le_bytes(self.bytes()[..8].try_into().unwrap());
147         self.offset += 8;
148         value
149     }
150 }
151