diff options
Diffstat (limited to 'format/packfile/ingest/header.go')
| -rw-r--r-- | format/packfile/ingest/header.go | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/format/packfile/ingest/header.go b/format/packfile/ingest/header.go new file mode 100644 index 00000000..6a214828 --- /dev/null +++ b/format/packfile/ingest/header.go @@ -0,0 +1,49 @@ +package ingest + +import ( + "encoding/binary" + "fmt" + "io" + + "codeberg.org/lindenii/furgit/format/packfile" +) + +const packHeaderSize = 12 + +// readAndValidatePackHeader reads one PACK header from src and validates it. +func readAndValidatePackHeader(src io.Reader) (HeaderInfo, [packHeaderSize]byte, error) { + var hdr [packHeaderSize]byte + + _, err := io.ReadFull(src, hdr[:]) + if err != nil { + return HeaderInfo{}, [packHeaderSize]byte{}, &InvalidPackHeaderError{ + Reason: fmt.Sprintf("read header: %v", err), + } + } + + header, err := parseAndValidatePackHeader(hdr) + if err != nil { + return HeaderInfo{}, [packHeaderSize]byte{}, err + } + + return header, hdr, nil +} + +// parseAndValidatePackHeader validates one already-read PACK header. +func parseAndValidatePackHeader(hdr [packHeaderSize]byte) (HeaderInfo, error) { + if binary.BigEndian.Uint32(hdr[:4]) != packfile.Signature { + return HeaderInfo{}, &InvalidPackHeaderError{Reason: "signature mismatch"} + } + + version := binary.BigEndian.Uint32(hdr[4:8]) + if !packfile.VersionSupported(version) { + return HeaderInfo{}, &InvalidPackHeaderError{ + Reason: fmt.Sprintf("unsupported version %d", version), + } + } + + return HeaderInfo{ + Version: version, + ObjectCount: binary.BigEndian.Uint32(hdr[8:12]), + }, nil +} |
