github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/cmn/archive/copy.go (about)

     1  // Package archive: write, read, copy, append, list primitives
     2  // across all supported formats
     3  /*
     4   * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved.
     5   */
     6  package archive
     7  
     8  import (
     9  	"archive/tar"
    10  	"archive/zip"
    11  	"io"
    12  )
    13  
    14  // copy .tar, .tar.gz, and .tar.lz4 (`src` => `tw` one file at a time)
    15  // - opens specific arch reader
    16  // - always closes it
    17  // - `tw` is the writer that can be further used to write (ie., append)
    18  func cpTar(src io.Reader, tw *tar.Writer, buf []byte) (err error) {
    19  	tr := tar.NewReader(src)
    20  	for err == nil {
    21  		var hdr *tar.Header
    22  		hdr, err = tr.Next()
    23  		if err == io.EOF {
    24  			err = nil
    25  			break
    26  		}
    27  		if err != nil {
    28  			break
    29  		}
    30  		// copy next one
    31  		csl := &io.LimitedReader{R: tr, N: hdr.Size}
    32  		if err = tw.WriteHeader(hdr); err == nil {
    33  			_, err = io.CopyBuffer(tw, csl, buf)
    34  		}
    35  	}
    36  	return err
    37  }
    38  
    39  func cpZip(src io.ReaderAt, size int64, zw *zip.Writer, buf []byte) (err error) {
    40  	var zr *zip.Reader
    41  	if zr, err = zip.NewReader(src, size); err != nil {
    42  		return
    43  	}
    44  	for _, f := range zr.File {
    45  		var (
    46  			zipr io.ReadCloser
    47  			zipw io.Writer
    48  		)
    49  		if f.FileInfo().IsDir() {
    50  			continue
    51  		}
    52  		zipr, err = f.Open()
    53  		if err != nil {
    54  			break
    55  		}
    56  		hdr := f.FileHeader
    57  		zipw, err = zw.CreateHeader(&hdr)
    58  		if err == nil {
    59  			reader := &io.LimitedReader{R: zipr, N: int64(hdr.UncompressedSize64)}
    60  			_, err = io.CopyBuffer(zipw, reader, buf)
    61  		}
    62  		zipr.Close()
    63  		if err != nil {
    64  			break
    65  		}
    66  	}
    67  	return err
    68  }