...

Source file src/oras.land/oras-go/pkg/content/gunzip.go

Documentation: oras.land/oras-go/pkg/content

     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  
    16  package content
    17  
    18  import (
    19  	"compress/gzip"
    20  	"fmt"
    21  	"io"
    22  
    23  	"github.com/containerd/containerd/content"
    24  )
    25  
    26  // NewGunzipWriter wrap a writer with a gunzip, so that the stream is gunzipped
    27  //
    28  // By default, it calculates the hash when writing. If the option `skipHash` is true,
    29  // it will skip doing the hash. Skipping the hash is intended to be used only
    30  // if you are confident about the validity of the data being passed to the writer,
    31  // and wish to save on the hashing time.
    32  func NewGunzipWriter(writer content.Writer, opts ...WriterOpt) content.Writer {
    33  	// process opts for default
    34  	wOpts := DefaultWriterOpts()
    35  	for _, opt := range opts {
    36  		if err := opt(&wOpts); err != nil {
    37  			return nil
    38  		}
    39  	}
    40  	return NewPassthroughWriter(writer, func(r io.Reader, w io.Writer, done chan<- error) {
    41  		gr, err := gzip.NewReader(r)
    42  		if err != nil {
    43  			done <- fmt.Errorf("error creating gzip reader: %v", err)
    44  			return
    45  		}
    46  		// write out the uncompressed data
    47  		b := make([]byte, wOpts.Blocksize, wOpts.Blocksize)
    48  		for {
    49  			var n int
    50  			n, err = gr.Read(b)
    51  			if err != nil && err != io.EOF {
    52  				err = fmt.Errorf("GunzipWriter data read error: %v\n", err)
    53  				break
    54  			}
    55  			l := n
    56  			if n > len(b) {
    57  				l = len(b)
    58  			}
    59  			if _, err2 := w.Write(b[:l]); err2 != nil {
    60  				err = fmt.Errorf("GunzipWriter: error writing to underlying writer: %v", err2)
    61  				break
    62  			}
    63  			if err == io.EOF {
    64  				// clear the error
    65  				err = nil
    66  				break
    67  			}
    68  		}
    69  		gr.Close()
    70  		done <- err
    71  	}, opts...)
    72  }
    73  

View as plain text