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