1package archiver
2
3import (
4	"fmt"
5	"io"
6	"path/filepath"
7
8	"github.com/dsnet/compress/bzip2"
9)
10
11// Bz2 facilitates bzip2 compression.
12type Bz2 struct {
13	CompressionLevel int
14}
15
16// Compress reads in, compresses it, and writes it to out.
17func (bz *Bz2) Compress(in io.Reader, out io.Writer) error {
18	w, err := bzip2.NewWriter(out, &bzip2.WriterConfig{
19		Level: bz.CompressionLevel,
20	})
21	if err != nil {
22		return err
23	}
24	defer w.Close()
25	_, err = io.Copy(w, in)
26	return err
27}
28
29// Decompress reads in, decompresses it, and writes it to out.
30func (bz *Bz2) Decompress(in io.Reader, out io.Writer) error {
31	r, err := bzip2.NewReader(in, nil)
32	if err != nil {
33		return err
34	}
35	defer r.Close()
36	_, err = io.Copy(out, r)
37	return err
38}
39
40// CheckExt ensures the file extension matches the format.
41func (bz *Bz2) CheckExt(filename string) error {
42	if filepath.Ext(filename) != ".bz2" {
43		return fmt.Errorf("filename must have a .bz2 extension")
44	}
45	return nil
46}
47
48func (bz *Bz2) String() string { return "bz2" }
49
50// NewBz2 returns a new, default instance ready to be customized and used.
51func NewBz2() *Bz2 {
52	return &Bz2{
53		CompressionLevel: bzip2.DefaultCompression,
54	}
55}
56
57// Compile-time checks to ensure type implements desired interfaces.
58var (
59	_ = Compressor(new(Bz2))
60	_ = Decompressor(new(Bz2))
61)
62
63// DefaultBz2 is a default instance that is conveniently ready to use.
64var DefaultBz2 = NewBz2()
65