aboutsummaryrefslogtreecommitdiff
path: root/packfile/ingest/drain.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 /packfile/ingest/drain.go
parentcommitgraph: Move out of format/ (diff)
signatureNo signature
*: format/pack -> packfile; format/delta -> delta; delete format
Diffstat (limited to 'packfile/ingest/drain.go')
-rw-r--r--packfile/ingest/drain.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/packfile/ingest/drain.go b/packfile/ingest/drain.go
new file mode 100644
index 00000000..ce04fcb4
--- /dev/null
+++ b/packfile/ingest/drain.go
@@ -0,0 +1,68 @@
+package ingest
+
+import (
+ "fmt"
+ "io"
+
+ "codeberg.org/lindenii/furgit/internal/compress/zlib"
+ "codeberg.org/lindenii/furgit/objectheader"
+ "codeberg.org/lindenii/furgit/objectid"
+ "codeberg.org/lindenii/furgit/objecttype"
+ packfmt "codeberg.org/lindenii/furgit/packfile"
+)
+
+// drainEntryPayload inflates one entry payload from stream and returns
+// (inflatedLength, oidForBaseEntry).
+func drainEntryPayload(state *ingestState, record objectRecord) (int64, objectid.ObjectID, error) {
+ var zero objectid.ObjectID
+
+ reader, err := zlib.NewReader(state.stream)
+ if err != nil {
+ return 0, zero, &MalformedPackEntryError{Offset: record.offset, Reason: fmt.Sprintf("open zlib stream: %v", err)}
+ }
+
+ defer func() { _ = reader.Close() }()
+
+ var total int64
+
+ if packfmt.IsBaseObjectType(record.packedType) {
+ header, ok := objectheader.Encode(record.packedType, record.declaredSize)
+ if !ok {
+ return 0, zero, &MalformedPackEntryError{Offset: record.offset, Reason: "encode object header"}
+ }
+
+ hashImpl, err := state.algo.New()
+ if err != nil {
+ return 0, zero, err
+ }
+
+ _, _ = hashImpl.Write(header)
+
+ n, err := io.Copy(hashImpl, reader)
+ if err != nil {
+ return 0, zero, &MalformedPackEntryError{Offset: record.offset, Reason: fmt.Sprintf("inflate base object: %v", err)}
+ }
+
+ total = n
+
+ oid, err := objectid.FromBytes(state.algo, hashImpl.Sum(nil))
+ if err != nil {
+ return 0, zero, err
+ }
+
+ return total, oid, nil
+ }
+
+ if record.packedType == objecttype.TypeOfsDelta || record.packedType == objecttype.TypeRefDelta {
+ n, err := io.Copy(io.Discard, reader)
+ if err != nil {
+ return 0, zero, &MalformedPackEntryError{Offset: record.offset, Reason: fmt.Sprintf("inflate delta payload: %v", err)}
+ }
+
+ total = n
+
+ return total, zero, nil
+ }
+
+ return 0, zero, &MalformedPackEntryError{Offset: record.offset, Reason: "unsupported payload type"}
+}