// package asciiscan is used to parse plaintext files into structured data package asciiscan import ( "bufio" "bytes" "io" "os" "strconv" ) var hashComment = []byte("#") type Scanner struct { bufio *bufio.Scanner closer io.Closer } func New(filename string) (*Scanner, error) { f, err := os.Open(filename) if err != nil { return nil, err } return &Scanner{ bufio: bufio.NewScanner(f), closer: f, }, nil } func (s *Scanner) Bufio() *bufio.Scanner { return s.bufio } func (s *Scanner) Close() error { return s.closer.Close() } func (s *Scanner) ConsumeString() (string, error) { for s.bufio.Scan() { line := s.bufio.Bytes() if len(line) == 0 || line[0] == hashComment[0] { // Most .dat files use # for comments continue } comment := bytes.Index(line, hashComment) if comment > 0 { line = line[0:comment] } return string(bytes.TrimRight(line, "\r\n\t ")), nil } err := s.bufio.Err() if err == nil { return "", io.EOF } return "", err } func (s *Scanner) ConsumeInt() (int, error) { str, err := s.ConsumeString() if err != nil { return 0, err } return strconv.Atoi(str) } func (s *Scanner) ConsumeIntPtr(to *int) error { val, err := s.ConsumeInt() if err != nil { return err } *to = val return nil } func (s *Scanner) ConsumeIntPtrs(ptrs ...*int) error { for _, ptr := range ptrs { if err := s.ConsumeIntPtr(ptr); err != nil { return err } } return nil }