From ae5c818674e2c9ca950ca7a9bf93f1283e7411b7 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 8 Mar 2026 12:03:26 +0800 Subject: receivepack, format/pack/ingest: Two-stage ingestion --- format/pack/ingest/header.go | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'format/pack/ingest/header.go') diff --git a/format/pack/ingest/header.go b/format/pack/ingest/header.go index fba2b175..76d43bef 100644 --- a/format/pack/ingest/header.go +++ b/format/pack/ingest/header.go @@ -3,32 +3,47 @@ package ingest import ( "encoding/binary" "fmt" + "io" "codeberg.org/lindenii/furgit/format/pack" ) -// readAndValidatePackHeader reads and validates PACK header from the stream. -func readAndValidatePackHeader(state *ingestState) error { - var hdr [12]byte +const packHeaderSize = 12 - err := state.stream.readFull(hdr[:]) +// readAndValidatePackHeader reads one PACK header from src and validates it. +func readAndValidatePackHeader(src io.Reader) (HeaderInfo, [packHeaderSize]byte, error) { + var hdr [packHeaderSize]byte + + _, err := io.ReadFull(src, hdr[:]) + if err != nil { + return HeaderInfo{}, [packHeaderSize]byte{}, &InvalidPackHeaderError{ + Reason: fmt.Sprintf("read header: %v", err), + } + } + + header, err := parseAndValidatePackHeader(hdr) if err != nil { - return &InvalidPackHeaderError{Reason: fmt.Sprintf("read header: %v", err)} + return HeaderInfo{}, [packHeaderSize]byte{}, err } + return header, hdr, nil +} + +// parseAndValidatePackHeader validates one already-read PACK header. +func parseAndValidatePackHeader(hdr [packHeaderSize]byte) (HeaderInfo, error) { if binary.BigEndian.Uint32(hdr[:4]) != pack.Signature { - return &InvalidPackHeaderError{Reason: "signature mismatch"} + return HeaderInfo{}, &InvalidPackHeaderError{Reason: "signature mismatch"} } version := binary.BigEndian.Uint32(hdr[4:8]) if !pack.VersionSupported(version) { - return &InvalidPackHeaderError{Reason: fmt.Sprintf("unsupported version %d", version)} - } - - state.objectCountHeader = binary.BigEndian.Uint32(hdr[8:12]) - if state.objectCountHeader == 0 { - return &InvalidPackHeaderError{Reason: "zero objects"} + return HeaderInfo{}, &InvalidPackHeaderError{ + Reason: fmt.Sprintf("unsupported version %d", version), + } } - return nil + return HeaderInfo{ + Version: version, + ObjectCount: binary.BigEndian.Uint32(hdr[8:12]), + }, nil } -- cgit v1.3.1-10-gc9f91