diff options
| author | 2026-03-10 14:07:54 +0800 | |
|---|---|---|
| committer | 2026-03-10 14:07:54 +0800 | |
| commit | c2cb06aa23a1769a0d84756acccf1ac1358f61ef (patch) | |
| tree | 86d991b67542dd8e8509a74c832b749ccf948342 /packfile/ingest/entry.go | |
| parent | commitgraph: Move out of format/ (diff) | |
| signature | No signature | |
*: format/pack -> packfile; format/delta -> delta; delete format
Diffstat (limited to 'packfile/ingest/entry.go')
| -rw-r--r-- | packfile/ingest/entry.go | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/packfile/ingest/entry.go b/packfile/ingest/entry.go new file mode 100644 index 00000000..01be318d --- /dev/null +++ b/packfile/ingest/entry.go @@ -0,0 +1,92 @@ +package ingest + +import ( + "fmt" + + "codeberg.org/lindenii/furgit/objecttype" + packfmt "codeberg.org/lindenii/furgit/packfile" +) + +// scanOneEntry scans one pack entry from stream and appends one record. +func scanOneEntry(state *ingestState, startOffset uint64) (uint64, error) { + state.stream.beginEntryCRC() + + record, err := parseEntryPrefix(state, startOffset) + if err != nil { + return 0, err + } + + payloadStartConsumed := state.stream.consumed + + contentLen, oid, err := drainEntryPayload(state, record) + if err != nil { + return 0, err + } + + consumedInput := state.stream.consumed - payloadStartConsumed + + if contentLen != record.declaredSize { + return 0, &MalformedPackEntryError{ + Offset: startOffset, + Reason: fmt.Sprintf("inflated size mismatch got %d want %d", contentLen, record.declaredSize), + } + } + + endOffset := startOffset + uint64(record.headerLen) + consumedInput + if endOffset > state.stream.consumed { + return 0, &MalformedPackEntryError{ + Offset: startOffset, + Reason: fmt.Sprintf("entry end offset overflow got %d > stream %d", endOffset, state.stream.consumed), + } + } + + record.packedLen = endOffset - startOffset + + record.dataOffset = startOffset + uint64(record.headerLen) + if record.packedLen < uint64(record.headerLen) { + return 0, &MalformedPackEntryError{Offset: startOffset, Reason: "negative payload span"} + } + + crc, err := state.stream.endEntryCRC() + if err != nil { + return 0, err + } + + record.crc32 = crc + + if packfmt.IsBaseObjectType(record.packedType) { + record.objectID = oid + record.realType = record.packedType + record.resolved = true + } + + recordIdx := len(state.records) + state.records = append(state.records, record) + + state.offsetToRecord[record.offset] = recordIdx + if record.resolved { + state.objectToRecord[record.objectID] = recordIdx + } + + switch record.packedType { + case objecttype.TypeOfsDelta: + state.ofsDeltas = append(state.ofsDeltas, ofsDeltaRef{ + baseOffset: record.baseOffset, + recordIdx: recordIdx, + }) + case objecttype.TypeRefDelta: + state.refDeltas = append(state.refDeltas, refDeltaRef{ + baseObject: record.baseObject, + recordIdx: recordIdx, + }) + case objecttype.TypeInvalid, + objecttype.TypeCommit, + objecttype.TypeTree, + objecttype.TypeBlob, + objecttype.TypeTag, + objecttype.TypeFuture: + default: + } + + return endOffset, nil +} |
