package zipper import ( "fmt" "io" "os" ) // unzipper defines a struct for a Zip-file writer type unzipper struct { filename string zipFile *os.File zipReader io.Closer isOpen bool decompressor Decompressor } type Decompressor interface { Decompress(targetFolderPathInFileSystem string) (err error) OpenReader(zipFile *os.File) (err error) } type Unzipper interface { io.Closer ExtractFiles(targetFolderPathInFileSystem string) error SetDecompressor(decompressor Decompressor) error SetReader(reader io.Closer) GetReader() (reader io.Closer) } // NewBaseUnzipper makes a new Unzipper interface missing the decompressor. func NewBaseUnzipper(archiveFilename string) Unzipper { return &unzipper{filename: archiveFilename, isOpen: false} } func (unzipper *unzipper) SetDecompressor(decompressor Decompressor) (err error) { if decompressor != nil { if unzipper.decompressor == nil { unzipper.decompressor = decompressor } else { err = fmt.Errorf("decompressor already defined") } } else { err = fmt.Errorf("undefined decompressor") } return } func (unzipper *unzipper) SetReader(reader io.Closer) { unzipper.zipReader = reader } func (unzipper *unzipper) GetReader() io.Closer { return unzipper.zipReader } // Close implements the Closer interface func (unzipper *unzipper) Close() (err error) { if unzipper.isOpen { if nil != unzipper.zipReader { if err = unzipper.zipReader.Close(); err == nil { unzipper.zipReader = nil } } if nil == err && nil != unzipper.zipFile { if err = unzipper.zipFile.Close(); err == nil { unzipper.zipFile = nil } } if err == nil { unzipper.isOpen = false } } return } func (unzipper *unzipper) ExtractFiles(targetFolderPathInFileSystem string) (err error) { if unzipper.decompressor == nil { return fmt.Errorf("unable to initialise decompressor") } if !unzipper.isOpen { if unzipper.zipFile, err = os.Open(unzipper.filename); err == nil { err = unzipper.decompressor.OpenReader(unzipper.zipFile) unzipper.isOpen = true defer func() { errClose := unzipper.Close() if err == nil { err = errClose } }() } } if err == nil { err = unzipper.decompressor.Decompress(targetFolderPathInFileSystem) } return err }