@@ -87,46 +87,6 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, desc o
8787 return Copy (ctx , cw , r , desc .Size , desc .Digest , opts ... )
8888}
8989
90- // WriteBlobBlind writes data without expected digest into the content store. If
91- // expected already exists, the method returns immediately and the reader will
92- // not be consumed.
93- //
94- // This is useful when the digest and size are NOT known beforehand.
95- //
96- // Copy is buffered, so no need to wrap reader in buffered io.
97- func WriteBlobBlind (ctx context.Context , cs Ingester , ref string , r io.Reader , opts ... Opt ) (digest.Digest , int64 , error ) {
98- cw , err := OpenWriter (ctx , cs , WithRef (ref ))
99- if err != nil {
100- return "" , 0 , errors .Wrap (err , "failed to open writer" )
101- }
102- defer cw .Close ()
103-
104- ws , err := cw .Status ()
105- if err != nil {
106- return "" , 0 , errors .Wrap (err , "failed to get status" )
107- }
108-
109- if ws .Offset > 0 {
110- // not needed
111- return "" , 0 , errors .New ("ws.Offset > 0 is not supported" )
112- }
113-
114- size , err := copyWithBuffer (cw , r )
115- if err != nil {
116- return "" , 0 , errors .Wrap (err , "failed to copy" )
117- }
118-
119- digest := cw .Digest ()
120-
121- if err := cw .Commit (ctx , size , digest ); err != nil {
122- if ! errdefs .IsAlreadyExists (err ) {
123- return "" , 0 , errors .Wrapf (err , "failed commit block" )
124- }
125- }
126-
127- return digest , size , err
128- }
129-
13090// OpenWriter opens a new writer for the given reference, retrying if the writer
13191// is locked until the reference is available or returns an error.
13292func OpenWriter (ctx context.Context , cs Ingester , opts ... WriterOpt ) (Writer , error ) {
@@ -209,6 +169,28 @@ func CopyReaderAt(cw Writer, ra ReaderAt, n int64) error {
209169 return err
210170}
211171
172+ // CopyReader copies to a writer from a given reader, returning
173+ // the number of bytes copied.
174+ // Note: if the writer has a non-zero offset, the total number
175+ // of bytes read may be greater than those copied if the reader
176+ // is not an io.Seeker.
177+ // This copy does not commit the writer.
178+ func CopyReader (cw Writer , r io.Reader ) (int64 , error ) {
179+ ws , err := cw .Status ()
180+ if err != nil {
181+ return 0 , errors .Wrap (err , "failed to get status" )
182+ }
183+
184+ if ws .Offset > 0 {
185+ r , err = seekReader (r , ws .Offset , 0 )
186+ if err != nil {
187+ return 0 , errors .Wrapf (err , "unable to resume write to %v" , ws .Ref )
188+ }
189+ }
190+
191+ return copyWithBuffer (cw , r )
192+ }
193+
212194// seekReader attempts to seek the reader to the given offset, either by
213195// resolving `io.Seeker`, by detecting `io.ReaderAt`, or discarding
214196// up to the given offset.
0 commit comments