func readCompressed(r *io.SectionReader, offset int64, s []byte) (int, error) { zr, err := zlib.NewReader(io.NewSectionReader(r, offset, r.Size()-offset)) if err != nil { return 0, err } return io.ReadFull(zr, s) }
func nextAtom(sr *io.SectionReader) (string, *io.SectionReader, error) { var asz uint32 var sz int64 atyp := make([]byte, 4) if err := binary.Read(sr, binary.BigEndian, &asz); err != nil { return "", nil, err } if asz == 0 { // Size is entire section sz = sr.Size() } else if asz == 1 { return "", nil, ErrNotImplemented } else { sz = int64(asz) } if _, err := io.ReadFull(sr, atyp); err != nil { return "", nil, err } sz = sz - 8 // 4 bytes for size, 4 bytes for type // Get current offset cur, err := seekCur(sr) if err != nil { return "", nil, err } // Consume remainder of parent if _, err := io.CopyN(ioutil.Discard, sr, sz); err != nil { return "", nil, err } return string(atyp), io.NewSectionReader(sr, cur, sz), nil }
// hashCore hashes a SectionReader using the ImoHash parameters. func (imo *ImoHash) hashCore(f *io.SectionReader) [Size]byte { var result [Size]byte imo.hasher.Reset() if f.Size() < int64(imo.sampleThreshold) || imo.sampleSize < 1 { buffer := make([]byte, f.Size()) f.Read(buffer) imo.hasher.Write(buffer) } else { buffer := make([]byte, imo.sampleSize) f.Read(buffer) imo.hasher.Write(buffer) f.Seek(f.Size()/2, 0) f.Read(buffer) imo.hasher.Write(buffer) f.Seek(int64(-imo.sampleSize), 2) f.Read(buffer) imo.hasher.Write(buffer) } hash := imo.hasher.Sum(nil) binary.PutUvarint(hash, uint64(f.Size())) copy(result[:], hash) return result }