Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package zstd

/*
#define ZSTD_STATIC_LINKING_ONLY
#include "zstd.h"
*/
import "C"

// ErrorCode is an error returned by the zstd library.
type ErrorCode int

// Error returns the error string given by zstd
func (e ErrorCode) Error() string {
return C.GoString(C.ZSTD_getErrorName(C.size_t(e)))
}

func cIsError(code int) bool {
return int(C.ZSTD_isError(C.size_t(code))) != 0
}

// getError returns an error for the return code, or nil if it's not an error
func getError(code int) error {
if code < 0 && cIsError(code) {
return ErrorCode(code)
}
return nil
}

// IsDstSizeTooSmallError returns whether the error correspond to zstd standard sDstSizeTooSmall error
func IsDstSizeTooSmallError(e error) bool {
if e != nil && e.Error() == "Destination buffer is too small" {
return true
}
return false
}
29 changes: 29 additions & 0 deletions errors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package zstd

import (
"testing"
)

const (
// ErrorUpperBound is the upper bound to error number, currently only used in test
// If this needs to be updated, check in zstd_errors.h what the max is
ErrorUpperBound = 1000
)

// TestFindIsDstSizeTooSmallError tests that there is at least one error code that
// corresponds to dst size too small
func TestFindIsDstSizeTooSmallError(t *testing.T) {
found := 0
for i := -1; i > -ErrorUpperBound; i-- {
e := ErrorCode(i)
if IsDstSizeTooSmallError(e) {
found++
}
}

if found == 0 {
t.Fatal("Couldn't find an error code for DstSizeTooSmall error, please make sure we didn't change the error string")
} else if found > 1 {
t.Fatal("IsDstSizeTooSmallError found multiple error codes matching, this shouldn't be the case")
}
}
64 changes: 7 additions & 57 deletions zstd.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,16 @@ import (
"unsafe"
)

// ErrorCode is an error returned by the zstd library.
type ErrorCode int

func (e ErrorCode) Error() string {
if C.ZSTD_isError(C.size_t(e)) != C.uint(0) {
return C.GoString(C.ZSTD_getErrorName(C.size_t(e)))
}

return ""
}

// Defines best and standard values for zstd cli
const (
BestSpeed = 1
BestCompression = 20
BestSpeed = 1
BestCompression = 20
DefaultCompression = 5
)

// FIXME: this is very fragile, must map 1-to-1 with zstd's
// error_public.h. They have no problem with adding error codes,
// renumbering errors, etc.
var (
ErrGeneric ErrorCode = -1
ErrPrefixUnknown ErrorCode = -2
ErrVersionUnsupported ErrorCode = -3
ErrParameterUnknown ErrorCode = -4
ErrFrameParameterUnsupported ErrorCode = -5
ErrFrameParameterUnsupportedBy32bits ErrorCode = -6
ErrFrameParameterWindowTooLarge ErrorCode = -7
ErrCompressionParameterUnsupported ErrorCode = -8
ErrCompressionParameterOutOfBound ErrorCode = -9
ErrInitMissing ErrorCode = -10
ErrMemoryAllocation ErrorCode = -11
ErrStageWrong ErrorCode = -12
ErrDstSizeTooSmall ErrorCode = -13
ErrSrcSizeWrong ErrorCode = -14
ErrCorruptionDetected ErrorCode = -15
ErrChecksumWrong ErrorCode = -16
ErrTableLogTooLarge ErrorCode = -17
ErrMaxSymbolValueTooLarge ErrorCode = -18
ErrMaxSymbolValueTooSmall ErrorCode = -19
ErrDictionaryCorrupted ErrorCode = -20
ErrDictionaryWrong ErrorCode = -21
ErrDictionaryCreationFailed ErrorCode = -22
ErrFrameIndexTooLarge ErrorCode = -23
ErrSeekableIO ErrorCode = -24
ErrMaxCode ErrorCode = -25
ErrEmptySlice = errors.New("Bytes slice is empty")

DefaultCompression = 5
// ErrEmptySlice is returned when there is nothing to compress
ErrEmptySlice = errors.New("Bytes slice is empty")
)

// CompressBound returns the worst case size needed for a destination buffer,
Expand All @@ -79,18 +41,6 @@ func cCompressBound(srcSize int) int {
return int(C.ZSTD_compressBound(C.size_t(srcSize)))
}

// getError returns an error for the return code, or nil if it's not an error
func getError(code int) error {
if code < 0 && code > int(ErrMaxCode) {
return ErrorCode(code)
}
return nil
}

func cIsError(code int) bool {
return int(C.ZSTD_isError(C.size_t(code))) != 0
}

// Compress src into dst. If you have a buffer to use, you can pass it to
// prevent allocation. If it is too small, or if nil is passed, a new buffer
// will be allocated and returned.
Expand Down Expand Up @@ -161,7 +111,7 @@ func Decompress(dst, src []byte) ([]byte, error) {
}
for i := 0; i < 3; i++ { // 3 tries to allocate a bigger buffer
result, err := decompress(dst, src)
if err != ErrDstSizeTooSmall {
if !IsDstSizeTooSmallError(err) {
return result, err
}
dst = make([]byte, len(dst)*2) // Grow buffer by 2
Expand Down