diff options
Diffstat (limited to 'src/util')
| -rw-r--r-- | src/util/buffer_queue.rs | 80 | ||||
| -rw-r--r-- | src/util/smallcharset.rs | 4 | 
2 files changed, 42 insertions, 42 deletions
| diff --git a/src/util/buffer_queue.rs b/src/util/buffer_queue.rs index 7f8c3cc..5201a57 100644 --- a/src/util/buffer_queue.rs +++ b/src/util/buffer_queue.rs @@ -20,8 +20,6 @@  use std::collections::VecDeque; -use tendril::StrTendril; -  pub use self::SetResult::{FromSet, NotFromSet};  use crate::util::smallcharset::SmallCharSet; @@ -35,7 +33,7 @@ pub enum SetResult {      /// A character from the `SmallCharSet`.      FromSet(char),      /// A string buffer containing no characters from the `SmallCharSet`. -    NotFromSet(StrTendril), +    NotFromSet(String),  }  /// A queue of owned string buffers, which supports incrementally consuming characters. @@ -46,7 +44,7 @@ pub enum SetResult {  #[derive(Debug)]  pub struct BufferQueue {      /// Buffers to process. -    buffers: VecDeque<StrTendril>, +    buffers: VecDeque<(usize, String)>,  }  impl BufferQueue { @@ -66,28 +64,32 @@ impl BufferQueue {      /// Get the buffer at the beginning of the queue.      #[inline] -    pub fn pop_front(&mut self) -> Option<StrTendril> { -        self.buffers.pop_front() +    pub fn pop_front(&mut self) -> Option<String> { +        if let Some((i, s)) = self.buffers.pop_front() { +            return Some(s[i..].into()) +        } +        None +        // self.buffers.pop_front().map(|(i, s)| &s[i..])      }      /// Add a buffer to the beginning of the queue.      ///      /// If the buffer is empty, it will be skipped. -    pub fn push_front(&mut self, buf: StrTendril) { -        if buf.len32() == 0 { +    pub fn push_front(&mut self, buf: String) { +        if buf.len() == 0 {              return;          } -        self.buffers.push_front(buf); +        self.buffers.push_front((0, buf));      }      /// Add a buffer to the end of the queue.      ///      /// If the buffer is empty, it will be skipped. -    pub fn push_back(&mut self, buf: StrTendril) { -        if buf.len32() == 0 { +    pub fn push_back(&mut self, buf: String) { +        if buf.len() == 0 {              return;          } -        self.buffers.push_back(buf); +        self.buffers.push_back((0, buf));      }      /// Look at the next available character without removing it, if the queue is not empty. @@ -95,11 +97,11 @@ impl BufferQueue {          debug_assert!(              self.buffers                  .iter() -                .find(|el| el.len32() == 0) +                .find(|(i, s)| s[*i..].is_empty())                  .is_none(),              "invariant \"all buffers in the queue are non-empty\" failed"          ); -        self.buffers.front().map(|b| b.chars().next().unwrap()) +        self.buffers.front().map(|(i, s)| s[*i..].chars().next().unwrap())      }      /// Get the next character if one is available, removing it from the queue. @@ -108,9 +110,10 @@ impl BufferQueue {      pub fn next(&mut self) -> Option<char> {          let (result, now_empty) = match self.buffers.front_mut() {              None => (None, false), -            Some(buf) => { -                let c = buf.pop_front_char().expect("empty buffer in queue"); -                (Some(c), buf.is_empty()) +            Some((i, buf)) => { +                let c = &buf[*i..].chars().next().expect("empty buffer in queue"); +                *i += c.len_utf8(); +                (Some(*c), buf[*i..].is_empty())              },          }; @@ -126,18 +129,15 @@ impl BufferQueue {      pub fn pop_except_from(&mut self, set: SmallCharSet) -> Option<SetResult> {          let (result, now_empty) = match self.buffers.front_mut() {              None => (None, false), -            Some(buf) => { -                let n = set.nonmember_prefix_len(&buf); +            Some((i, buf)) => { +                let n = set.nonmember_prefix_len(&buf[*i..]);                  if n > 0 { -                    let out; -                    unsafe { -                        out = buf.unsafe_subtendril(0, n); -                        buf.unsafe_pop_front(n); -                    } -                    (Some(NotFromSet(out)), buf.is_empty()) +                    let out = buf.drain(*i..*i + n).collect(); +                    (Some(NotFromSet(out)), buf[*i..].is_empty())                  } else { -                    let c = buf.pop_front_char().expect("empty buffer in queue"); -                    (Some(FromSet(c)), buf.is_empty()) +                    let c = &buf[*i..].chars().next().expect("empty buffer in queue"); +                    *i += c.len_utf8(); +                    (Some(FromSet(*c)), buf[*i..].is_empty())                  }              },          }; @@ -166,9 +166,9 @@ impl BufferQueue {              if buffers_exhausted >= self.buffers.len() {                  return None;              } -            let buf = &self.buffers[buffers_exhausted]; +            let (i, buf) = &self.buffers[buffers_exhausted]; -            if !eq(&buf.as_bytes()[consumed_from_last], &pattern_byte) { +            if !eq(&buf[*i..].as_bytes()[consumed_from_last], &pattern_byte) {                  return Some(false);              } @@ -186,7 +186,9 @@ impl BufferQueue {          match self.buffers.front_mut() {              None => assert_eq!(consumed_from_last, 0), -            Some(ref mut buf) => buf.pop_front(consumed_from_last as u32), +            Some((i, _buf)) => { +                *i += consumed_from_last; +            },          }          Some(true) @@ -196,8 +198,6 @@ impl BufferQueue {  #[cfg(test)]  #[allow(non_snake_case)]  mod test { -    use tendril::SliceExt; -      use super::BufferQueue;      use super::SetResult::{FromSet, NotFromSet}; @@ -207,7 +207,7 @@ mod test {          assert_eq!(bq.peek(), None);          assert_eq!(bq.next(), None); -        bq.push_back("abc".to_tendril()); +        bq.push_back("abc".into());          assert_eq!(bq.peek(), Some('a'));          assert_eq!(bq.next(), Some('a'));          assert_eq!(bq.peek(), Some('b')); @@ -222,10 +222,10 @@ mod test {      #[test]      fn can_unconsume() {          let mut bq = BufferQueue::new(); -        bq.push_back("abc".to_tendril()); +        bq.push_back("abc".into());          assert_eq!(bq.next(), Some('a')); -        bq.push_front("xy".to_tendril()); +        bq.push_front("xy".into());          assert_eq!(bq.next(), Some('x'));          assert_eq!(bq.next(), Some('y'));          assert_eq!(bq.next(), Some('b')); @@ -236,11 +236,11 @@ mod test {      #[test]      fn can_pop_except_set() {          let mut bq = BufferQueue::new(); -        bq.push_back("abc&def".to_tendril()); +        bq.push_back("abc&def".into());          let mut pop = || bq.pop_except_from(small_char_set!('&')); -        assert_eq!(pop(), Some(NotFromSet("abc".to_tendril()))); +        assert_eq!(pop(), Some(NotFromSet("abc".into())));          assert_eq!(pop(), Some(FromSet('&'))); -        assert_eq!(pop(), Some(NotFromSet("def".to_tendril()))); +        assert_eq!(pop(), Some(NotFromSet("def".into())));          assert_eq!(pop(), None);      } @@ -250,8 +250,8 @@ mod test {          // integration tests for more thorough testing with many          // different input buffer splits.          let mut bq = BufferQueue::new(); -        bq.push_back("a".to_tendril()); -        bq.push_back("bc".to_tendril()); +        bq.push_back("a".into()); +        bq.push_back("bc".into());          assert_eq!(bq.eat("abcd", u8::eq_ignore_ascii_case), None);          assert_eq!(bq.eat("ax", u8::eq_ignore_ascii_case), Some(false));          assert_eq!(bq.eat("ab", u8::eq_ignore_ascii_case), Some(true)); diff --git a/src/util/smallcharset.rs b/src/util/smallcharset.rs index aeeb189..2bf8585 100644 --- a/src/util/smallcharset.rs +++ b/src/util/smallcharset.rs @@ -41,7 +41,7 @@ impl SmallCharSet {      /// Count the number of bytes of characters at the beginning of `buf` which are not in the set.      ///      /// This functionality is used in [`BufferQueue::pop_except_from`]. -    pub fn nonmember_prefix_len(&self, buf: &str) -> u32 { +    pub fn nonmember_prefix_len(&self, buf: &str) -> usize {          let mut n = 0;          for b in buf.bytes() {              if b >= 64 || !self.contains(b) { @@ -61,7 +61,7 @@ mod test {      #[test]      fn nonmember_prefix() {          for &c in ['&', '\0'].iter() { -            for x in 0..48u32 { +            for x in 0..48 {                  for y in 0..48u32 {                      let mut s = repeat("x").take(x as usize).collect::<String>();                      s.push(c); | 
