aboutsummaryrefslogtreecommitdiff
path: root/internal/format/packfile/header.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/format/packfile/header.go')
-rw-r--r--internal/format/packfile/header.go63
1 files changed, 63 insertions, 0 deletions
diff --git a/internal/format/packfile/header.go b/internal/format/packfile/header.go
new file mode 100644
index 00000000..64c7d140
--- /dev/null
+++ b/internal/format/packfile/header.go
@@ -0,0 +1,63 @@
+package packfile
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+)
+
+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
+}