...
1
2
3
4
5 package zip
6
7 import (
8 "errors"
9 "io"
10 "sync"
11
12 "github.com/klauspost/compress/flate"
13 )
14
15
16
17
18
19
20 type Compressor func(w io.Writer) (io.WriteCloser, error)
21
22
23
24
25
26
27 type Decompressor func(r io.Reader) io.ReadCloser
28
29 var flateWriterPool sync.Pool
30
31 func newFlateWriter(w io.Writer) io.WriteCloser {
32 fw, ok := flateWriterPool.Get().(*flate.Writer)
33 if ok {
34 fw.Reset(w)
35 } else {
36 fw, _ = flate.NewWriter(w, 5)
37 }
38 return &pooledFlateWriter{fw: fw}
39 }
40
41 type pooledFlateWriter struct {
42 mu sync.Mutex
43 fw *flate.Writer
44 }
45
46 func (w *pooledFlateWriter) Write(p []byte) (n int, err error) {
47 w.mu.Lock()
48 defer w.mu.Unlock()
49 if w.fw == nil {
50 return 0, errors.New("Write after Close")
51 }
52 return w.fw.Write(p)
53 }
54
55 func (w *pooledFlateWriter) Close() error {
56 w.mu.Lock()
57 defer w.mu.Unlock()
58 var err error
59 if w.fw != nil {
60 err = w.fw.Close()
61 flateWriterPool.Put(w.fw)
62 w.fw = nil
63 }
64 return err
65 }
66
67 var flateReaderPool sync.Pool
68
69 func newFlateReader(r io.Reader) io.ReadCloser {
70 fr, ok := flateReaderPool.Get().(io.ReadCloser)
71 if ok {
72 fr.(flate.Resetter).Reset(r, nil)
73 } else {
74 fr = flate.NewReader(r)
75 }
76 return &pooledFlateReader{fr: fr}
77 }
78
79 type pooledFlateReader struct {
80 mu sync.Mutex
81 fr io.ReadCloser
82 }
83
84 func (r *pooledFlateReader) Read(p []byte) (n int, err error) {
85 r.mu.Lock()
86 defer r.mu.Unlock()
87 if r.fr == nil {
88 return 0, errors.New("Read after Close")
89 }
90 return r.fr.Read(p)
91 }
92
93 func (r *pooledFlateReader) Close() error {
94 r.mu.Lock()
95 defer r.mu.Unlock()
96 var err error
97 if r.fr != nil {
98 err = r.fr.Close()
99 flateReaderPool.Put(r.fr)
100 r.fr = nil
101 }
102 return err
103 }
104
105 var (
106 compressors sync.Map
107 decompressors sync.Map
108 )
109
110 func init() {
111 compressors.Store(Store, Compressor(func(w io.Writer) (io.WriteCloser, error) { return &nopCloser{w}, nil }))
112 compressors.Store(Deflate, Compressor(func(w io.Writer) (io.WriteCloser, error) { return newFlateWriter(w), nil }))
113
114 decompressors.Store(Store, Decompressor(io.NopCloser))
115 decompressors.Store(Deflate, Decompressor(newFlateReader))
116 }
117
118
119
120 func RegisterDecompressor(method uint16, dcomp Decompressor) {
121 if _, dup := decompressors.LoadOrStore(method, dcomp); dup {
122 panic("decompressor already registered")
123 }
124 }
125
126
127
128 func RegisterCompressor(method uint16, comp Compressor) {
129 if _, dup := compressors.LoadOrStore(method, comp); dup {
130 panic("compressor already registered")
131 }
132 }
133
134 func compressor(method uint16) Compressor {
135 ci, ok := compressors.Load(method)
136 if !ok {
137 return nil
138 }
139 return ci.(Compressor)
140 }
141
142 func decompressor(method uint16) Decompressor {
143 di, ok := decompressors.Load(method)
144 if !ok {
145 return nil
146 }
147 return di.(Decompressor)
148 }
149
View as plain text