pdf_lib_rs/core/parser/
byte_stream.rs1use crate::core::syntax::CharCodes;
2
3#[derive(Debug, Clone, Copy)]
5pub struct Position {
6 pub line: usize,
7 pub column: usize,
8 pub offset: usize,
9}
10
11pub struct ByteStream<'a> {
13 bytes: &'a [u8],
14 idx: usize,
15 line: usize,
16 column: usize,
17}
18
19impl<'a> ByteStream<'a> {
20 pub fn of(bytes: &'a [u8]) -> Self {
21 ByteStream {
22 bytes,
23 idx: 0,
24 line: 0,
25 column: 0,
26 }
27 }
28
29 pub fn move_to(&mut self, offset: usize) {
30 self.idx = offset;
31 }
32
33 #[allow(clippy::should_implement_trait)]
34 pub fn next(&mut self) -> Option<u8> {
35 if self.idx >= self.bytes.len() {
36 return None;
37 }
38 let byte = self.bytes[self.idx];
39 self.idx += 1;
40 if byte == CharCodes::Newline {
41 self.line += 1;
42 self.column = 0;
43 } else {
44 self.column += 1;
45 }
46 Some(byte)
47 }
48
49 pub fn peek(&self) -> Option<u8> {
50 self.bytes.get(self.idx).copied()
51 }
52
53 pub fn peek_ahead(&self, steps: usize) -> Option<u8> {
54 self.bytes.get(self.idx + steps).copied()
55 }
56
57 pub fn done(&self) -> bool {
58 self.idx >= self.bytes.len()
59 }
60
61 pub fn offset(&self) -> usize {
62 self.idx
63 }
64
65 pub fn slice(&self, start: usize, end: usize) -> &'a [u8] {
66 &self.bytes[start..end.min(self.bytes.len())]
67 }
68
69 pub fn position(&self) -> Position {
70 Position {
71 line: self.line,
72 column: self.column,
73 offset: self.idx,
74 }
75 }
76
77 pub fn remaining(&self) -> &'a [u8] {
78 &self.bytes[self.idx..]
79 }
80}