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