Skip to content

Commit 3ff5b66

Browse files
committed
Use generics in Parser::read instead
1 parent c3fd205 commit 3ff5b66

File tree

1 file changed

+42
-39
lines changed

1 file changed

+42
-39
lines changed

src/parse.rs

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
imp::{AuthMeta, Constraints, HostMeta, Meta},
3-
pct_enc::{self, encoder::*, Encoder},
3+
pct_enc::{self, encoder::*, Encoder, Table},
44
utf8,
55
};
66
use core::{
@@ -164,6 +164,44 @@ impl<'a> Reader<'a> {
164164
err!(i, UnexpectedCharOrEnd);
165165
}
166166

167+
// FIXME: This makes things faster but causes significant bloat.
168+
#[inline(always)]
169+
fn read_generic<const ALLOW_PCT_ENCODED: bool, const ALLOW_NON_ASCII: bool>(
170+
&mut self,
171+
table: Table,
172+
) -> Result<bool> {
173+
let start = self.pos;
174+
let mut i = self.pos;
175+
176+
while i < self.len() {
177+
let x = self.bytes[i];
178+
if ALLOW_PCT_ENCODED && x == b'%' {
179+
let [hi, lo, ..] = self.bytes[i + 1..] else {
180+
return self.invalid_pct();
181+
};
182+
if !pct_enc::is_hexdig_pair(hi, lo) {
183+
return self.invalid_pct();
184+
}
185+
i += 3;
186+
} else if ALLOW_NON_ASCII {
187+
let (x, len) = utf8::next_code_point(self.bytes, i);
188+
if !table.allows_code_point(x) {
189+
break;
190+
}
191+
i += len;
192+
} else {
193+
if !table.allows_ascii(x) {
194+
break;
195+
}
196+
i += 1;
197+
}
198+
}
199+
200+
// INVARIANT: `i` is non-decreasing.
201+
self.pos = i;
202+
Ok(self.pos > start)
203+
}
204+
167205
#[inline(always)]
168206
fn read<E: Encoder>(&mut self) -> Result<bool> {
169207
struct Helper<E: Encoder> {
@@ -175,51 +213,16 @@ impl<'a> Reader<'a> {
175213
const ALLOWS_NON_ASCII: bool = E::TABLE.allows_non_ascii();
176214
}
177215

178-
let start = self.pos;
179-
let mut i = self.pos;
180-
181-
macro_rules! do_loop {
182-
($allow_pct_encoded:expr, $allow_non_ascii:expr) => {
183-
while i < self.len() {
184-
let x = self.bytes[i];
185-
if $allow_pct_encoded && x == b'%' {
186-
let [hi, lo, ..] = self.bytes[i + 1..] else {
187-
return self.invalid_pct();
188-
};
189-
if !pct_enc::is_hexdig_pair(hi, lo) {
190-
return self.invalid_pct();
191-
}
192-
i += 3;
193-
} else if $allow_non_ascii {
194-
let (x, len) = utf8::next_code_point(self.bytes, i);
195-
if !E::TABLE.allows_code_point(x) {
196-
break;
197-
}
198-
i += len;
199-
} else {
200-
if !E::TABLE.allows_ascii(x) {
201-
break;
202-
}
203-
i += 1;
204-
}
205-
}
206-
};
207-
}
208-
209216
if Helper::<E>::ALLOWS_PCT_ENCODED {
210217
if Helper::<E>::ALLOWS_NON_ASCII {
211-
do_loop!(true, true);
218+
self.read_generic::<true, true>(E::TABLE)
212219
} else {
213-
do_loop!(true, false);
220+
self.read_generic::<true, false>(E::TABLE)
214221
}
215222
} else {
216223
assert!(!Helper::<E>::ALLOWS_NON_ASCII);
217-
do_loop!(false, false);
224+
self.read_generic::<false, false>(E::TABLE)
218225
}
219-
220-
// INVARIANT: `i` is non-decreasing.
221-
self.pos = i;
222-
Ok(self.pos > start)
223226
}
224227

225228
fn read_str(&mut self, s: &str) -> bool {

0 commit comments

Comments
 (0)