1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
use super::{Error, Encoding}; #[derive(Clone)] pub struct StringTable<'a> { slice: &'a [u8], } impl<'a> StringTable<'a> { pub fn new(slice: &'a [u8]) -> Self { StringTable { slice } } pub fn pick(&self, index: usize) -> Result<&'a str, Error> { use core::str::from_utf8; const MAX_LENGTH: usize = 0xff; let mut length = 0; loop { if index + length > self.slice.len() { return Err(Error::SliceTooShort); } if self.slice[index + length] == 0 || length == MAX_LENGTH { break; } else { length += 1; } } from_utf8(&self.slice[index..(index + length)]).map_err(Error::Utf8Error) } pub fn as_raw(&self) -> &'a [u8] { self.slice } } #[derive(Clone, Debug, Eq, PartialEq)] pub struct NoteEntry<'a> { pub ty: u64, pub name: &'a str, pub description: &'a [u8], } #[derive(Clone)] pub struct NoteTable<'a> { slice: &'a [u8], encoding: Encoding, } impl<'a> NoteTable<'a> { pub fn new(slice: &'a [u8], encoding: Encoding) -> Self { NoteTable { slice, encoding } } pub fn next(&self, position: &mut usize) -> Result<NoteEntry<'a>, Error> { use core::str; if self.slice.len() < *position + 0x18 { return Err(Error::SliceTooShort); }; let align8 = |x: usize| if x % 8 == 0 { x } else { x + 8 - x % 8 }; let header = &self.slice[*position..]; let name_size = read_int!(&header[0x00..], &self.encoding, u64) as usize; let description_size = read_int!(&header[0x08..], &self.encoding, u64) as usize; let ty = read_int!(&header[0x10..], &self.encoding, u64); let name_size_aligned = align8(name_size); let description_size = align8(description_size); let new_position = *position + 0x18 + name_size_aligned + description_size; if self.slice.len() < new_position { return Err(Error::SliceTooShort); }; let str_start = *position + 0x18; let str_end = str_start + name_size; let entry = NoteEntry { ty, name: str::from_utf8(&self.slice[str_start..str_end]).map_err(Error::Utf8Error)?, description: &self.slice[str_end..new_position], }; *position = new_position; Ok(entry) } }