Files
lwch bc5d709dcb 1. 增加代码注释
2. 增加通用encoding层
2023-02-01 17:08:09 +08:00

89 lines
1.9 KiB
Go

package gzip
import (
"compress/gzip"
"fmt"
"io"
"sync"
"github.com/lwch/natpass/code/network/encoding"
"github.com/lwch/runtime"
)
type writer struct {
*gzip.Writer
pool *sync.Pool
}
// Close close write and put writer to pool
func (w *writer) Close() error {
w.pool.Put(w)
return w.Writer.Close()
}
type reader struct {
*gzip.Reader
pool *sync.Pool
}
// Close close reader and put reader to pool
func (r *reader) Close() error {
r.pool.Put(r)
return r.Reader.Close()
}
type compressor struct {
level int
poolWriter [gzip.BestCompression]sync.Pool
poolReader sync.Pool
}
// New create compressor
func New(level ...int) (encoding.Compressor, error) {
if len(level) > 0 {
if level[0] < 0 || level[0] > gzip.BestCompression {
return nil, fmt.Errorf("invalid gzip compress level: %d", level[0])
}
} else {
level = append(level, 6)
}
ret := new(compressor)
ret.level = level[0]
for i := 0; i < gzip.BestCompression; i++ {
ret.poolWriter[i].New = func() interface{} {
w, err := gzip.NewWriterLevel(io.Discard, i)
runtime.Assert(err)
return &writer{Writer: w, pool: &ret.poolWriter[i]}
}
}
ret.poolReader.New = func() interface{} {
r, err := gzip.NewReader(io.NopCloser(nil))
runtime.Assert(err)
return &reader{Reader: r, pool: &ret.poolReader}
}
return ret, nil
}
// Compress gzip compress
func (c *compressor) Compress(w io.Writer) (io.WriteCloser, error) {
pw := c.poolWriter[c.level].Get().(*writer)
pw.Writer.Reset(w)
return pw, nil
}
// Decompress gzip decompress
func (c *compressor) Decompress(r io.Reader) (io.ReadCloser, error) {
pr := c.poolReader.Get().(*reader)
pr.Reader.Reset(r)
return pr, nil
}
// SetLevel set compress level
func (c *compressor) SetLevel(level int) error {
if level < 0 || level > gzip.BestCompression {
return fmt.Errorf("invalid gzip compress level: %d", level)
}
c.level = level
return nil
}