diff options
Diffstat (limited to 'internal/format/packfile/header.go')
| -rw-r--r-- | internal/format/packfile/header.go | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/internal/format/packfile/header.go b/internal/format/packfile/header.go index 1a156f36..64c7d140 100644 --- a/internal/format/packfile/header.go +++ b/internal/format/packfile/header.go @@ -1,9 +1,63 @@ package packfile -// Signature is the 4-byte "PACK" magic at the start of pack files. -const Signature = 0x5041434b +import ( + "encoding/binary" + "errors" + "fmt" +) -// SupportedVersion reports whether a pack version is supported. -func SupportedVersion(version uint32) bool { - return version == 2 +const ( + // signature is the 4-byte "PACK" magic at the start of pack files. + signature = 0x5041434b + + // version is the only pack version this package reads or writes. + version = 2 +) + +// HeaderLen is the size of a pack header: +// signature, version, and object count. +const HeaderLen = 12 + +// ErrMalformedHeader reports that +// a pack header is truncated, +// or has a bad signature or unsupported version. +var ErrMalformedHeader = errors.New("internal/format/packfile: malformed pack header") + +// Header is one parsed pack header. +type Header struct { + // ObjectCount is the number of object entries + // declared to follow the header. + ObjectCount uint32 +} + +// ParseHeader parses and validates the pack header +// at the start of data. +func ParseHeader(data []byte) (Header, error) { + var zero Header + + if len(data) < HeaderLen { + return zero, fmt.Errorf("%w: truncated", ErrMalformedHeader) + } + + if binary.BigEndian.Uint32(data[0:4]) != signature { + return zero, fmt.Errorf("%w: bad signature", ErrMalformedHeader) + } + + parsedVersion := binary.BigEndian.Uint32(data[4:8]) + if parsedVersion != version { + return zero, fmt.Errorf("%w: unsupported version %d", ErrMalformedHeader, parsedVersion) + } + + return Header{ + ObjectCount: binary.BigEndian.Uint32(data[8:12]), + }, nil +} + +// AppendHeader appends an encoded pack header for objectCount to dst. +func AppendHeader(dst []byte, objectCount uint32) []byte { + dst = binary.BigEndian.AppendUint32(dst, signature) + dst = binary.BigEndian.AppendUint32(dst, version) + dst = binary.BigEndian.AppendUint32(dst, objectCount) + + return dst } |
