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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
//! A byte reader.
use core::ops::Range;
/// A reader for reading bytes and PDF objects.
#[derive(Clone, Debug)]
pub struct Reader<'a> {
/// The underlying data of the reader.
pub data: &'a [u8],
/// The current byte-offset.
pub offset: usize,
}
impl<'a> Reader<'a> {
/// Create a new reader.
#[inline]
pub fn new(data: &'a [u8]) -> Self {
Self { data, offset: 0 }
}
/// Create a new reader at the given offset.
#[inline]
pub fn new_with(data: &'a [u8], offset: usize) -> Self {
Self { data, offset }
}
/// Returns `true` if the reader has reached the end of the data.
#[inline]
pub fn at_end(&self) -> bool {
self.offset >= self.data.len()
}
/// Moves the reader offset to the end of the data.
#[inline]
pub fn jump_to_end(&mut self) {
self.offset = self.data.len();
}
/// Moves the reader to the specified offset.
#[inline]
pub fn jump(&mut self, offset: usize) {
self.offset = offset;
}
/// Returns the remaining data from the current offset to the end.
#[inline]
pub fn tail(&mut self) -> Option<&'a [u8]> {
self.data.get(self.offset..)
}
/// Returns the total length of the underlying data.
#[inline]
pub fn len(&self) -> usize {
self.data.len()
}
/// Returns `true` if the underlying data is empty.
#[inline]
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
/// Returns a slice of the data for the specified range.
#[inline]
pub fn range(&self, range: Range<usize>) -> Option<&'a [u8]> {
self.data.get(range)
}
/// Returns the current offset of the reader.
#[inline]
pub fn offset(&self) -> usize {
self.offset
}
/// Reads the specified number of bytes and advances the offset.
#[inline]
pub fn read_bytes(&mut self, len: usize) -> Option<&'a [u8]> {
let v = self.peek_bytes(len)?;
self.offset += len;
Some(v)
}
/// Reads a single byte and advances the offset.
#[inline]
pub fn read_byte(&mut self) -> Option<u8> {
let v = self.peek_byte()?;
self.offset += 1;
Some(v)
}
/// Skips the specified number of bytes by advancing the offset.
#[inline]
pub fn skip_bytes(&mut self, len: usize) -> Option<()> {
self.read_bytes(len).map(|_| {})
}
/// Peeks the specified number of bytes.
#[inline]
pub fn peek_bytes(&self, len: usize) -> Option<&'a [u8]> {
self.data.get(self.offset..self.offset + len)
}
/// Peeks a single byte.
#[inline]
pub fn peek_byte(&self) -> Option<u8> {
self.data.get(self.offset).copied()
}
/// Eat the next byte if it satisfies the condition.
#[inline]
pub fn eat(&mut self, f: impl Fn(u8) -> bool) -> Option<u8> {
let val = self.peek_byte()?;
if f(val) {
self.forward();
Some(val)
} else {
None
}
}
/// Advances the offset by one byte.
#[inline]
pub fn forward(&mut self) {
self.offset += 1;
}
/// Advances the offset by one byte if the current byte satisfies the predicate.
#[inline]
pub fn forward_if(&mut self, f: impl Fn(u8) -> bool) -> Option<()> {
if f(self.peek_byte()?) {
self.forward();
Some(())
} else {
None
}
}
/// Advances the offset while bytes satisfy the predicate, at least one time.
#[inline]
pub fn forward_while_1(&mut self, f: impl Fn(u8) -> bool) -> Option<()> {
self.eat(&f)?;
self.forward_while(f);
Some(())
}
/// Advances the offset if the next bytes match the specified tag.
#[inline]
pub fn forward_tag(&mut self, tag: &[u8]) -> Option<()> {
self.peek_tag(tag)?;
self.offset += tag.len();
Some(())
}
/// Advances the offset while the given byte satisfies the predicate.
#[inline]
pub fn forward_while(&mut self, f: impl Fn(u8) -> bool) {
while let Some(b) = self.peek_byte() {
if f(b) {
self.forward();
} else {
break;
}
}
}
/// Checks if the next bytes match the specified tag.
#[inline]
pub fn peek_tag(&self, tag: &[u8]) -> Option<()> {
let mut cloned = self.clone();
for b in tag.iter().copied() {
if cloned.peek_byte() == Some(b) {
cloned.forward();
} else {
return None;
}
}
Some(())
}
/// Read a u16 integer (in big endian order).
#[inline]
pub fn read_u16(&mut self) -> Option<u16> {
let bytes = self.read_bytes(2)?;
Some(u16::from_be_bytes([bytes[0], bytes[1]]))
}
/// Read a u32 integer (in big endian order).
#[inline]
pub fn read_u32(&mut self) -> Option<u32> {
let bytes = self.read_bytes(4)?;
Some(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}
/// Read a u64 integer (in big endian order).
#[inline]
pub fn read_u64(&mut self) -> Option<u64> {
let bytes = self.read_bytes(8)?;
Some(u64::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
]))
}
}