diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-01-28 14:52:35 -0700 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-01-28 15:01:41 -0700 |
commit | 66a1b1f39a1e1d5499b548b36d18c8daa872d7da (patch) | |
tree | 96471dbd5486ede1a908790ac23e0c55b226dfad /gopher/gophermap/parse.go | |
parent | a27b879accb191b6a6c6e76a6251ed751967f73a (diff) |
gopher support.
Some of the contrib packages were originally built gemini-specific and
had to be refactored into generic core functionality and thin
protocol-specific wrappers for each of gemini and gopher.
Diffstat (limited to 'gopher/gophermap/parse.go')
-rw-r--r-- | gopher/gophermap/parse.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/gopher/gophermap/parse.go b/gopher/gophermap/parse.go new file mode 100644 index 0000000..302aef0 --- /dev/null +++ b/gopher/gophermap/parse.go @@ -0,0 +1,61 @@ +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) +} |