Skip to content

Commit

Permalink
Add LZ4 decompressor
Browse files Browse the repository at this point in the history
  • Loading branch information
bodgit committed May 11, 2022
1 parent 629e548 commit 0cc1b40
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ Current status:
* Handles password-protected versions of both of the above (`7za a -mhc=on|off -mhe=on -ppassword test.7z ...`).
* Handles archives split into multiple volumes, (`7za a -v100m test.7z ...`).
* Validates CRC values as it parses the file.
* Supports BCJ2, Bzip2, Copy, Deflate, Delta, LZMA and LZMA2 methods.
* Supports BCJ2, Bzip2, Copy, Deflate, Delta, LZ4, LZMA and LZMA2 methods.

More examples of 7-zip archives are needed to test all of the different combinations/algorithms possible.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/bodgit/windows v1.0.0
github.com/connesc/cipherio v0.2.1
github.com/hashicorp/go-multierror v1.1.1
github.com/pierrec/lz4/v4 v4.1.14
github.com/ulikunitz/xz v0.5.10
go4.org v0.0.0-20200411211856-f5505b9728dd
golang.org/x/text v0.3.7
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
Expand Down
54 changes: 54 additions & 0 deletions internal/lz4/reader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package lz4

import (
"errors"
"io"
"sync"

lz4 "github.com/pierrec/lz4/v4"
)

//nolint:gochecknoglobals
var lz4ReaderPool sync.Pool

type readCloser struct {
c io.Closer
r *lz4.Reader
}

func (rc *readCloser) Close() (err error) {
if rc.c != nil {
lz4ReaderPool.Put(rc.r)
err = rc.c.Close()
rc.c, rc.r = nil, nil
}

return
}

func (rc *readCloser) Read(p []byte) (int, error) {
if rc.r == nil {
return 0, errors.New("lz4: Read after Close")
}

return rc.r.Read(p)
}

// NewReader returns a new LZ4 io.ReadCloser.
func NewReader(_ []byte, _ uint64, readers []io.ReadCloser) (io.ReadCloser, error) {
if len(readers) != 1 {
return nil, errors.New("lz4: need exactly one reader")
}

r, ok := lz4ReaderPool.Get().(*lz4.Reader)
if ok {
r.Reset(readers[0])
} else {
r = lz4.NewReader(readers[0])
}

return &readCloser{
c: readers[0],
r: r,
}, nil
}
8 changes: 8 additions & 0 deletions reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ func TestOpenReader(t *testing.T) {
name: "complex",
file: "lzma1900.7z",
},
{
name: "lz4",
file: "lz4.7z",
},
}

for _, table := range tables {
Expand Down Expand Up @@ -234,3 +238,7 @@ func BenchmarkBCJ2(b *testing.B) {
func BenchmarkComplex(b *testing.B) {
benchmarkArchive(b, "lzma1900.7z")
}

func BenchmarkLZ4(b *testing.B) {
benchmarkArchive(b, "lz4.7z")
}
3 changes: 3 additions & 0 deletions register.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/bodgit/sevenzip/internal/bzip2"
"github.com/bodgit/sevenzip/internal/deflate"
"github.com/bodgit/sevenzip/internal/delta"
"github.com/bodgit/sevenzip/internal/lz4"
"github.com/bodgit/sevenzip/internal/lzma"
"github.com/bodgit/sevenzip/internal/lzma2"
)
Expand Down Expand Up @@ -45,6 +46,8 @@ func init() {
RegisterDecompressor([]byte{0x04, 0x01, 0x08}, Decompressor(deflate.NewReader))
// Bzip2
RegisterDecompressor([]byte{0x04, 0x02, 0x02}, Decompressor(bzip2.NewReader))
// LZ4
RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x04}, Decompressor(lz4.NewReader))
// AES-CBC-256 & SHA-256
RegisterDecompressor([]byte{0x06, 0xf1, 0x07, 0x01}, Decompressor(aes7z.NewReader))
// LZMA2
Expand Down
Binary file added testdata/lz4.7z
Binary file not shown.

0 comments on commit 0cc1b40

Please sign in to comment.