aboutsummaryrefslogtreecommitdiff
path: root/delta/apply/header.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-10 14:07:54 +0800
committerGravatar Runxi Yu2026-03-10 14:07:54 +0800
commitc2cb06aa23a1769a0d84756acccf1ac1358f61ef (patch)
tree86d991b67542dd8e8509a74c832b749ccf948342 /delta/apply/header.go
parentcommitgraph: Move out of format/ (diff)
signatureNo signature
*: format/pack -> packfile; format/delta -> delta; delete format
Diffstat (limited to 'delta/apply/header.go')
-rw-r--r--delta/apply/header.go47
1 files changed, 47 insertions, 0 deletions
diff --git a/delta/apply/header.go b/delta/apply/header.go
new file mode 100644
index 00000000..69c9659a
--- /dev/null
+++ b/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")
+ }
+ }
+}