github.com/nikkelma/oras-project_oras-go@v1.1.1-0.20220201001104-a75f6a419090/pkg/oras/provider.go (about) 1 /* 2 Copyright The ORAS Authors. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 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 // ProviderWrapper wraps a remote.Fetcher to make a content.Provider, which is useful for things 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 // if we do not have a readcloser, get it 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 = f.rc.Read(p) 74 if err != nil { 75 return n, err 76 } 77 f.offset += int64(n) 78 return n, err 79 }