NewReader returns a Reader for this data object. If the object has a seek index and if the provided span skips part of the object, the seek index will be used to limit the reading window of the returned reader.
(ctx context.Context, engine storage.Engine, path *storage.URI, ranges []seekindex.Range)
| 20 | // and if the provided span skips part of the object, the seek index will be used to |
| 21 | // limit the reading window of the returned reader. |
| 22 | func (o *Object) NewReader(ctx context.Context, engine storage.Engine, path *storage.URI, ranges []seekindex.Range) (*Reader, error) { |
| 23 | objectPath := o.SequenceURI(path) |
| 24 | reader, err := engine.Get(ctx, objectPath) |
| 25 | if err != nil { |
| 26 | return nil, fmt.Errorf("%s: %w", objectPath, err) |
| 27 | } |
| 28 | var r io.Reader |
| 29 | var readBytes int64 |
| 30 | if len(ranges) == 0 { |
| 31 | r = reader |
| 32 | readBytes = o.Size |
| 33 | } else { |
| 34 | readers := make([]io.Reader, 0, len(ranges)) |
| 35 | for _, rg := range ranges { |
| 36 | readers = append(readers, io.NewSectionReader(reader, rg.Offset, rg.Length)) |
| 37 | readBytes += rg.Length |
| 38 | } |
| 39 | r = io.MultiReader(readers...) |
| 40 | } |
| 41 | return &Reader{ |
| 42 | Reader: r, |
| 43 | Closer: reader, |
| 44 | TotalBytes: o.Size, |
| 45 | ReadBytes: readBytes, |
| 46 | }, nil |
| 47 | } |