mfer/mfer/deserialize.go

82 lines
1.5 KiB
Go

package mfer
import (
"bytes"
"compress/gzip"
"errors"
"io"
"git.eeqj.de/sneak/mfer/internal/bork"
"git.eeqj.de/sneak/mfer/internal/log"
"google.golang.org/protobuf/proto"
)
func (m *manifest) validateProto() error {
if m.pbOuter.Version != MFFileOuter_VERSION_ONE {
return errors.New("unknown version")
}
if m.pbOuter.CompressionType != MFFileOuter_COMPRESSION_GZIP {
return errors.New("unknown compression type")
}
bb := bytes.NewBuffer(m.pbOuter.InnerMessage)
gzr, err := gzip.NewReader(bb)
if err != nil {
return err
}
dat, err := io.ReadAll(gzr)
defer gzr.Close()
if err != nil {
return err
}
isize := len(dat)
if int64(isize) != m.pbOuter.Size {
log.Debugf("truncated data, got %d expected %d", isize, m.pbOuter.Size)
return bork.ErrFileTruncated
}
log.Dump(dat)
log.Dump(m.pbOuter.Sha256)
return nil
}
func NewFromProto(input io.Reader) (*manifest, error) {
m := New()
dat, err := io.ReadAll(input)
if err != nil {
return nil, err
}
ml := len([]byte(MAGIC))
bb := bytes.NewBuffer(dat)
got := dat[0:ml]
log.Dump("got:")
log.Dump(got)
expected := []byte(MAGIC)
log.Dump("expected:")
log.Dump(expected)
if !bytes.Equal(got, expected) {
return nil, errors.New("invalid file format")
}
bb = bytes.NewBuffer(dat[ml:])
dat = bb.Bytes()
log.Dump(dat)
m.pbOuter = new(MFFileOuter)
err = proto.Unmarshal(dat, m.pbOuter)
if err != nil {
return nil, err
}
ve := m.validateProto()
if ve != nil {
return nil, ve
}
return m, nil
}