aboutsummaryrefslogtreecommitdiff
path: root/format/packfile/delta/apply/header.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-26 09:17:14 +0000
committerGravatar Runxi Yu2026-03-26 09:18:30 +0000
commit3e884f5f3d42cbc4874a04da31dde10314b0cfad (patch)
treef5e1e325fd1a2a0801791c054010213214475d80 /format/packfile/delta/apply/header.go
parentnetwork/receivepack: Rename from receivepack (diff)
signatureNo signature
format: Move commitgraph and packfile here
Diffstat (limited to 'format/packfile/delta/apply/header.go')
-rw-r--r--format/packfile/delta/apply/header.go47
1 files changed, 47 insertions, 0 deletions
diff --git a/format/packfile/delta/apply/header.go b/format/packfile/delta/apply/header.go
new file mode 100644
index 00000000..69c9659a
--- /dev/null
+++ b/format/packfile/delta/apply/header.go
@@ -0,0 +1,47 @@
+package apply
+
+import (
+ "fmt"
+ "io"
+)
+
+// ReadHeaderSizes reads the first two varints in one inflated delta stream.
+//
+// Callers that continue reading the same stream should pass their own buffered
+// byte reader and keep using that same reader afterwards.
+func ReadHeaderSizes(reader io.ByteReader) (int, int, error) {
+ srcSize, err := readVarintFromByteReader(reader)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ dstSize, err := readVarintFromByteReader(reader)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ return srcSize, dstSize, nil
+}
+
+// readVarintFromByteReader parses one Git delta varint from reader.
+func readVarintFromByteReader(reader io.ByteReader) (int, error) {
+ value := 0
+ shift := uint(0)
+
+ for {
+ b, err := reader.ReadByte()
+ if err != nil {
+ return 0, fmt.Errorf("delta/apply: malformed delta varint: %w", err)
+ }
+
+ value |= int(b&0x7f) << shift
+ if b&0x80 == 0 {
+ return value, nil
+ }
+
+ shift += 7
+ if shift > 63 {
+ return 0, fmt.Errorf("delta/apply: delta varint overflow")
+ }
+ }
+}