Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Leonora Tindall | 1cbd2e725a |
45
src/lib.rs
45
src/lib.rs
|
@ -11,6 +11,8 @@ use std::io::Write;
|
|||
pub struct Parser {
|
||||
token: &'static [u8],
|
||||
suffix: &'static [u8],
|
||||
/// NORA: Records the position in the token across calls to `process`.
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
impl Parser {
|
||||
|
@ -19,7 +21,11 @@ impl Parser {
|
|||
//
|
||||
// NOTE: This function signature should stay the same.
|
||||
pub fn new(token: &'static [u8], suffix: &'static [u8]) -> Self {
|
||||
Self { token, suffix }
|
||||
Self {
|
||||
token,
|
||||
suffix,
|
||||
pos: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Write the bytes given in `input` to `output`, plus the bytes in `suffix`
|
||||
|
@ -56,7 +62,42 @@ impl Parser {
|
|||
//
|
||||
// NOTE: This function signature should stay the same.
|
||||
pub fn process(&mut self, input: &[u8], output: &mut dyn Write) -> Result<(), std::io::Error> {
|
||||
output.write_all(input)
|
||||
// NORA: Create a buffer to work in for just this call.
|
||||
// We'll write the whole buffer at the end, unconditionally;
|
||||
// the only question is what's in it.
|
||||
let mut buffer = Vec::with_capacity(input.len() + self.suffix.len());
|
||||
|
||||
// NORA: Look at each byte in the input.
|
||||
for byte in input {
|
||||
// NORA: Unconditionally, write that byte into our buffer.
|
||||
// No requirement calls for losing any bytes.
|
||||
buffer.push(*byte);
|
||||
|
||||
// NORA: Compare the current byte in the input to the current byte
|
||||
// in the token.
|
||||
if *byte == self.token[self.pos] {
|
||||
// NORA: If this byte is a match, progress to the next token byte.
|
||||
self.pos += 1;
|
||||
// NORA: If we've reached the end of the token,
|
||||
// that's a successful match.
|
||||
if self.pos == self.token.len() {
|
||||
// NORA: Write the whole suffix into the output buffer.
|
||||
for suffix_byte in self.suffix {
|
||||
buffer.push(*suffix_byte);
|
||||
}
|
||||
// NORA: And reset to zero, so we can look for a new match.
|
||||
self.pos = 0;
|
||||
}
|
||||
} else {
|
||||
// NORA: If the current input byte isn't a match for the current
|
||||
// token byte, we have failed to match the token;
|
||||
// reset to the beginning.
|
||||
// This prevents e.g. "oat meal" from matching "oatmeal".
|
||||
self.pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
output.write_all(&buffer)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue