package cursor import ( "errors" "fmt" "io" "unicode/utf8" ) // BufferedReaderAt uses a buffer to supplement an io.Reader // with limited backward seeking. type BufferedReaderAt struct{} func NewBufferedReaderAt(r io.Reader, minBuffer uint64) *BufferedReaderAt { return nil } // ReadAt reads bytes from the underlying reader. If the offset is after // the end of the buffer, ReadAt will first read and ignore bytes from the // underlying reader until it reaches the offset. If the offset is // before the start of the buffer, ReadAt will return an error. // // If your parser needs unlimited lookahead, you should probably // just read the whole input into a slice and use BytesCursor. func (b *BufferedReaderAt) ReadAt(dst []byte, offset int64) (int, error) { return 0, nil } // RuneReader is an io.RuneReader backed by a Cursor, for compatibility // with the regexp package. type RuneReader struct { cursor Cursor[byte] } func NewRuneReader(c Cursor[byte]) *RuneReader { return &RuneReader{cursor: c} } func (rr *RuneReader) ReadRune() (r rune, size int, err error) { var b [4]byte s := b[:] n, next, err := rr.cursor.Read(s) if err != nil && !errors.Is(err, io.EOF) { rr.cursor = next return 0, 0, fmt.Errorf("ReadRune: %w", err) } s = s[:n] r, size = utf8.DecodeRune(s) rr.cursor = rr.cursor.At(rr.cursor.Pos() + uint64(size)) return r, size, err } func (rr *RuneReader) Cursor() Cursor[byte] { return rr.cursor }