package ingest import ( "fmt" objecttype "codeberg.org/lindenii/furgit/object/type" packfmt "codeberg.org/lindenii/furgit/format/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 }