diff options
| author | 2026-03-12 10:01:32 +0800 | |
|---|---|---|
| committer | 2026-03-12 10:01:32 +0800 | |
| commit | f74018c19970d11a7ba0c89e581cb9f86c0d3c14 (patch) | |
| tree | 9787292fb089641ffb9f6bc91cfb92fc97e8f833 /packfile | |
| parent | refstore: More fixes on ResolveToDetached (diff) | |
| signature | No signature | |
packfile: Split to many files
Diffstat (limited to 'packfile')
| -rw-r--r-- | packfile/doc.go | 2 | ||||
| -rw-r--r-- | packfile/entry.go | 45 | ||||
| -rw-r--r-- | packfile/entry_header.go | 52 | ||||
| -rw-r--r-- | packfile/header.go | 9 | ||||
| -rw-r--r-- | packfile/object_type.go | 16 | ||||
| -rw-r--r-- | packfile/ofs.go | 26 | ||||
| -rw-r--r-- | packfile/pack.go | 52 |
7 files changed, 105 insertions, 97 deletions
diff --git a/packfile/doc.go b/packfile/doc.go new file mode 100644 index 00000000..d656e256 --- /dev/null +++ b/packfile/doc.go @@ -0,0 +1,2 @@ +// Package packfile provides Git packfile format parsing primitives. +package packfile diff --git a/packfile/entry.go b/packfile/entry.go index 50c5e73b..158cf9ce 100644 --- a/packfile/entry.go +++ b/packfile/entry.go @@ -6,51 +6,6 @@ import ( "codeberg.org/lindenii/furgit/objecttype" ) -// EntryHeader is one parsed pack entry header prefix. -type EntryHeader struct { - // Type is the entry type tag from the first header byte. - Type objecttype.Type - // Size is the declared resulting object size. - Size int64 - // HeaderSize is the number of bytes consumed by the type/size header. - HeaderSize int -} - -// ParseEntryHeader parses one pack entry type/size header from data. -func ParseEntryHeader(data []byte) (EntryHeader, error) { - var zero EntryHeader - if len(data) == 0 { - return zero, fmt.Errorf("packfile: truncated entry header") - } - - first := data[0] - header := EntryHeader{ - Type: objecttype.Type((first >> 4) & 0x07), - Size: int64(first & 0x0f), - HeaderSize: 1, - } - - shift := uint(4) - - b := first - for b&0x80 != 0 { - if header.HeaderSize >= len(data) { - return zero, fmt.Errorf("packfile: truncated entry header") - } - - b = data[header.HeaderSize] - header.HeaderSize++ - header.Size |= int64(b&0x7f) << shift - shift += 7 - } - - if header.Size < 0 { - return zero, fmt.Errorf("packfile: negative entry size") - } - - return header, nil -} - // Entry is one parsed pack entry prefix, including any delta base reference // data that appears before the compressed payload. type Entry struct { diff --git a/packfile/entry_header.go b/packfile/entry_header.go new file mode 100644 index 00000000..b7f8e79c --- /dev/null +++ b/packfile/entry_header.go @@ -0,0 +1,52 @@ +package packfile + +import ( + "fmt" + + "codeberg.org/lindenii/furgit/objecttype" +) + +// EntryHeader is one parsed pack entry header prefix. +type EntryHeader struct { + // Type is the entry type tag from the first header byte. + Type objecttype.Type + // Size is the declared resulting object size. + Size int64 + // HeaderSize is the number of bytes consumed by the type/size header. + HeaderSize int +} + +// ParseEntryHeader parses one pack entry type/size header from data. +func ParseEntryHeader(data []byte) (EntryHeader, error) { + var zero EntryHeader + if len(data) == 0 { + return zero, fmt.Errorf("packfile: truncated entry header") + } + + first := data[0] + header := EntryHeader{ + Type: objecttype.Type((first >> 4) & 0x07), + Size: int64(first & 0x0f), + HeaderSize: 1, + } + + shift := uint(4) + + b := first + for b&0x80 != 0 { + if header.HeaderSize >= len(data) { + return zero, fmt.Errorf("packfile: truncated entry header") + } + + b = data[header.HeaderSize] + header.HeaderSize++ + header.Size |= int64(b&0x7f) << shift + shift += 7 + } + + if header.Size < 0 { + return zero, fmt.Errorf("packfile: negative entry size") + } + + return header, nil +} diff --git a/packfile/header.go b/packfile/header.go new file mode 100644 index 00000000..bc859a55 --- /dev/null +++ b/packfile/header.go @@ -0,0 +1,9 @@ +package packfile + +// Signature is the 4-byte "PACK" magic at the start of pack files. +const Signature = 0x5041434b + +// VersionSupported reports whether one pack version is supported. +func VersionSupported(version uint32) bool { + return version == 2 || version == 3 +} diff --git a/packfile/object_type.go b/packfile/object_type.go new file mode 100644 index 00000000..559222ba --- /dev/null +++ b/packfile/object_type.go @@ -0,0 +1,16 @@ +package packfile + +import "codeberg.org/lindenii/furgit/objecttype" + +// IsBaseObjectType reports whether ty is one of the four canonical object +// types encoded directly in pack entries. +func IsBaseObjectType(ty objecttype.Type) bool { + switch ty { + case objecttype.TypeCommit, objecttype.TypeTree, objecttype.TypeBlob, objecttype.TypeTag: + return true + case objecttype.TypeInvalid, objecttype.TypeFuture, objecttype.TypeOfsDelta, objecttype.TypeRefDelta: + return false + default: + return false + } +} diff --git a/packfile/ofs.go b/packfile/ofs.go new file mode 100644 index 00000000..4992a506 --- /dev/null +++ b/packfile/ofs.go @@ -0,0 +1,26 @@ +package packfile + +import "fmt" + +// ParseOfsDeltaDistance parses one ofs-delta backward distance. +func ParseOfsDeltaDistance(buf []byte) (uint64, int, error) { + if len(buf) == 0 { + return 0, 0, fmt.Errorf("packfile: malformed ofs-delta distance") + } + + b := buf[0] + dist := uint64(b & 0x7f) + + consumed := 1 + for b&0x80 != 0 { + if consumed >= len(buf) { + return 0, 0, fmt.Errorf("packfile: malformed ofs-delta distance") + } + + b = buf[consumed] + consumed++ + dist = ((dist + 1) << 7) + uint64(b&0x7f) + } + + return dist, consumed, nil +} diff --git a/packfile/pack.go b/packfile/pack.go deleted file mode 100644 index c0fb88d8..00000000 --- a/packfile/pack.go +++ /dev/null @@ -1,52 +0,0 @@ -// Package packfile provides Git packfile format parsing primitives. -package packfile - -import ( - "fmt" - - "codeberg.org/lindenii/furgit/objecttype" -) - -// Signature is the 4-byte "PACK" magic at the start of pack files. -const Signature = 0x5041434b - -// VersionSupported reports whether one pack version is supported. -func VersionSupported(version uint32) bool { - return version == 2 || version == 3 -} - -// IsBaseObjectType reports whether ty is one of the four canonical object -// types encoded directly in pack entries. -func IsBaseObjectType(ty objecttype.Type) bool { - switch ty { - case objecttype.TypeCommit, objecttype.TypeTree, objecttype.TypeBlob, objecttype.TypeTag: - return true - case objecttype.TypeInvalid, objecttype.TypeFuture, objecttype.TypeOfsDelta, objecttype.TypeRefDelta: - return false - default: - return false - } -} - -// ParseOfsDeltaDistance parses one ofs-delta backward distance. -func ParseOfsDeltaDistance(buf []byte) (uint64, int, error) { - if len(buf) == 0 { - return 0, 0, fmt.Errorf("packfile: malformed ofs-delta distance") - } - - b := buf[0] - dist := uint64(b & 0x7f) - - consumed := 1 - for b&0x80 != 0 { - if consumed >= len(buf) { - return 0, 0, fmt.Errorf("packfile: malformed ofs-delta distance") - } - - b = buf[consumed] - consumed++ - dist = ((dist + 1) << 7) + uint64(b&0x7f) - } - - return dist, consumed, nil -} |
