diff --git a/src/binary/reader.rs b/src/binary/reader.rs index 30010b3..9b408f3 100644 --- a/src/binary/reader.rs +++ b/src/binary/reader.rs @@ -2,7 +2,7 @@ use super::{ lexer::{read_id, read_string, read_token}, LexError, LexemeId, LexerError, Token, }; -use crate::buffer::{BufferError, BufferWindow, BufferWindowBuilder}; +use crate::buffer::{BufferError, BufferWindow, BufferWindowBuilder, SliceReader}; use std::{fmt, io::Read}; /// [Lexer](crate::binary::Lexer) that works over a [Read] implementation @@ -56,6 +56,15 @@ where TokenReader::builder().build(reader) } + /// Read from a byte slice without memcpy's + #[inline] + pub fn from_slice(data: &[u8]) -> TokenReader> { + TokenReader { + reader: SliceReader::new(data), + buf: BufferWindow::from_slice(data), + } + } + /// Returns the byte position of the data stream that has been processed. /// /// ```rust diff --git a/src/buffer.rs b/src/buffer.rs index 5cb66d1..4901507 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -1,5 +1,5 @@ use crate::Scalar; -use std::{io::Read, ops::Range}; +use std::{io::Read, marker::PhantomData, ops::Range}; #[derive(Debug)] pub struct BufferWindow { @@ -21,6 +21,16 @@ pub enum BufferError { } impl BufferWindow { + #[inline] + pub fn from_slice(data: &[u8]) -> Self { + Self { + buf: Box::new([]), + start: data.as_ptr(), + end: data.as_ptr_range().end, + prior_reads: 0, + } + } + #[inline] pub fn advance_to(&mut self, ptr: *const u8) { debug_assert!((self.start..=self.end).contains(&ptr)); @@ -139,3 +149,18 @@ impl BufferWindowBuilder { } } } + +#[derive(Debug)] +pub struct SliceReader<'a>(PhantomData<&'a [u8]>); + +impl<'a> SliceReader<'a> { + pub fn new(_data: &'a [u8]) -> Self { + SliceReader(PhantomData) + } +} + +impl<'a> Read for SliceReader<'a> { + fn read(&mut self, _buf: &mut [u8]) -> std::io::Result { + Ok(0) + } +} diff --git a/src/text/reader.rs b/src/text/reader.rs index 896ca49..820cb8b 100644 --- a/src/text/reader.rs +++ b/src/text/reader.rs @@ -1,6 +1,6 @@ use super::Operator; use crate::{ - buffer::{BufferError, BufferWindow, BufferWindowBuilder}, + buffer::{BufferError, BufferWindow, BufferWindowBuilder, SliceReader}, data::is_boundary, util::{contains_zero_byte, count_chunk, repeat_byte}, Scalar, @@ -109,6 +109,16 @@ where TokenReader::builder().build(reader) } + /// Read from a byte slice without memcpy's + #[inline] + pub fn from_slice(data: &[u8]) -> TokenReader> { + TokenReader { + reader: SliceReader::new(data), + buf: BufferWindow::from_slice(data), + utf8: Utf8Bom::Unknown, + } + } + /// Returns the byte position of the data stream that has been processed. /// /// ```rust