diff --git a/src/engine.rs b/src/engine.rs index 97489633d..a854f8d89 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -7,7 +7,7 @@ use crate::string::{ use super::{SreAtCode, SreCatCode, SreInfo, SreOpcode, StrDrive, StringCursor, MAXREPEAT}; use optional::Optioned; -use std::convert::TryFrom; +use std::{convert::TryFrom, ptr::null}; #[derive(Debug, Clone, Copy)] pub struct Request<'a, S> { @@ -126,17 +126,12 @@ impl State { self.marks.clear(); self.repeat_stack.clear(); self.start = start; - if self.cursor.ptr.is_null() || self.cursor.position > self.start { - self.cursor = req.string.create_cursor(self.start); - } else if self.cursor.position < self.start { - let skip = self.start - self.cursor.position; - S::skip(&mut self.cursor, skip); - } + req.string.adjust_cursor(&mut self.cursor, start); } pub fn pymatch(&mut self, req: &Request) -> bool { self.start = req.start; - self.cursor = req.string.create_cursor(self.start); + req.string.adjust_cursor(&mut self.cursor, self.start); let ctx = MatchContext { cursor: self.cursor, @@ -151,7 +146,7 @@ impl State { pub fn search(&mut self, mut req: Request) -> bool { self.start = req.start; - self.cursor = req.string.create_cursor(self.start); + req.string.adjust_cursor(&mut self.cursor, self.start); if req.start > req.end { return false; @@ -215,7 +210,9 @@ impl State { || ctx.try_peek_code_as::(&req, 1).unwrap() == SreAtCode::BEGINNING_STRING) { - self.reset(&req, req.end); + self.cursor.position = req.end; + self.cursor.ptr = null(); + // self.reset(&req, req.end); return false; } diff --git a/src/string.rs b/src/string.rs index 464901af8..1340c3742 100644 --- a/src/string.rs +++ b/src/string.rs @@ -16,6 +16,7 @@ impl Default for StringCursor { pub trait StrDrive: Copy { fn count(&self) -> usize; fn create_cursor(&self, n: usize) -> StringCursor; + fn adjust_cursor(&self, cursor: &mut StringCursor, n: usize); fn advance(cursor: &mut StringCursor) -> u32; fn peek(cursor: &StringCursor) -> u32; fn skip(cursor: &mut StringCursor, n: usize); @@ -38,6 +39,12 @@ impl<'a> StrDrive for &'a [u8] { } } + #[inline] + fn adjust_cursor(&self, cursor: &mut StringCursor, n: usize) { + cursor.position = n; + cursor.ptr = self[n..].as_ptr(); + } + #[inline] fn advance(cursor: &mut StringCursor) -> u32 { cursor.position += 1; @@ -83,11 +90,21 @@ impl StrDrive for &str { #[inline] fn create_cursor(&self, n: usize) -> StringCursor { - let mut ptr = self.as_ptr(); - for _ in 0..n { - unsafe { next_code_point(&mut ptr) }; + let mut cursor = StringCursor { + ptr: self.as_ptr(), + position: 0, + }; + Self::skip(&mut cursor, n); + cursor + } + + #[inline] + fn adjust_cursor(&self, cursor: &mut StringCursor, n: usize) { + if cursor.ptr.is_null() || cursor.position > n { + *cursor = Self::create_cursor(&self, n); + } else if cursor.position < n { + Self::skip(cursor, n - cursor.position); } - StringCursor { ptr, position: n } } #[inline]