dns/scanner.go

57 lines
1.0 KiB
Go
Raw Normal View History

2012-02-22 08:36:27 +11:00
package dns
2012-02-22 08:43:24 +11:00
2012-02-22 08:36:27 +11:00
// Implement a simple scanner, return a byte stream from an io reader.
import (
"bufio"
"context"
2012-02-22 08:36:27 +11:00
"io"
"text/scanner"
)
type scan struct {
2012-02-22 08:43:24 +11:00
src *bufio.Reader
position scanner.Position
eof bool // Have we just seen a eof
ctx context.Context
2012-02-22 08:36:27 +11:00
}
func scanInit(r io.Reader) (*scan, context.CancelFunc) {
2012-02-22 08:36:27 +11:00
s := new(scan)
s.src = bufio.NewReader(r)
2012-02-22 08:43:24 +11:00
s.position.Line = 1
ctx, cancel := context.WithCancel(context.Background())
s.ctx = ctx
return s, cancel
2012-02-22 08:36:27 +11:00
}
// tokenText returns the next byte from the input
func (s *scan) tokenText() (byte, error) {
2012-02-22 08:43:24 +11:00
c, err := s.src.ReadByte()
if err != nil {
return c, err
}
select {
case <-s.ctx.Done():
return c, context.Canceled
default:
break
}
// delay the newline handling until the next token is delivered,
// fixes off-by-one errors when reporting a parse error.
if s.eof == true {
2012-02-22 08:43:24 +11:00
s.position.Line++
s.position.Column = 0
s.eof = false
}
if c == '\n' {
s.eof = true
return c, nil
2012-02-22 08:43:24 +11:00
}
s.position.Column++
return c, nil
2012-02-22 08:36:27 +11:00
}