github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/ioutils/ioutil.go (about)

     1  package ioutils
     2  
     3  import (
     4  	"bytes"
     5  	"compress/gzip"
     6  	"io"
     7  	"io/ioutil"
     8  
     9  	"github.com/fibonacci-chain/fbc/x/wasm/types"
    10  )
    11  
    12  // Uncompress returns gzip uncompressed content if input was gzip, or original src otherwise
    13  func Uncompress(src []byte, limit uint64) ([]byte, error) {
    14  	switch n := uint64(len(src)); {
    15  	case n < 3:
    16  		return src, nil
    17  	case n > limit:
    18  		return nil, types.ErrLimit
    19  	}
    20  	if !bytes.Equal(gzipIdent, src[0:3]) {
    21  		return src, nil
    22  	}
    23  	zr, err := gzip.NewReader(bytes.NewReader(src))
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  	zr.Multistream(false)
    28  	defer zr.Close()
    29  	return ioutil.ReadAll(LimitReader(zr, int64(limit)))
    30  }
    31  
    32  // LimitReader returns a Reader that reads from r
    33  // but stops with types.ErrLimit after n bytes.
    34  // The underlying implementation is a *io.LimitedReader.
    35  func LimitReader(r io.Reader, n int64) io.Reader {
    36  	return &LimitedReader{r: &io.LimitedReader{R: r, N: n}}
    37  }
    38  
    39  type LimitedReader struct {
    40  	r *io.LimitedReader
    41  }
    42  
    43  func (l *LimitedReader) Read(p []byte) (n int, err error) {
    44  	if l.r.N <= 0 {
    45  		return 0, types.ErrLimit
    46  	}
    47  	return l.r.Read(p)
    48  }