github.com/wfusion/gofusion@v1.1.14/common/utils/compress/decode.go (about) 1 package compress 2 3 import ( 4 "io" 5 6 "github.com/wfusion/gofusion/common/utils" 7 ) 8 9 type decodable interface { 10 io.Reader 11 Reset(r io.Reader) error 12 } 13 14 func DecodeBytesFunc(algo Algorithm) func(src []byte) (dst []byte, err error) { 15 return func(src []byte) (dst []byte, err error) { 16 var ( 17 dec decodable 18 recycles []func() 19 ) 20 defer func() { 21 for _, cb := range recycles { 22 if cb != nil { 23 cb() 24 } 25 } 26 }() 27 28 srcBuffer, bufferCb := utils.BytesBufferPool.Get(nil) 29 recycles = append(recycles, bufferCb) 30 srcBuffer.Write(src) 31 _, err = utils.Catch(func() { 32 var cb func() 33 dec, cb = getDecoder(algo, srcBuffer) 34 recycles = append(recycles, cb) 35 }) 36 if err != nil || dec == nil { 37 return 38 } 39 40 dstBuffer, bufferCb := utils.BytesBufferPool.Get(nil) 41 recycles = append(recycles, bufferCb) 42 if _, err = io.Copy(dstBuffer, dec); err != nil { 43 if err = utils.ErrIgnore(err, eofErrs...); err != nil { 44 return 45 } 46 } 47 dst = make([]byte, dstBuffer.Len()) 48 copy(dst, dstBuffer.Bytes()) 49 return 50 } 51 } 52 53 func DecodeStreamFunc(algo Algorithm) func(dst io.Writer, src io.Reader) (err error) { 54 return func(dst io.Writer, src io.Reader) (err error) { 55 var ( 56 dec decodable 57 cb func() 58 ) 59 defer func() { 60 if cb != nil { 61 cb() 62 } 63 }() 64 65 if _, err = utils.Catch(func() { dec, cb = getDecoder(algo, src) }); err != nil { 66 return 67 } 68 69 _, err = io.Copy(dst, dec) 70 return utils.ErrIgnore(err, eofErrs...) 71 } 72 } 73 74 func getDecoder(algo Algorithm, src io.Reader) (dec decodable, recycle func()) { 75 p, ok := decoderPools[algo] 76 if !algo.IsValid() || !ok { 77 panic(ErrUnknownAlgorithm) 78 } 79 80 sealer, recycle := p.Get(src) 81 dec = sealer.decodable 82 return 83 } 84 85 type decoder struct { 86 dec decodable 87 r io.Reader 88 cb func() 89 } 90 91 func NewDecFunc(algo Algorithm) func(r io.Reader) io.ReadCloser { 92 return func(r io.Reader) io.ReadCloser { 93 dec, cb := getDecoder(algo, r) 94 return &decoder{ 95 dec: dec, 96 r: r, 97 cb: cb, 98 } 99 } 100 } 101 102 func (e *decoder) Reset(r io.Reader) error { return e.dec.Reset(r) } 103 func (e *decoder) Read(p []byte) (n int, err error) { return e.dec.Read(p) } 104 func (e *decoder) Close() (err error) { defer e.cb(); utils.CloseAnyway(e.r); return }