Skip to main content

Lexer

Struct Lexer 

Source
pub struct Lexer<'a> { /* private fields */ }
Expand description

A cursor over the bytes of a PDF file.

Offsets are relative to whatever slice the lexer was built over. The document layer passes the file from its header onwards, so a lexer position and a cross-reference offset mean the same thing.

use pdfrum_common::Limits;
use pdfrum_parser::{Lexer, Token};

let limits = Limits::default();
let mut lx = Lexer::new(b"12 0 obj % a comment\n<< /Type /Page >>");
assert_eq!(lx.next_word(&limits), Token::Number(b"12"));
assert_eq!(lx.next_word(&limits), Token::Number(b"0"));
assert_eq!(lx.next_word(&limits), Token::Keyword(b"obj"));
// Comments are invisible everywhere except inside strings.
assert!(matches!(lx.next_word(&limits), Token::Delim(_)));
assert_eq!(lx.next_word(&limits), Token::Name(b"Type"));

Implementations§

Source§

impl<'a> Lexer<'a>

Source

pub fn new(bytes: &'a [u8]) -> Self

A lexer positioned at the start of bytes.

Source

pub fn at(bytes: &'a [u8], pos: usize) -> Self

A lexer positioned at pos, clamped to the end of the input.

Source

pub fn bytes(&self) -> &'a [u8]

The bytes being read.

Source

pub fn pos(&self) -> usize

The current offset.

Source

pub fn seek(&mut self, pos: usize)

Move to pos, clamped to the end of the input.

Source

pub fn at_eof(&self) -> bool

Whether the cursor is at or past the end.

Source

pub fn peek_byte(&self) -> Option<u8>

The byte at the cursor, without advancing.

Source

pub fn skip_to_word(&mut self)

Skip whitespace and comments, leaving the cursor on the first byte of the next token (or at the end).

A % runs to the next line ending, and the skipping repeats — so a block of comment lines costs one call.

Source

pub fn to_next_line(&mut self)

Move past the next line ending, so the cursor sits on the first byte of the following line.

A \r\n pair counts as one ending. This is how stream data finds its first byte after the stream keyword (ISO 32000-1 §7.3.8.1).

Source

pub fn skip_eol_marker(&mut self) -> usize

Consume one end-of-line marker if the cursor is on one, and report how many bytes it took: two for \r\n, one for a lone \r or \n, zero for anything else.

Source

pub fn next_word(&mut self, limits: &Limits) -> Token<'a>

Read the next token, skipping whitespace and comments first.

Words longer than limits.max_word_len are truncated in the returned token but consumed whole, so the cursor always lands past the run.

Source

pub fn peek_word(&mut self, limits: &Limits) -> Token<'a>

Read the next token and restore the cursor, so a caller can decide what to do without committing.

Source

pub fn read_literal_string(&mut self) -> Cow<'a, [u8]>

Read the body of a literal string, the ( already consumed (ISO 32000-1 §7.3.4.2).

Nested parentheses are kept as content and only an unescaped ) at depth zero ends the string. An end of file ends it too, silently, with whatever was read — the recovery scan depends on that, because it uses this function to skip over string bodies that may well be truncated.

The result borrows the file when no escape sequence forced a rewrite.

Source

pub fn read_hex_string(&mut self) -> Vec<u8>

Read the body of a hexadecimal string, the < already consumed (ISO 32000-1 §7.3.4.3).

Every byte that is neither a hex digit nor > is skipped without comment — whitespace, NULs, letters, anything. A > or the end of file ends the string, and a dangling half byte is padded with a zero nibble, so <1A2 reads as 1A 20.

Source

pub fn search_back(&mut self, word: &[u8], window: usize) -> bool

Search backwards from the cursor for word as a whole word, within window bytes, and leave the cursor on its first byte.

“Whole word” means the neighbouring bytes are not regular or numeric; a delimiter beside the word is an acceptable boundary. The cursor’s own byte is inside the search, so a match may end at pos() rather than before it. This is how startxref is found in a file whose tail is otherwise junk.

Trait Implementations§

Source§

impl<'a> Clone for Lexer<'a>

Source§

fn clone(&self) -> Lexer<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for Lexer<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Lexer<'a>

§

impl<'a> RefUnwindSafe for Lexer<'a>

§

impl<'a> Send for Lexer<'a>

§

impl<'a> Sync for Lexer<'a>

§

impl<'a> Unpin for Lexer<'a>

§

impl<'a> UnsafeUnpin for Lexer<'a>

§

impl<'a> UnwindSafe for Lexer<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.