Skip to content

LineIterator

Mojo struct 🡭

@memory_only
struct LineIterator[R: Reader]

Iterates over newline-separated lines from a BufferedReader. Owns the buffer; parsers hold LineIterator and use next_line.

Supports the Mojo Iterator protocol: for line in line_iterator works. Each line is a Span[Byte, MutExternalOrigin] invalidated by the next iteration or any buffer mutation (same contract as next_line()).

  • IteratorType[origin: Origin]: AnyStruct[_LineIteratorIter[R, origin]] = _LineIteratorIter[R, origin]
  • R (Reader)
  • buffer (BufferedReader[R])

AnyType, ImplicitlyDestructible, Iterable, Movable

def __init__(out self, var reader: R, capacity: Int = 262144, growth_enabled: Bool = False, max_capacity: Int = 1073741824)

Build a line iterator over a Reader. Optionally allow buffer growth for long lines.

Args:

  • reader (R): Source (e.g. FileReader, MemoryReader).
  • capacity (Int): Initial buffer size in bytes.
  • growth_enabled (Bool): If True, buffer can grow up to max_capacity for long lines.
  • max_capacity (Int): Maximum buffer size when growth is enabled.
  • self (Self)

Returns:

Self

Raises:

def stream_position(self) -> Int

Logical byte position of next line start (for errors and compaction).

Args:

  • self (Self)

Returns:

Int

def buffer_position(self) -> Int

Current read offset in the buffer (for parser compact_from).

Args:

  • self (Self)

Returns:

Int

def get_line_number(self) -> Int

Return the current line number (1-indexed).

Args:

  • self (Self)

Returns:

Int: The line number of the last line returned by next_line(), or 0 if no lines have been read yet.

def get_file_position(self) -> Int64

Return the current byte position in the file.

Args:

  • self (Self)

Returns:

Int64: The byte position corresponding to the start of the current line, or 0 if unknown.

def has_more(self) -> Bool

True if there is at least one more line (data in buffer or more can be read).

Args:

  • self (Self)

Returns:

Bool

def next_line(mut self) -> Span[Byte, MutExternalOrigin]

Next line as span excluding newline (and trimming trailing \r). None at EOF. Invalidated by next next_line() or any buffer mutation.

Args:

  • self (Self)

Returns:

Span

Raises:

def next_complete_line(mut self) -> Span[Byte, MutExternalOrigin]

Return the next line only if a complete line (ending with newline) is in the current buffer. Does not compact. When the buffer is empty, refills once to distinguish EOF from EMPTY_BUFFER. If no newline is found, raise LineIteratorError.INCOMPLETE_LINE and do not consume; if the buffer is empty after a refill, raise LineIteratorError.EMPTY_BUFFER. Caller can fall back to next_line() to refill. Invalidated by next next_line or any buffer grow/compact/resize.

Args:

  • self (Self)

Returns:

Span

Raises:

def peek(self, amt: Int) -> Span[Byte, MutExternalOrigin]

Peek at the next amt bytes in the buffer without consuming them.

Args:

  • self (Self)
  • amt (Int)

Returns:

Span

Raises:

def read_exact(mut self, size: Int) -> Span[Byte, MutExternalOrigin]

Read exactly size bytes. Refills and compacts the buffer as needed. Raises EOFError if the stream ends before size bytes are available. Returns a span over the buffer; valid only until the next mutating call.

Args:

  • self (Self)
  • size (Int)

Returns:

Span

Raises:

def consume_line_scalar(mut self) -> Span[Byte, MutExternalOrigin]

Consume the next line (plus line) using scalar memchr to find newline. Validates line starts with ’+’. Does not refill; raises INCOMPLETE_LINE if newline not in current buffer. Raises OTHER if line does not start with ’+’.

Args:

  • self (Self)

Returns:

Span

Raises:

def __iter__(ref self) -> _LineIteratorIter[R, origin_of(self)]

Return an iterator for use in for line in self.

Args:

  • self (Self)

Returns:

_LineIteratorIter