m8_file_parser/
reader.rs

1use std::fmt;
2
3#[derive(PartialEq, Debug)]
4pub struct ParseError(pub String);
5
6impl fmt::Display for ParseError {
7    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8        write!(f, "ParseError: {}", &self.0)
9    }
10}
11
12impl std::error::Error for ParseError {}
13
14/// Spefic result type for M8 song parsing
15pub type M8Result<T> = std::result::Result<T, ParseError>;
16
17pub struct Reader {
18    buffer: Vec<u8>,
19    position: usize,
20}
21
22#[allow(dead_code)]
23impl Reader {
24    pub fn new(buffer: Vec<u8>) -> Self {
25        Self {
26            buffer,
27            position: 0,
28        }
29    }
30
31    pub fn len(&self) -> usize {
32        self.buffer.len()
33    }
34
35    pub fn read(&mut self) -> u8 {
36        let p: usize = self.position;
37        let b = self.buffer[p];
38        self.position += 1;
39        b
40    }
41
42    pub fn read_bytes(&mut self, n: usize) -> &[u8] {
43        let p: usize = self.position;
44        let bs = &self.buffer[p..p + n];
45        self.position += n;
46        bs
47    }
48
49    pub fn read_bool(&mut self) -> bool {
50        self.read() == 1
51    }
52
53    pub fn read_string(&mut self, n: usize) -> String {
54        let b = self.read_bytes(n);
55        let mut end = b.iter().position(|&x| x == 0 || x == 255).unwrap_or(n);
56
57        while end > 0 {
58            match std::str::from_utf8(&b[0..end]) {
59                Ok(str) => return str.to_string(),
60                Err(_) => end -= 1,
61            }
62        }
63
64        String::from("")
65    }
66
67    pub fn pos(&self) -> usize {
68        self.position
69    }
70
71    pub fn set_pos(&mut self, n: usize) {
72        self.position = n;
73    }
74}