185 lines
6.2 KiB
Go
185 lines
6.2 KiB
Go
package zipper
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
type Writer interface {
|
|
Flush() error
|
|
Close() error
|
|
}
|
|
|
|
type Compressor interface {
|
|
Compress(fileToZip *os.File, pathInArchive string) (err error)
|
|
OpenWriter(zipFile *os.File) (err error)
|
|
MultiFileSupported() bool
|
|
}
|
|
|
|
// zipper defines a struct for a Zip-file writer
|
|
type zipper struct {
|
|
filename string
|
|
zipFile *os.File
|
|
zipWriter Writer
|
|
isOpen bool
|
|
compressor Compressor
|
|
canCompress bool
|
|
}
|
|
|
|
type Zipper interface {
|
|
io.Closer
|
|
AddZipFilesPathed(files []string, pathInArchive, pathInFileSystem string) error
|
|
AddZipFiles(files []string, pathInArchive string) error
|
|
AddZipFilesPathedSimple(files []string, pathInFileSystem string) error
|
|
AddZipFilesSimple(files []string) error
|
|
AddFileToZipPathed(filename, pathInArchive, pathInFileSystem string) error
|
|
AddFileToZip(filename, pathInArchive string) error
|
|
AddFileToZipPathedSimple(filename, pathInFileSystem string) error
|
|
AddFileToZipSimple(filename string) error
|
|
SetCompressor(compressor Compressor) error
|
|
SetWriter(writer Writer)
|
|
GetWriter() (writer Writer)
|
|
}
|
|
|
|
// NewBaseZipper makes a new Zipper interface missing the compressor.
|
|
func NewBaseZipper(archiveFilename string) Zipper {
|
|
return &zipper{filename: archiveFilename, isOpen: false, canCompress: true}
|
|
}
|
|
|
|
func (zipper *zipper) SetCompressor(compressor Compressor) (err error) {
|
|
if compressor != nil {
|
|
if zipper.compressor == nil {
|
|
zipper.compressor = compressor
|
|
} else {
|
|
err = fmt.Errorf("compressor already defined")
|
|
}
|
|
} else {
|
|
err = fmt.Errorf("undefined compressor")
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zipper *zipper) SetWriter(writer Writer) {
|
|
zipper.zipWriter = writer
|
|
}
|
|
|
|
func (zipper *zipper) GetWriter() Writer {
|
|
return zipper.zipWriter
|
|
}
|
|
|
|
// Close implements the Closer interface
|
|
func (zipper *zipper) Close() (err error) {
|
|
if zipper.isOpen {
|
|
if nil != zipper.zipWriter {
|
|
zipper.zipWriter.Flush()
|
|
if err = zipper.zipWriter.Close(); err == nil {
|
|
zipper.zipWriter = nil
|
|
}
|
|
}
|
|
if nil == err && nil != zipper.zipFile {
|
|
zipper.zipFile.Sync()
|
|
if err = zipper.zipFile.Close(); err == nil {
|
|
zipper.zipFile = nil
|
|
}
|
|
}
|
|
if err == nil {
|
|
zipper.isOpen = false
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// AddZipFilesPathed compresses one or many files into the current zip archive file.
|
|
// Param 1: files is a list of files to add to the zip.
|
|
// Param 2: pathInArchive is subfolder definition within the zip, where the files are to be situated.
|
|
// Param 3: pathInFileSystem is the subfolder definition within the file system, where the file may be found.
|
|
func (zipper *zipper) AddZipFilesPathed(files []string, pathInArchive, pathInFileSystem string) (err error) {
|
|
// Add files to zip
|
|
for _, file := range files {
|
|
if err = zipper.AddFileToZipPathed(file, pathInArchive, pathInFileSystem); err != nil {
|
|
break
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
// AddZipFiles compresses one or many files into the current zip archive file.
|
|
// Param 1: files is a list of files to add to the zip.
|
|
// Param 2: pathInArchive is subfolder definition within the zip, where the files are to be situated.
|
|
func (zipper *zipper) AddZipFiles(files []string, pathInArchive string) error {
|
|
return zipper.AddZipFilesPathed(files, pathInArchive, "")
|
|
}
|
|
|
|
// AddZipFilesPathedSimple compresses one or many files into the current zip archive file.
|
|
// Param 1: files is a list of files to add to the zip.
|
|
// Param 2: pathInFileSystem is the subfolder definition within the file system, where the file may be found.
|
|
func (zipper *zipper) AddZipFilesPathedSimple(files []string, pathInFileSystem string) error {
|
|
return zipper.AddZipFilesPathed(files, "", pathInFileSystem)
|
|
}
|
|
|
|
// AddZipFilesSimple compresses one or many files into the current zip archive file.
|
|
// Param: files is a list of files to add to the zip.
|
|
func (zipper *zipper) AddZipFilesSimple(files []string) error {
|
|
return zipper.AddZipFilesPathed(files, "", "")
|
|
}
|
|
|
|
// AddFileToZip compresses a single file into the current zip archive file.
|
|
// Param 1: filename reflects the path of the file to add to the zip within the file system.
|
|
// Param 2: pathInArchive is the subfolder definition within the zip, where the file is to be situated.
|
|
func (zipper *zipper) AddFileToZip(filename, pathInArchive string) error {
|
|
return zipper.AddFileToZipPathed(filename, pathInArchive, "")
|
|
}
|
|
|
|
// AddFileToZipPathedSimple compresses a single file into the current zip archive file.
|
|
// Param 1: filename reflects the path of the file to add to the zip within the file system.
|
|
// Param 2: pathInFileSystem is the subfolder definition within the file system, where the file may be found.
|
|
func (zipper *zipper) AddFileToZipPathedSimple(filename, pathInFileSystem string) error {
|
|
return zipper.AddFileToZipPathed(filename, "", pathInFileSystem)
|
|
}
|
|
|
|
// AddFileToZipSimple compresses a single file into the current zip archive file.
|
|
// Param: filename reflects the path of the file to add to the zip within the file system.
|
|
func (zipper *zipper) AddFileToZipSimple(filename string) error {
|
|
return zipper.AddFileToZipPathed(filename, "", "")
|
|
}
|
|
|
|
// AddFileToZipPathed compresses a single file into the current zip archive file.
|
|
// Param 1: filename reflects the path of the file to add to the zip within the file system.
|
|
// Param 2: pathInArchive is the subfolder definition within the zip, where the file is to be situated.
|
|
// Param 3: pathInFileSystem is the subfolder definition within the file system, where the file may be found.
|
|
func (zipper *zipper) AddFileToZipPathed(filename, pathInArchive, pathInFileSystem string) (err error) {
|
|
if zipper.compressor == nil {
|
|
return fmt.Errorf("unable to initialise compressor")
|
|
}
|
|
if !zipper.isOpen {
|
|
if err = MakeSurePathExists(zipper.filename, 0644); err == nil {
|
|
if zipper.zipFile, err = os.Create(zipper.filename); err == nil {
|
|
err = zipper.compressor.OpenWriter(zipper.zipFile)
|
|
zipper.isOpen = true
|
|
}
|
|
}
|
|
}
|
|
if nil != err {
|
|
return err
|
|
}
|
|
|
|
if !zipper.canCompress {
|
|
return fmt.Errorf("no further compression is supported")
|
|
}
|
|
|
|
var fileToZip *os.File
|
|
if fileToZip, err = os.Open(PrependPath(filename, pathInFileSystem)); err != nil {
|
|
return err
|
|
}
|
|
defer fileToZip.Close()
|
|
|
|
if err = zipper.compressor.Compress(fileToZip, pathInArchive); err == nil {
|
|
if !zipper.compressor.MultiFileSupported() {
|
|
zipper.canCompress = false
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|