You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

80 lines
2.0 KiB

package assets
import (
"bytes"
"compress/bzip2"
"github.com/gabriel-vasile/mimetype"
"github.com/klauspost/compress/gzip"
"github.com/ulikunitz/xz"
"io"
)
const (
notArchive = iota
gzipArchive
bzip2Archive
xzArchive
)
// gzipExtract use to extract independent gzip format stream.
func gzipExtract(a *asset) error {
a.debug("Start extracting gzip archive stream")
reader, err := gzip.NewReader(a.stream)
if err != nil {
a.error("Failed to extract gzip archive -> %v", err)
return err
}
a.stream, a.archive = reader, gzipArchive
return nil
}
// bzip2Extract use to extract independent bzip2 format stream.
func bzip2Extract(a *asset) error {
a.debug("Start extracting bzip2 archive stream")
a.stream = bzip2.NewReader(a.stream)
a.archive = bzip2Archive
return nil
}
// xzExtract use to extract independent xz format stream.
func xzExtract(a *asset) error {
a.debug("Start extracting xz archive stream")
reader, err := xz.NewReader(a.stream)
if err != nil {
a.error("Failed to extract xz archive -> %v", err)
return err
}
a.stream, a.archive = reader, xzArchive
return nil
}
// tryExtract try to extract the data stream as a compressed format, and will
// return the original data if it cannot be determined.
func (a *asset) tryExtract() error {
if a.archive != notArchive {
return nil // already extracted
}
header := bytes.NewBuffer(nil)
mime, err := mimetype.DetectReader(io.TeeReader(a.stream, header))
if err != nil {
a.error("Failed to detect data stream -> %v", err)
return err
}
a.stream = io.MultiReader(header, a.stream) // recycle reader
switch mime.String() { // extract with detected mime type
case "application/gzip":
a.debug("Data detected as gzip format")
return gzipExtract(a)
case "application/x-bzip2":
a.debug("Data detected as bzip2 format")
return bzip2Extract(a)
case "application/x-xz":
a.debug("Data detected as xz format")
return xzExtract(a)
default:
a.debug("Data detected as non-archive format -> `%s`", mime)
return nil
}
}