package zip
import (
"compress/flate"
"errors"
"io"
"sync"
)
type Compressor func (w io .Writer ) (io .WriteCloser , error )
type Decompressor func (r io .Reader ) io .ReadCloser
var flateWriterPool sync .Pool
func newFlateWriter(w io .Writer ) io .WriteCloser {
fw , ok := flateWriterPool .Get ().(*flate .Writer )
if ok {
fw .Reset (w )
} else {
fw , _ = flate .NewWriter (w , 5 )
}
return &pooledFlateWriter {fw : fw }
}
type pooledFlateWriter struct {
mu sync .Mutex
fw *flate .Writer
}
func (w *pooledFlateWriter ) Write (p []byte ) (n int , err error ) {
w .mu .Lock ()
defer w .mu .Unlock ()
if w .fw == nil {
return 0 , errors .New ("Write after Close" )
}
return w .fw .Write (p )
}
func (w *pooledFlateWriter ) Close () error {
w .mu .Lock ()
defer w .mu .Unlock ()
var err error
if w .fw != nil {
err = w .fw .Close ()
flateWriterPool .Put (w .fw )
w .fw = nil
}
return err
}
var flateReaderPool sync .Pool
func newFlateReader(r io .Reader ) io .ReadCloser {
fr , ok := flateReaderPool .Get ().(io .ReadCloser )
if ok {
fr .(flate .Resetter ).Reset (r , nil )
} else {
fr = flate .NewReader (r )
}
return &pooledFlateReader {fr : fr }
}
type pooledFlateReader struct {
mu sync .Mutex
fr io .ReadCloser
}
func (r *pooledFlateReader ) Read (p []byte ) (n int , err error ) {
r .mu .Lock ()
defer r .mu .Unlock ()
if r .fr == nil {
return 0 , errors .New ("Read after Close" )
}
return r .fr .Read (p )
}
func (r *pooledFlateReader ) Close () error {
r .mu .Lock ()
defer r .mu .Unlock ()
var err error
if r .fr != nil {
err = r .fr .Close ()
flateReaderPool .Put (r .fr )
r .fr = nil
}
return err
}
var (
compressors sync .Map
decompressors sync .Map
)
func init() {
compressors .Store (Store , Compressor (func (w io .Writer ) (io .WriteCloser , error ) { return &nopCloser {w }, nil }))
compressors .Store (Deflate , Compressor (func (w io .Writer ) (io .WriteCloser , error ) { return newFlateWriter (w ), nil }))
decompressors .Store (Store , Decompressor (io .NopCloser ))
decompressors .Store (Deflate , Decompressor (newFlateReader ))
}
func RegisterDecompressor (method uint16 , dcomp Decompressor ) {
if _ , dup := decompressors .LoadOrStore (method , dcomp ); dup {
panic ("decompressor already registered" )
}
}
func RegisterCompressor (method uint16 , comp Compressor ) {
if _ , dup := compressors .LoadOrStore (method , comp ); dup {
panic ("compressor already registered" )
}
}
func compressor(method uint16 ) Compressor {
ci , ok := compressors .Load (method )
if !ok {
return nil
}
return ci .(Compressor )
}
func decompressor(method uint16 ) Decompressor {
di , ok := decompressors .Load (method )
if !ok {
return nil
}
return di .(Decompressor )
}
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .