aboutsummaryrefslogtreecommitdiff
path: root/format/pack/entry.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-02-21 18:52:58 +0800
committerGravatar Runxi Yu2026-02-21 18:52:58 +0800
commitffd8a66b3a1dcf16c574af736b3582b0611d288e (patch)
treec8f67c1a8ba04140640dd2fa4715537eb94db062 /format/pack/entry.go
parentformat/delta/apply: Move core delta apply algorithm here (diff)
signatureNo signature
format/pack: Extract general constants and such from objectstore/packed
Diffstat (limited to 'format/pack/entry.go')
-rw-r--r--format/pack/entry.go48
1 files changed, 48 insertions, 0 deletions
diff --git a/format/pack/entry.go b/format/pack/entry.go
new file mode 100644
index 00000000..512b45f8
--- /dev/null
+++ b/format/pack/entry.go
@@ -0,0 +1,48 @@
+package pack
+
+import (
+ "fmt"
+
+ "codeberg.org/lindenii/furgit/objecttype"
+)
+
+// EntryHeader is one parsed pack entry header prefix.
+type EntryHeader struct {
+ // Type is the entry type tag from the first header byte.
+ Type objecttype.Type
+ // Size is the declared resulting object size.
+ Size int64
+ // HeaderSize is the number of bytes consumed by the type/size header.
+ HeaderSize int
+}
+
+// ParseEntryHeader parses one pack entry type/size header from data.
+func ParseEntryHeader(data []byte) (EntryHeader, error) {
+ var zero EntryHeader
+ if len(data) == 0 {
+ return zero, fmt.Errorf("format/pack: truncated entry header")
+ }
+
+ first := data[0]
+ header := EntryHeader{
+ Type: objecttype.Type((first >> 4) & 0x07),
+ Size: int64(first & 0x0f),
+ HeaderSize: 1,
+ }
+
+ shift := uint(4)
+ b := first
+ for b&0x80 != 0 {
+ if header.HeaderSize >= len(data) {
+ return zero, fmt.Errorf("format/pack: truncated entry header")
+ }
+ b = data[header.HeaderSize]
+ header.HeaderSize++
+ header.Size |= int64(b&0x7f) << shift
+ shift += 7
+ }
+ if header.Size < 0 {
+ return zero, fmt.Errorf("format/pack: negative entry size")
+ }
+ return header, nil
+}