MCPcopy
hub / github.com/perkeep/perkeep / readerForOffset

Method readerForOffset

pkg/schema/filereader.go:317–397  ·  view source on GitHub ↗

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. The provided context is not used after the method re

(ctx context.Context, off int64)

Source from the content-addressed store, hash-verified

315// chunk at that offset. The caller must close the ReadCloser when done reading.
316// The provided context is not used after the method returns.
317func (fr *FileReader) readerForOffset(ctx context.Context, off int64) (io.ReadCloser, error) {
318 if debug {
319 log.Printf("(%p) readerForOffset %d + %d = %d", fr, fr.rootOff, off, fr.rootOff+off)
320 }
321 if off < 0 {
322 panic("negative offset")
323 }
324 if off >= fr.size {
325 return types.EmptyBody, nil
326 }
327 offRemain := off
328 var skipped int64
329 parts := fr.ss.Parts
330 for len(parts) > 0 && parts[0].Size <= uint64(offRemain) {
331 offRemain -= int64(parts[0].Size)
332 skipped += int64(parts[0].Size)
333 parts = parts[1:]
334 }
335 if len(parts) == 0 {
336 return types.EmptyBody, nil
337 }
338 p0 := parts[0]
339 var rsc readerutil.ReadSeekCloser
340 var err error
341 switch {
342 case p0.BlobRef.Valid() && p0.BytesRef.Valid():
343 return nil, fmt.Errorf("part illegally contained both a blobRef and bytesRef")
344 case !p0.BlobRef.Valid() && !p0.BytesRef.Valid():
345 return io.NopCloser(
346 io.LimitReader(zeroReader{},
347 int64(p0.Size-uint64(offRemain)))), nil
348 case p0.BlobRef.Valid():
349 blob, err := fr.getBlob(ctx, p0.BlobRef)
350 if err != nil {
351 return nil, err
352 }
353 byteReader, err := blob.ReadAll(ctx)
354 if err != nil {
355 return nil, err
356 }
357 rsc = struct {
358 io.ReadSeeker
359 io.Closer
360 }{
361 byteReader,
362 io.NopCloser(nil),
363 }
364 case p0.BytesRef.Valid():
365 var ss *superset
366 ss, err = fr.getSuperset(ctx, p0.BytesRef)
367 if err != nil {
368 return nil, err
369 }
370 rsc, err = ss.NewFileReader(fr.fetcher)
371 if err == nil {
372 subFR := rsc.(*FileReader)
373 subFR.parent = fr.rootReader()
374 subFR.rootOff = fr.rootOff + skipped

Callers 1

ReadAtMethod · 0.95

Calls 7

getBlobMethod · 0.95
getSupersetMethod · 0.95
NewFileReaderMethod · 0.95
rootReaderMethod · 0.95
PrintfMethod · 0.80
ReadAllMethod · 0.80
ValidMethod · 0.45

Tested by

no test coverage detected