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)
| 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. |
| 317 | func (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 |
no test coverage detected