lz4.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package lz4
  2. // #cgo CFLAGS: -O3
  3. // #include "src/lz4.h"
  4. // #include "src/lz4.c"
  5. import "C"
  6. import (
  7. "errors"
  8. "fmt"
  9. "unsafe"
  10. )
  11. // p gets a char pointer to the first byte of a []byte slice
  12. func p(in []byte) *C.char {
  13. if len(in) == 0 {
  14. return (*C.char)(unsafe.Pointer(nil))
  15. }
  16. return (*C.char)(unsafe.Pointer(&in[0]))
  17. }
  18. // clen gets the length of a []byte slice as a char *
  19. func clen(s []byte) C.int {
  20. return C.int(len(s))
  21. }
  22. // Uncompress with a known output size. len(out) should be equal to
  23. // the length of the uncompressed out.
  24. func Uncompress(in, out []byte) (error) {
  25. if int(C.LZ4_decompress_safe(p(in), p(out), clen(in), clen(out))) < 0 {
  26. return errors.New("Malformed compression stream")
  27. }
  28. return nil
  29. }
  30. // CompressBound calculates the size of the output buffer needed by
  31. // Compress. This is based on the following macro:
  32. //
  33. // #define LZ4_COMPRESSBOUND(isize)
  34. // ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
  35. func CompressBound(in []byte) int {
  36. return len(in) + ((len(in) / 255) + 16)
  37. }
  38. // Compress compresses in and puts the content in out. len(out)
  39. // should have enough space for the compressed data (use CompressBound
  40. // to calculate). Returns the number of bytes in the out slice.
  41. func Compress(in, out []byte) (outSize int, err error) {
  42. outSize = int(C.LZ4_compress_limitedOutput(p(in), p(out), clen(in), clen(out)))
  43. if outSize == 0 {
  44. err = fmt.Errorf("insufficient space for compression")
  45. }
  46. return
  47. }