github.com/iotexproject/iotex-core@v1.14.1-rc1/pkg/compress/compress.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package compress
     7  
     8  import (
     9  	"bytes"
    10  	"compress/gzip"
    11  	"io"
    12  
    13  	"github.com/golang/snappy"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // constants
    18  const (
    19  	Gzip   = "Gzip"
    20  	Snappy = "Snappy"
    21  )
    22  
    23  // error definition
    24  var (
    25  	ErrInputEmpty = errors.New("input cannot be empty")
    26  )
    27  
    28  // Compress compresses input according to compressor
    29  func Compress(value []byte, compressor string) ([]byte, error) {
    30  	if value == nil {
    31  		return nil, ErrInputEmpty
    32  	}
    33  
    34  	switch compressor {
    35  	case Gzip:
    36  		return CompGzip(value)
    37  	case Snappy:
    38  		return CompSnappy(value)
    39  	default:
    40  		panic("unsupported compressor")
    41  	}
    42  }
    43  
    44  // Decompress decompresses input according to compressor
    45  func Decompress(value []byte, compressor string) ([]byte, error) {
    46  	switch compressor {
    47  	case Gzip:
    48  		return DecompGzip(value)
    49  	case Snappy:
    50  		return DecompSnappy(value)
    51  	default:
    52  		panic("unsupported compressor")
    53  	}
    54  }
    55  
    56  // CompGzip uses gzip to compress the input bytes
    57  func CompGzip(data []byte) ([]byte, error) {
    58  	var bb bytes.Buffer
    59  	w, err := gzip.NewWriterLevel(&bb, gzip.BestCompression)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	if _, err = w.Write(data); err != nil {
    64  		err = w.Close()
    65  		return nil, err
    66  	}
    67  	if err = w.Close(); err != nil {
    68  		return nil, err
    69  	}
    70  	output := bb.Bytes()
    71  	return output, nil
    72  }
    73  
    74  // DecompGzip uses gzip to uncompress the input bytes
    75  func DecompGzip(data []byte) ([]byte, error) {
    76  	r, err := gzip.NewReader(bytes.NewBuffer(data))
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	if err = r.Close(); err != nil {
    81  		return nil, err
    82  	}
    83  	return io.ReadAll(r)
    84  }
    85  
    86  // CompSnappy uses Snappy to compress the input bytes
    87  func CompSnappy(data []byte) ([]byte, error) {
    88  	return snappy.Encode(nil, data), nil
    89  }
    90  
    91  // DecompSnappy uses Snappy to decompress the input bytes
    92  func DecompSnappy(data []byte) ([]byte, error) {
    93  	v, err := snappy.Decode(nil, data)
    94  	if len(v) == 0 {
    95  		v = []byte{}
    96  	}
    97  	return v, err
    98  }