7 // V2 implements IndexVersion for v2 packfiles.
10 // Name implements IndexVersion.Name by returning the 20 byte SHA-1 object name
11 // for the given entry at offset "at" in the v2 index file "idx".
12 func (v *V2) Name(idx *Index, at int64) ([]byte, error) {
14 if _, err := idx.readAt(sha[:], v2ShaOffset(at)); err != nil {
21 // Entry implements IndexVersion.Entry for v2 packfiles by parsing and returning
22 // the IndexEntry specified at the offset "at" in the given index file.
23 func (v *V2) Entry(idx *Index, at int64) (*IndexEntry, error) {
25 if _, err := idx.readAt(offs[:], v2SmallOffsetOffset(at, int64(idx.Count()))); err != nil {
29 loc := uint64(binary.BigEndian.Uint32(offs[:]))
30 if loc&0x80000000 > 0 {
31 // If the most significant bit (MSB) of the offset is set, then
32 // the offset encodes the indexed location for an 8-byte offset.
34 // Mask away (offs&0x7fffffff) the MSB to use as an index to
35 // find the offset of the 8-byte pack offset.
36 lo := v2LargeOffsetOffset(int64(loc&0x7fffffff), int64(idx.Count()))
39 if _, err := idx.readAt(offs[:], lo); err != nil {
43 loc = binary.BigEndian.Uint64(offs[:])
45 return &IndexEntry{PackOffset: loc}, nil
48 // Width implements IndexVersion.Width() by returning the number of bytes that
49 // v2 packfile index header occupy.
50 func (v *V2) Width() int64 {
54 // v2ShaOffset returns the offset of a SHA1 given at "at" in the V2 index file.
55 func v2ShaOffset(at int64) int64 {
56 // Skip the packfile index header and the L1 fanout table.
57 return indexOffsetV2Start +
58 // Skip until the desired name in the sorted names table.
59 (indexObjectNameWidth * at)
62 // v2SmallOffsetOffset returns the offset of an object's small (4-byte) offset
64 func v2SmallOffsetOffset(at, total int64) int64 {
65 // Skip the packfile index header and the L1 fanout table.
66 return indexOffsetV2Start +
67 // Skip the name table.
68 (indexObjectNameWidth * total) +
69 // Skip the CRC table.
70 (indexObjectCRCWidth * total) +
71 // Skip until the desired index in the small offsets table.
72 (indexObjectSmallOffsetWidth * at)
75 // v2LargeOffsetOffset returns the offset of an object's large (4-byte) offset,
76 // given by the index "at".
77 func v2LargeOffsetOffset(at, total int64) int64 {
78 // Skip the packfile index header and the L1 fanout table.
79 return indexOffsetV2Start +
80 // Skip the name table.
81 (indexObjectNameWidth * total) +
82 // Skip the CRC table.
83 (indexObjectCRCWidth * total) +
84 // Skip the small offsets table.
85 (indexObjectSmallOffsetWidth * total) +
86 // Seek to the large offset within the large offset(s) table.
87 (indexObjectLargeOffsetWidth * at)