diff --git a/README.md b/README.md index 4d5b2339..2373814c 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,15 @@ Introducing **Archiver 4.0** - a cross-platform, multi-format archive utility an ### Supported compression formats -- brotli (br) -- bzip2 (bz2) -- flate (zip) -- gzip (gz) -- lz4 -- snappy (sz) -- xz -- zstandard (zst) +- brotli (.br) +- bzip2 (.bz2) +- flate (.zip) +- gzip (.gz) +- lz4 (.lz4) +- snappy (.sz) +- xz (.xz) +- zlib (.zz) +- zstandard (.zst) ### Supported archive formats diff --git a/zlib.go b/zlib.go new file mode 100644 index 00000000..ce07890d --- /dev/null +++ b/zlib.go @@ -0,0 +1,52 @@ +package archiver + +import ( + "bytes" + "io" + "strings" + + "github.com/klauspost/compress/zlib" +) + +func init() { + RegisterFormat(Zlib{}) +} + +// Zlib facilitates zlib compression. +type Zlib struct { + CompressionLevel int +} + +func (Zlib) Name() string { return ".zz" } + +func (zz Zlib) Match(filename string, stream io.Reader) (MatchResult, error) { + var mr MatchResult + + // match filename + if strings.Contains(strings.ToLower(filename), zz.Name()) { + mr.ByName = true + } + + // match file header + buf, err := readAtMost(stream, len(ZlibHeader)) + if err != nil { + return mr, err + } + mr.ByStream = bytes.Equal(buf, ZlibHeader) + + return mr, nil +} + +func (zz Zlib) OpenWriter(w io.Writer) (io.WriteCloser, error) { + level := zz.CompressionLevel + if level == 0 { + level = zlib.DefaultCompression + } + return zlib.NewWriterLevel(w, level) +} + +func (Zlib) OpenReader(r io.Reader) (io.ReadCloser, error) { + return zlib.NewReader(r) +} + +var ZlibHeader = []byte{0x78}