Skip to content

Commit

Permalink
tiedied up v1 repo
Browse files Browse the repository at this point in the history
  • Loading branch information
4kills committed Nov 7, 2020
1 parent bcf9e30 commit bf71681
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 112 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
*/go.sum
go.sum

# Goland
.idea/

Expand Down
2 changes: 1 addition & 1 deletion compressor.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ This prediction is a wild overestimate in most cases, for which holds true: max
However, it gives a hard maximal bound of the size of compressed data, compressing with the given mode
at the compression level of the this compressor, independent of the actual data.
This method will always return the same max size for the same compressor, input size and mode.
*/
*/
func (c Compressor) WorstCaseCompressedSize(size int, m Mode) (max int) {
switch m {
case ModeDEFLATE:
Expand Down
4 changes: 2 additions & 2 deletions compressor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ func TestCompressDecompress(t *testing.T) {
out := make([]byte, len(shortString))
dc, _ := NewDecompressor()
defer dc.Close()
if c, _, err := dc.DecompressZlib(comp, out); err != nil || c != len(comp){
if _, err := dc.DecompressZlib(comp, out); err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)
}

/*---------------------
Expand Down
19 changes: 6 additions & 13 deletions decompress.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package libdeflate

// DecompressZlib decompresses the given zlib data from in to out and returns the number of consumed bytes c
// from 'in' and 'out' or an error if something went wrong.
//
// c is the number of bytes that were read before the BFINAL flag was
// encountered, which indicates the end of the compressed data.
// DecompressZlib decompresses the given data from in (zlib formatted) to out and returns out
// or an error if something went wrong.
//
// If you pass a buffer to out, the size of this buffer must exactly match the length of the decompressed data.
// If you pass nil to out, this function will allocate a sufficient buffer and return it.
Expand All @@ -13,28 +10,24 @@ package libdeflate
// as this function creates a new Decompressor (alloc 32KiB) which is then closed at the end of the function.
//
// If error != nil, the data in out is undefined.
func DecompressZlib(in, out []byte) (int, []byte, error) {
func DecompressZlib(in, out []byte) ([]byte, error) {
return Decompress(in, out, ModeZlib)
}

// Decompress decompresses the given data from in to out and returns the number of consumed bytes c from 'in' and 'out'
// or an error if something went wrong.
// Decompress decompresses the given data from in to out and returns out or an error if something went wrong.
// Mode m specifies the format (e.g. zlib) of the data within in.
//
// c is the number of bytes that were read before the BFINAL flag was
// encountered, which indicates the end of the compressed data.
//
// If you pass a buffer to out, the size of this buffer must exactly match the length of the decompressed data.
// If you pass nil to out, this function will allocate a sufficient buffer and return it.
//
// IF YOU WANT TO DECOMPRESS MORE THAN ONCE, PLEASE REFER TO NewDecompressor(),
// as this function creates a new Decompressor (alloc 32KiB) which is then closed at the end of the function.
//
// If error != nil, the data in out is undefined.
func Decompress(in, out []byte, m Mode) (int, []byte, error) {
func Decompress(in, out []byte, m Mode) ([]byte, error) {
dc, err := NewDecompressor()
if err != nil {
return 0, out, err
return out, err
}
defer dc.Close()

Expand Down
6 changes: 3 additions & 3 deletions decompress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ func TestDecompressZlibConvenience(t *testing.T) {
out := make([]byte, len(shortString))
dc, _ := NewDecompressor()
defer dc.Close()
if c, _, err := DecompressZlib(in, out); err != nil || c != len(in) {
if _, err := DecompressZlib(in, out); err != nil {
t.Error(err)
}
slicesEqual([]byte(shortString), out, t)

c, out, err := dc.DecompressZlib(in, nil)
if err != nil || c != len(in) {
out, err := dc.DecompressZlib(in, nil)
if err != nil {
t.Error(err)
}
slicesEqual([]byte(shortString), out, t)
Expand Down
16 changes: 4 additions & 12 deletions decompressor.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,24 @@ func NewDecompressor() (Decompressor, error) {
return Decompressor{dc}, err
}

// DecompressZlib decompresses the given zlib data from in to out and returns the number of consumed bytes c
// from 'in' and 'out' or an error if something went wrong.
//
// c is the number of bytes that were read before the BFINAL flag was
// encountered, which indicates the end of the compressed data.
// DecompressZlib decompresses the given zlib data from in to out and returns out or an error if something went wrong.
//
// If you pass a buffer to out, the size of this buffer must exactly match the length of the decompressed data.
// If you pass nil to out, this function will allocate a sufficient buffer and return it.
//
// If error != nil, the data in out is undefined.
func (dc Decompressor) DecompressZlib(in, out []byte) (int, []byte, error) {
func (dc Decompressor) DecompressZlib(in, out []byte) ([]byte, error) {
return dc.Decompress(in, out, ModeZlib)
}

// Decompress decompresses the given data from in to out and returns the number of consumed bytes c from 'in' and 'out'
// or an error if something went wrong.
// Decompress decompresses the given data from in to out and returns out or an error if something went wrong.
// Mode m specifies the format (e.g. zlib) of the data within in.
//
// c is the number of bytes that were read before the BFINAL flag was
// encountered, which indicates the end of the compressed data.
//
// If you pass a buffer to out, the size of this buffer must exactly match the length of the decompressed data.
// If you pass nil to out, this function will allocate a sufficient buffer and return it.
//
// If error != nil, the data in out is undefined.
func (dc Decompressor) Decompress(in, out []byte, m Mode) (int, []byte, error) {
func (dc Decompressor) Decompress(in, out []byte, m Mode) ([]byte, error) {
switch m {
case ModeZlib:
return dc.dc.Decompress(in, out, native.DecompressZlib)
Expand Down
36 changes: 18 additions & 18 deletions decompressor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestDecompressDEFLATE(t *testing.T) {
// compress with go standard lib
buf := &bytes.Buffer{}
w, _ := flate.NewWriter(buf, flate.DefaultCompression)
w.Write(shortString)
w.Write([]byte(shortString))
w.Close()
in := buf.Bytes()

Expand All @@ -25,23 +25,23 @@ func TestDecompressDEFLATE(t *testing.T) {
out := make([]byte, len(shortString))
dc, _ := NewDecompressor()
defer dc.Close()
if c, _, err := dc.Decompress(in, out, ModeDEFLATE); err != nil || c != len(in){
if _, err := dc.Decompress(in, out, ModeDEFLATE); err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)

c, out, err := dc.Decompress(in, nil, ModeDEFLATE)
if err != nil || c != len(in) {
out, err := dc.Decompress(in, nil, ModeDEFLATE)
if err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)
}

func TestDecompressGzip(t *testing.T) {
// compress with go standard lib
buf := &bytes.Buffer{}
w := gzip.NewWriter(buf)
w.Write(shortString)
w.Write([]byte(shortString))
w.Close()
in := buf.Bytes()

Expand All @@ -50,23 +50,23 @@ func TestDecompressGzip(t *testing.T) {
out := make([]byte, len(shortString))
dc, _ := NewDecompressor()
defer dc.Close()
if c, _, err := dc.Decompress(in, out, ModeGzip); err != nil || c != len(in){
if _, err := dc.Decompress(in, out, ModeGzip); err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)

c, out, err := dc.Decompress(in, nil, ModeGzip)
if err != nil || c != len(in) {
out, err := dc.Decompress(in, nil, ModeGzip)
if err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)
}

func TestDecompressZlib(t *testing.T) {
// compress with go standard lib
buf := &bytes.Buffer{}
w := zlib.NewWriter(buf)
w.Write(shortString)
w.Write([]byte(shortString))
w.Close()
in := buf.Bytes()

Expand All @@ -75,14 +75,14 @@ func TestDecompressZlib(t *testing.T) {
out := make([]byte, len(shortString))
dc, _ := NewDecompressor()
defer dc.Close()
if c, _, err := dc.DecompressZlib(in, out); err != nil || c != len(in) {
if _, err := dc.DecompressZlib(in, out); err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)

c, out, err := dc.DecompressZlib(in, nil)
if err != nil || c != len(in) {
out, err := dc.DecompressZlib(in, nil)
if err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/4kills/go-libdeflate

go 1.15
4 changes: 2 additions & 2 deletions native/compressor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ func TestCompressDecompress(t *testing.T) {
out := make([]byte, len(shortString))
dc, _ := NewDecompressor()
defer dc.Close()
if c, _, err := dc.Decompress(comp, out, DecompressZlib); err != nil || c != len(comp) {
if _, err := dc.Decompress(comp, out, DecompressZlib); err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)
}

/*---------------------
Expand Down
17 changes: 7 additions & 10 deletions native/decompressing.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,31 @@ size_t* mkPtr(size_t s) {
import "C"
import "unsafe"

type decompress func(dc *C.decomp, inAddr, outAddr *byte, inSize, outSize int, consPtr, sPtr uintptr) error
type decompress func(dc *C.decomp, inAddr, outAddr *byte, inSize, outSize int, sPtr uintptr) error

// DecompressZlib interfaces with c libdeflate for zlib decompression
func DecompressZlib(dc *C.decomp, inAddr, outAddr *byte, inSize, outSize int, consPtr, sPtr uintptr) error {
return parseResult(C.res(C.libdeflate_zlib_decompress_ex(dc,
func DecompressZlib(dc *C.decomp, inAddr, outAddr *byte, inSize, outSize int, sPtr uintptr) error {
return parseResult(C.res(C.libdeflate_zlib_decompress(dc,
unsafe.Pointer(inAddr), intToInt64(inSize),
unsafe.Pointer(outAddr), intToInt64(outSize),
C.mkPtr(C.size_t(consPtr)),
C.mkPtr(C.size_t(sPtr)),
)))
}

// DecompressDEFLATE interfaces with c libdeflate for DEFLATE decompression
func DecompressDEFLATE(dc *C.decomp, inAddr, outAddr *byte, inSize, outSize int, consPtr, sPtr uintptr) error {
return parseResult(C.res(C.libdeflate_deflate_decompress_ex(dc,
func DecompressDEFLATE(dc *C.decomp, inAddr, outAddr *byte, inSize, outSize int, sPtr uintptr) error {
return parseResult(C.res(C.libdeflate_deflate_decompress(dc,
unsafe.Pointer(inAddr), intToInt64(inSize),
unsafe.Pointer(outAddr), intToInt64(outSize),
C.mkPtr(C.size_t(consPtr)),
C.mkPtr(C.size_t(sPtr)),
)))
}

// DecompressGzip interfaces with c libdeflate for gzip decompression
func DecompressGzip(dc *C.decomp, inAddr, outAddr *byte, inSize, outSize int, consPtr, sPtr uintptr) error {
return parseResult(C.res(C.libdeflate_gzip_decompress_ex(dc,
func DecompressGzip(dc *C.decomp, inAddr, outAddr *byte, inSize, outSize int, sPtr uintptr) error {
return parseResult(C.res(C.libdeflate_gzip_decompress(dc,
unsafe.Pointer(inAddr), intToInt64(inSize),
unsafe.Pointer(outAddr), intToInt64(outSize),
C.mkPtr(C.size_t(consPtr)),
C.mkPtr(C.size_t(sPtr)),
)))
}
Expand Down
34 changes: 14 additions & 20 deletions native/decompressor.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,59 +32,53 @@ func NewDecompressor() (*Decompressor, error) {
// If error != nil, then the data in out is undefined.
// If you pass a buffer to out, the size of this buffer must exactly match the length of the decompressed data.
// If you pass nil as out, this function will allocate a sufficient buffer and return it.
// Returns the number of consumed bytes from 'in'
func (dc *Decompressor) Decompress(in, out []byte, f decompress) (int, []byte, error) {
func (dc *Decompressor) Decompress(in, out []byte, f decompress) ([]byte, error) {
if dc.isClosed {
panic(errorAlreadyClosed)
}
if len(in) == 0 {
return 0, out, errorNoInput
return out, errorNoInput
}

if out != nil {
cons, _, err := dc.decompress(in, out, true, f)
return cons, out, err
_, err := dc.decompress(in, out, true, f)
return out, err
}

cons := 0
n := 0
inc := 6
err := errorInsufficientSpace
for err == errorInsufficientSpace {
out = make([]byte, len(in)*inc)
cons, n, err = dc.decompress(in, out, false, f)
n, err = dc.decompress(in, out, false, f)
if inc >= 16 {
inc += 3
continue
}
inc += 5
}

return cons, out[:n], err
return out[:n], err
}

func (dc *Decompressor) decompress(in, out []byte, fit bool, f decompress) (int, int, error) {
func (dc *Decompressor) decompress(in, out []byte, fit bool, f decompress) (int, error) {
inAddr := startMemAddr(in)
outAddr := startMemAddr(out)

var (
cons int
n int
)

consPtr := uintptr(unsafe.Pointer(&cons))
sPtr := uintptr(unsafe.Pointer(&n))
var s int64
sPtr := uintptr(unsafe.Pointer(&s))
if fit {
sPtr = 0
}

err := f(dc.dc, inAddr, outAddr, len(in), len(out), consPtr, sPtr)
err := f(dc.dc, inAddr, outAddr, len(in), len(out), sPtr)

if fit {
n = len(out)
n := len(out)
if !fit {
n = int(s)
}

return cons, n, err
return n, err
}

// Close frees the memory allocated by C objects
Expand Down
36 changes: 5 additions & 31 deletions native/decompressor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,40 +35,14 @@ func TestDecompress(t *testing.T) {
out := make([]byte, len(shortString))
dc, _ := NewDecompressor()
defer dc.Close()
if c, _, err := dc.Decompress(in, out, DecompressZlib); err != nil || c != len(in) {
if _, err := dc.Decompress(in, out, DecompressZlib); err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)

c, out, err := dc.Decompress(in, nil, DecompressZlib)
if err != nil || c != len(in){
out, err := dc.Decompress(in, nil, DecompressZlib)
if err != nil {
t.Error(err)
}
slicesEqual(shortString, out, t)
}

func TestDecompressOversizedInput(t *testing.T) {
// compress with go standard zlib
buf := &bytes.Buffer{}
w := zlib.NewWriter(buf)
w.Write([]byte(shortString))
w.Close()
in := buf.Bytes()

// decompress with this lib

oversized := append(in, in...)
out := make([]byte, len(shortString))
dc, _ := NewDecompressor()
defer dc.Close()
if c, _, err := dc.Decompress(oversized, out, DecompressZlib); err != nil || c != len(in) {
t.Error(err)
}
slicesEqual(shortString, out, t)

c, out, err := dc.Decompress(oversized, nil, DecompressZlib)
if err != nil || c != len(in){
t.Error(err)
}
slicesEqual(shortString, out, t)
slicesEqual([]byte(shortString), out, t)
}

0 comments on commit bf71681

Please sign in to comment.