func (p *packIdxParser) parseIdx() *Idx { p.idxParser.ConsumeString(PackIdxSignature) p.idxParser.ConsumeBytes([]byte{0, 0, 0, PackVersion}) var counts [256]int for i := range counts { counts[i] = int(p.idxParser.ParseIntBigEndian(4)) } //discard the fan-out values, just use the largest value, //which is the total # of objects: count := counts[255] idToEntry := make(map[string]*PackedObjectId) entries := make([]*PackedObjectId, count, count) entriesByOid := make([]*PackedObjectId, count, count) for i := 0; i < count; i++ { b := p.idxParser.ReadNBytes(20) oid, _ := objects.OidFromBytes(b) entries[i] = &PackedObjectId{ ObjectId: oid, } entriesByOid[i] = entries[i] } for i := 0; i < count; i++ { entries[i].crc32 = int64(p.idxParser.ParseIntBigEndian(4)) } for i := 0; i < count; i++ { //TODO: 8-byte #'s for some offsets for some pack files (packs > 2gb) entries[i].offset = p.idxParser.ParseIntBigEndian(4) } checksumPack := p.idxParser.ReadNBytes(20) checksumIdx := p.idxParser.ReadNBytes(20) if !p.idxParser.EOF() { util.PanicErrf("Found extraneous bytes! %x", p.idxParser.Bytes()) } //order by offset sort.Sort(packedObjectIds(entries)) for i, v := range entries { v.index = i } packChecksum, _ := objects.OidFromBytes(checksumPack) idxChecksum, _ := objects.OidFromBytes(checksumIdx) return &Idx{ entries, entriesByOid, idToEntry, &counts, int64(count), packChecksum, idxChecksum, } }
func readPackedRefDelta(bytes []byte) (delta packedDelta, oid *objects.ObjectId) { baseOidBytes := bytes[0:20] deltaBytes := bytes[20:] delta = packedDelta(deltaBytes) oid, _ = objects.OidFromBytes(baseOidBytes) return }
// ParseOidBytes reads the next objects.OidSize bytes from // the Reader and generates an ObjectId. func (p *objectIdParser) ParseOidBytes() *objects.ObjectId { b := p.Consume(objects.OidSize) oid, e := objects.OidFromBytes(b) if e != nil { util.PanicErrf("expected: hash bytes %d long", objects.OidSize) } return oid }