// readerForOffset returns a ReadCloser that reads some number of bytes and then EOF // from the provided offset. Seeing EOF doesn't mean the end of the whole file; just the // chunk at that offset. The caller must close the ReadCloser when done reading. func (fr *FileReader) readerForOffset(off int64) (io.ReadCloser, error) { if off < 0 { panic("negative offset") } if off >= fr.size { return eofReader, nil } offRemain := off parts := fr.ss.Parts for len(parts) > 0 && parts[0].Size <= uint64(offRemain) { offRemain -= int64(parts[0].Size) parts = parts[1:] } if len(parts) == 0 { return eofReader, nil } p0 := parts[0] var rsc blobref.ReadSeekCloser var err error switch { case p0.BlobRef != nil && p0.BytesRef != nil: return nil, fmt.Errorf("part illegally contained both a blobRef and bytesRef") case p0.BlobRef == nil && p0.BytesRef == nil: return &nZeros{int(p0.Size - uint64(offRemain))}, nil case p0.BlobRef != nil: rsc, _, err = fr.fetcher.Fetch(p0.BlobRef) case p0.BytesRef != nil: rsc, err = NewFileReader(fr.fetcher, p0.BytesRef) } if err != nil { return nil, err } offRemain += int64(p0.Offset) if offRemain > 0 { newPos, err := rsc.Seek(offRemain, os.SEEK_SET) if err != nil { return nil, err } if newPos != offRemain { panic("Seek didn't work") } } return struct { io.Reader io.Closer }{ io.LimitReader(rsc, int64(p0.Size)), rsc, }, nil }
func (fr *FileReader) readerFor(br *blobref.BlobRef, seekTo int64) (r io.Reader, err error) { if fr.crbr == br { return fr.cr, nil } fr.closeOpenBlobs() var rsc blobref.ReadSeekCloser if br != nil { rsc, _, err = fr.fetcher.Fetch(br) if err != nil { return } _, serr := rsc.Seek(int64(seekTo), os.SEEK_SET) if serr != nil { return nil, fmt.Errorf("schema: FileReader.Read seek error on blob %s: %v", br, serr) } } else { rsc = &zeroReader{} } fr.crbr = br fr.cr = rsc return rsc, nil }
// readerForOffset returns a ReadCloser that reads some number of bytes and then EOF // from the provided offset. Seeing EOF doesn't mean the end of the whole file; just the // chunk at that offset. The caller must close the ReadCloser when done reading. func (fr *FileReader) readerForOffset(off int64) (io.ReadCloser, error) { if debug { log.Printf("(%p) readerForOffset %d + %d = %d", fr, fr.rootOff, off, fr.rootOff+off) } if off < 0 { panic("negative offset") } if off >= fr.size { return eofReader, nil } offRemain := off var skipped int64 parts := fr.ss.Parts for len(parts) > 0 && parts[0].Size <= uint64(offRemain) { offRemain -= int64(parts[0].Size) skipped += int64(parts[0].Size) parts = parts[1:] } if len(parts) == 0 { return eofReader, nil } p0 := parts[0] var rsc blobref.ReadSeekCloser var err error switch { case p0.BlobRef != nil && p0.BytesRef != nil: return nil, fmt.Errorf("part illegally contained both a blobRef and bytesRef") case p0.BlobRef == nil && p0.BytesRef == nil: return &nZeros{int(p0.Size - uint64(offRemain))}, nil case p0.BlobRef != nil: rsc, _, err = fr.fetcher.Fetch(p0.BlobRef) case p0.BytesRef != nil: var ss *Superset ss, err = fr.getSuperset(p0.BytesRef) if err != nil { return nil, err } rsc, err = ss.NewFileReader(fr.fetcher) if err == nil { subFR := rsc.(*FileReader) subFR.parent = fr.rootReader() subFR.rootOff = fr.rootOff + skipped } } if err != nil { return nil, err } offRemain += int64(p0.Offset) if offRemain > 0 { newPos, err := rsc.Seek(offRemain, os.SEEK_SET) if err != nil { return nil, err } if newPos != offRemain { panic("Seek didn't work") } } return struct { io.Reader io.Closer }{ io.LimitReader(rsc, int64(p0.Size)), rsc, }, nil }