mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 00:47:48 +08:00

full diff: https://github.com/moby/go-archive/compare/21f3f3385ab7...v0.1.0 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
66 lines
1.6 KiB
Go
66 lines
1.6 KiB
Go
package compression
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
)
|
|
|
|
const (
|
|
zstdMagicSkippableStart = 0x184D2A50
|
|
zstdMagicSkippableMask = 0xFFFFFFF0
|
|
)
|
|
|
|
var (
|
|
bzip2Magic = []byte{0x42, 0x5A, 0x68}
|
|
gzipMagic = []byte{0x1F, 0x8B, 0x08}
|
|
xzMagic = []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}
|
|
zstdMagic = []byte{0x28, 0xb5, 0x2f, 0xfd}
|
|
)
|
|
|
|
type matcher = func([]byte) bool
|
|
|
|
// Detect detects the compression algorithm of the source.
|
|
func Detect(source []byte) Compression {
|
|
compressionMap := map[Compression]matcher{
|
|
Bzip2: magicNumberMatcher(bzip2Magic),
|
|
Gzip: magicNumberMatcher(gzipMagic),
|
|
Xz: magicNumberMatcher(xzMagic),
|
|
Zstd: zstdMatcher(),
|
|
}
|
|
for _, compression := range []Compression{Bzip2, Gzip, Xz, Zstd} {
|
|
fn := compressionMap[compression]
|
|
if fn(source) {
|
|
return compression
|
|
}
|
|
}
|
|
return None
|
|
}
|
|
|
|
func magicNumberMatcher(m []byte) matcher {
|
|
return func(source []byte) bool {
|
|
return bytes.HasPrefix(source, m)
|
|
}
|
|
}
|
|
|
|
// zstdMatcher detects zstd compression algorithm.
|
|
// Zstandard compressed data is made of one or more frames.
|
|
// There are two frame formats defined by Zstandard: Zstandard frames and Skippable frames.
|
|
// See https://datatracker.ietf.org/doc/html/rfc8878#section-3 for more details.
|
|
func zstdMatcher() matcher {
|
|
return func(source []byte) bool {
|
|
if bytes.HasPrefix(source, zstdMagic) {
|
|
// Zstandard frame
|
|
return true
|
|
}
|
|
// skippable frame
|
|
if len(source) < 8 {
|
|
return false
|
|
}
|
|
// magic number from 0x184D2A50 to 0x184D2A5F.
|
|
if binary.LittleEndian.Uint32(source[:4])&zstdMagicSkippableMask == zstdMagicSkippableStart {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
}
|