package zhead import ( "bufio" "bytes" "encoding/hex" "errors" "io" "strconv" "strings" "text/template" "time" ) const header = `{{define "header" -}} date={{.Date.Format "2006-01-02T15:04:05Z07:00"}} key={{.KeyFile}} algorithm={{.Alg}} bocksize={{.BlockSize}} {{range .Sums}}{{printf "%x" .}} {{end}}{{end}}` type Header struct { Date time.Time KeyFile string Alg string BlockSize int Sums [][]byte } const ( DefaultAlg = "SHA512/256" DefaultBlockSize = 65535 ) func (h Header) Print() ([]byte, error) { t, err := template.New("header").Parse(header) if err != nil { return nil, err } buf := new(bytes.Buffer) err = t.ExecuteTemplate(buf, "header", h) return buf.Bytes(), err } func Parse(r io.Reader) (Header, error) { var inSum bool var h Header scanner := bufio.NewScanner(r) for scanner.Scan() { line := scanner.Text() switch { case strings.HasPrefix(line, "date="): t, err := time.Parse(time.RFC3339, line[5:]) if err != nil { return Header{}, err } h.Date = t case strings.HasPrefix(line, "key="): h.KeyFile = line[4:] case strings.HasPrefix(line, "algorithm="): h.Alg = line[10:] case strings.HasPrefix(line, "blocksize="): i, err := strconv.Atoi(line[9:]) if err != nil { return Header{}, err } h.BlockSize = i case line == "": if inSum { return Header{}, errors.New("already in sum part") } inSum = true } if inSum { sum, err := hex.DecodeString(line) if err != nil { return Header{}, err } h.Sums = append(h.Sums, sum) } } return h, scanner.Err() }