79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
package gzip
|
|
|
|
import (
|
|
"compress/gzip"
|
|
"fmt"
|
|
"io"
|
|
"io/fs"
|
|
"os"
|
|
"strings"
|
|
|
|
zipper "git.sa-roci.de/oss/go_zipper"
|
|
)
|
|
|
|
const ArchiveExt = ".gz"
|
|
|
|
// NewZipper makes a new Zipper.
|
|
func NewGZipper(gzipFilename string, multiFile bool) zipper.Zipper {
|
|
if !strings.HasSuffix(strings.ToLower(gzipFilename), ArchiveExt) {
|
|
gzipFilename += ArchiveExt
|
|
}
|
|
gzipper := gZipper{
|
|
Zipper: zipper.NewBaseZipper(gzipFilename),
|
|
multiFile: multiFile,
|
|
}
|
|
gzipper.SetCompressor(&gzipper)
|
|
return gzipper
|
|
}
|
|
|
|
type gZipper struct {
|
|
zipper.Zipper
|
|
output io.Writer
|
|
multiFile bool
|
|
}
|
|
|
|
func (gz *gZipper) OpenWriter(zipFile *os.File) error {
|
|
gz.SetWriter(gzip.NewWriter(zipFile))
|
|
gz.output = zipFile
|
|
return nil
|
|
}
|
|
|
|
func (gz *gZipper) MultiFileSupported() bool {
|
|
return gz.multiFile
|
|
}
|
|
|
|
func (gz *gZipper) Compress(fileToZip *os.File, pathInArchive string) (err error) {
|
|
// Get the file information
|
|
var info fs.FileInfo
|
|
if info, err = fileToZip.Stat(); err != nil {
|
|
return err
|
|
}
|
|
|
|
filename := info.Name()
|
|
|
|
if writer, ok := gz.GetWriter().(*gzip.Writer); ok {
|
|
writer.ModTime = info.ModTime()
|
|
|
|
// Using FileInfoHeader() above only uses the basename of the file. If we want
|
|
// to preserve the folder structure we can overwrite this with the full path.
|
|
if len(pathInArchive) > 0 || strings.Contains(filename, "/") || strings.Contains(filename, "\\") {
|
|
writer.Name = zipper.PrependPath(filename, pathInArchive)
|
|
} else {
|
|
writer.Name = filename
|
|
}
|
|
|
|
if _, err = io.Copy(writer, fileToZip); err == nil {
|
|
flushErr := writer.Flush()
|
|
if err = writer.Close(); err != nil {
|
|
err = flushErr
|
|
} else {
|
|
writer.Reset(gz.output)
|
|
}
|
|
}
|
|
} else {
|
|
err = fmt.Errorf("unable to access compressor")
|
|
}
|
|
|
|
return
|
|
}
|