package archiver import ( "archive/tar" "archive/zip" "bytes" "compress/bzip2" "compress/gzip" "github.com/ulikunitz/xz" "io" ) func zipRead(file *File) ([]byte, error) { isFound := false var fileBuffer bytes.Buffer for _, zipF := range file.archive.reader.(*zip.Reader).File { if file.Path != zipF.Name { continue } isFound = true archiveFile, err := zipF.Open() if err != nil { return nil, err } defer archiveFile.Close() if _, err := io.Copy(&fileBuffer, archiveFile); err != nil { return nil, err } break } if !isFound { return nil, ErrArchiveFileNotFound } return fileBuffer.Bytes(), nil } func tarRead(file *File) ([]byte, error) { defer tarCleanup(file.archive) var fileBuffer bytes.Buffer isFound := false for { header, err := file.archive.tarReader.Next() if err != nil && err != io.EOF { return nil, err } else if err == io.EOF { break } if file.Path != header.Name { continue } isFound = true if _, err := io.Copy(&fileBuffer, file.archive.tarReader); err != nil { return nil, err } break } if !isFound { return nil, ErrArchiveFileNotFound } return fileBuffer.Bytes(), nil } func tarCleanup(archive *Archive) error { if _, err := archive.archiveFile.Seek(0, io.SeekStart); err != nil { return err } switch archive.Type { case TarGzip: err := archive.reader.(*gzip.Reader).Reset(archive.archiveFile) if err != nil { return err } archive.tarReader = tar.NewReader(archive.reader.(*gzip.Reader)) case TarBzip: archive.reader = bzip2.NewReader(archive.archiveFile) archive.tarReader = tar.NewReader(archive.reader.(io.Reader)) case TarXz: var err error archive.reader, err = xz.NewReader(archive.archiveFile) if err != nil { return err } archive.tarReader = tar.NewReader(archive.reader.(*xz.Reader)) case Tar: archive.tarReader = tar.NewReader(archive.reader.(*bytes.Reader)) } return nil }