...
1
15 package oras
16
17 import (
18 "context"
19 "errors"
20 "io"
21
22 "github.com/containerd/containerd/content"
23 "github.com/containerd/containerd/remotes"
24 ocispec "github.com/opencontainers/image-spec/specs-go/v1"
25 )
26
27
28 type ProviderWrapper struct {
29 Fetcher remotes.Fetcher
30 }
31
32 func (p *ProviderWrapper) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
33 if p.Fetcher == nil {
34 return nil, errors.New("no Fetcher provided")
35 }
36 return &fetcherReaderAt{
37 ctx: ctx,
38 fetcher: p.Fetcher,
39 desc: desc,
40 offset: 0,
41 }, nil
42 }
43
44 type fetcherReaderAt struct {
45 ctx context.Context
46 fetcher remotes.Fetcher
47 desc ocispec.Descriptor
48 rc io.ReadCloser
49 offset int64
50 }
51
52 func (f *fetcherReaderAt) Close() error {
53 if f.rc == nil {
54 return nil
55 }
56 return f.rc.Close()
57 }
58
59 func (f *fetcherReaderAt) Size() int64 {
60 return f.desc.Size
61 }
62
63 func (f *fetcherReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
64
65 if f.rc == nil || f.offset != off {
66 rc, err := f.fetcher.Fetch(f.ctx, f.desc)
67 if err != nil {
68 return 0, err
69 }
70 f.rc = rc
71 }
72
73 n, err = io.ReadFull(f.rc, p)
74 if err != nil {
75 return n, err
76 }
77 f.offset += int64(n)
78 return n, err
79 }
80
View as plain text