archiver/read.go
2024-11-01 12:34:12 -04:00

98 lines
1.9 KiB
Go

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
}