This repository has been archived on 2023-05-01. You can view files and clone it, but cannot push or open issues or pull requests.
gus/gopher/gophermap/parse.go

62 lines
1.2 KiB
Go

package gophermap
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"tildegit.org/tjp/gus"
"tildegit.org/tjp/gus/gopher"
)
// Parse reads a gophermap document from a reader.
func Parse(input io.Reader) (gopher.MapDocument, error) {
rdr := bufio.NewReader(input)
doc := gopher.MapDocument{}
num := 0
for {
num += 1
line, err := rdr.ReadBytes('\n')
isEOF := errors.Is(err, io.EOF)
if err != nil && !isEOF {
return nil, err
}
if len(line) > 2 && !bytes.Equal(line, []byte(".\r\n")) {
if line[len(line)-2] != '\r' || line[len(line)-1] != '\n' {
return nil, InvalidLine(num)
}
item := gopher.MapItem{Type: gus.Status(line[0])}
spl := bytes.Split(line[1:len(line)-2], []byte{'\t'})
if len(spl) != 4 {
return nil, InvalidLine(num)
}
item.Display = string(spl[0])
item.Selector = string(spl[1])
item.Hostname = string(spl[2])
item.Port = string(spl[3])
doc = append(doc, item)
}
if isEOF {
break
}
}
return doc, nil
}
// InvalidLine is returned from Parse when the reader contains a line which is invalid gophermap.
type InvalidLine int
// Error implements the error interface.
func (il InvalidLine) Error() string {
return fmt.Sprintf("Invalid gophermap on line %d.", il)
}