You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys/internal/testkit/format3.go

76 lines
2.3 KiB

package testkit
import (
"crypto/sha256"
"io"
"g.activething.com/go/DateKeys/capsule"
)
// DiscardSink is a capsule.Sink that discards the files.
type DiscardSink struct{}
func (DiscardSink) Begin(*capsule.Head) error { return nil }
func (DiscardSink) Create(int) (io.WriteCloser, error) { return nopCloser{io.Discard}, nil }
func (DiscardSink) Commit() error { return nil }
func (DiscardSink) Abort() {}
type nopCloser struct{ io.Writer }
func (nopCloser) Close() error { return nil }
// MemorySink is a capsule.Sink that keeps the files in memory.
type MemorySink struct {
Head *capsule.Head
Files [][]byte
Committed bool
Aborted bool
}
func (s *MemorySink) Begin(h *capsule.Head) error {
s.Head, s.Files = h, make([][]byte, len(h.Files))
return nil
}
func (s *MemorySink) Create(i int) (io.WriteCloser, error) { return &memoryFile{s, i}, nil }
func (s *MemorySink) Commit() error { s.Committed = true; return nil }
func (s *MemorySink) Abort() { s.Aborted = true }
type memoryFile struct {
s *MemorySink
i int
}
func (f *memoryFile) Write(b []byte) (int, error) {
f.s.Files[f.i] = append(f.s.Files[f.i], b...)
return len(b), nil
}
func (f *memoryFile) Close() error { return nil }
// Head3 returns the head of the given files, laid out one after another in
// the order given, with their SHA-256, no mtime and a zero salt.
func Head3(comment, author string, paths []string, contents [][]byte) *capsule.Head {
h := &capsule.Head{Comment: comment, Author: author}
var end uint64
for i, p := range paths {
n := uint64(len(contents[i]))
h.Files = append(h.Files, capsule.File{Path: p, Size: n, Start: end, End: end + n, SHA256: sha256.Sum256(contents[i])})
end += n
}
return h
}
// Body3 assembles the BODY of a format 3 capsule (spec §29.2): the frame,
// security in an area of areaLen bytes, the head and the files.
func Body3(areaLen uint32, security, head []byte, contents ...[]byte) []byte {
frame := capsule.BodyFrame{AreaLen: areaLen, SecurityLen: uint32(len(security)), HeadLen: uint32(len(head))}.Bytes()
body := append(frame[:], security...)
body = append(body, make([]byte, int(areaLen)-len(security))...)
body = append(body, head...)
for _, c := range contents {
body = append(body, c...)
}
return body
}

Powered by TurnKey Linux.