1
1
//go:build generate
2
2
// +build generate
3
3
4
- //go:generate go run $GOFILE && gofmt -w ../inflate_gen.go
4
+ //go:generate go run $GOFILE
5
+ //go:generate go fmt ../inflate_gen.go
5
6
6
7
package main
7
8
@@ -16,9 +17,9 @@ func main() {
16
17
panic (err )
17
18
}
18
19
defer f .Close ()
19
- types := []string {"*bytes.Buffer" , "*bytes.Reader" , "*bufio.Reader" , "*strings.Reader" }
20
- names := []string {"BytesBuffer" , "BytesReader" , "BufioReader" , "StringsReader" }
21
- imports := []string {"bytes" , "bufio" , "io " , "strings" , "math/bits" }
20
+ types := []string {"*bytes.Buffer" , "*bytes.Reader" , "*bufio.Reader" , "*strings.Reader" , "Reader" }
21
+ names := []string {"BytesBuffer" , "BytesReader" , "BufioReader" , "StringsReader" , "GenericReader" }
22
+ imports := []string {"bytes" , "bufio" , "fmt " , "strings" , "math/bits" }
22
23
f .WriteString (`// Code generated by go generate gen_inflate.go. DO NOT EDIT.
23
24
24
25
package flate
@@ -44,6 +45,11 @@ func (f *decompressor) $FUNCNAME$() {
44
45
)
45
46
fr := f.r.($TYPE$)
46
47
48
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
49
+ // but is smart enough to keep local variables in registers, so use nb and b,
50
+ // inline call to moreBits and reassign b,nb back to f on return.
51
+ fnb, fb := f.nb, f.b
52
+
47
53
switch f.stepState {
48
54
case stateInit:
49
55
goto readLiteral
@@ -62,41 +68,35 @@ readLiteral:
62
68
// cases, the chunks slice will be 0 for the invalid sequence, leading it
63
69
// satisfy the n == 0 check below.
64
70
n := uint(f.hl.maxRead)
65
- // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
66
- // but is smart enough to keep local variables in registers, so use nb and b,
67
- // inline call to moreBits and reassign b,nb back to f on return.
68
- nb, b := f.nb, f.b
69
71
for {
70
- for nb < n {
72
+ for fnb < n {
71
73
c, err := fr.ReadByte()
72
74
if err != nil {
73
- f.b = b
74
- f.nb = nb
75
+ f.b, f.nb = fb, fnb
75
76
f.err = noEOF(err)
76
77
return
77
78
}
78
79
f.roffset++
79
- b |= uint32(c) << (nb & regSizeMaskUint32)
80
- nb += 8
80
+ fb |= uint32(c) << (fnb & regSizeMaskUint32)
81
+ fnb += 8
81
82
}
82
- chunk := f.hl.chunks[b &(huffmanNumChunks-1)]
83
+ chunk := f.hl.chunks[fb &(huffmanNumChunks-1)]
83
84
n = uint(chunk & huffmanCountMask)
84
85
if n > huffmanChunkBits {
85
- chunk = f.hl.links[chunk>>huffmanValueShift][(b >>huffmanChunkBits)&f.hl.linkMask]
86
+ chunk = f.hl.links[chunk>>huffmanValueShift][(fb >>huffmanChunkBits)&f.hl.linkMask]
86
87
n = uint(chunk & huffmanCountMask)
87
88
}
88
- if n <= nb {
89
+ if n <= fnb {
89
90
if n == 0 {
90
- f.b = b
91
- f.nb = nb
91
+ f.b, f.nb = fb, fnb
92
92
if debugDecode {
93
93
fmt.Println("huffsym: n==0")
94
94
}
95
95
f.err = CorruptInputError(f.roffset)
96
96
return
97
97
}
98
- f.b = b >> (n & regSizeMaskUint32)
99
- f.nb = nb - n
98
+ fb = fb >> (n & regSizeMaskUint32)
99
+ fnb = fnb - n
100
100
v = int(chunk >> huffmanValueShift)
101
101
break
102
102
}
@@ -111,10 +111,12 @@ readLiteral:
111
111
f.toRead = f.dict.readFlush()
112
112
f.step = (*decompressor).$FUNCNAME$
113
113
f.stepState = stateInit
114
+ f.b, f.nb = fb, fnb
114
115
return
115
116
}
116
117
goto readLiteral
117
118
case v == 256:
119
+ f.b, f.nb = fb, fnb
118
120
f.finishBlock()
119
121
return
120
122
// otherwise, reference to older data
@@ -124,48 +126,51 @@ readLiteral:
124
126
val := decCodeToLen[(v - 257)]
125
127
length = int(val.length) + 3
126
128
n := uint(val.extra)
127
- for f.nb < n {
129
+ for fnb < n {
128
130
c, err := fr.ReadByte()
129
131
if err != nil {
132
+ f.b, f.nb = fb, fnb
130
133
if debugDecode {
131
134
fmt.Println("morebits n>0:", err)
132
135
}
133
136
f.err = err
134
137
return
135
138
}
136
139
f.roffset++
137
- f.b |= uint32(c) << f.nb
138
- f.nb += 8
140
+ fb |= uint32(c) << (fnb®SizeMaskUint32)
141
+ fnb += 8
139
142
}
140
- length += int(f.b & uint32(1<<(n®SizeMaskUint32)-1) )
141
- f.b >>= n & regSizeMaskUint32
142
- f.nb -= n
143
+ length += int(fb & bitMask32[n] )
144
+ fb >>= n & regSizeMaskUint32
145
+ fnb -= n
143
146
default:
144
147
if debugDecode {
145
148
fmt.Println(v, ">= maxNumLit")
146
149
}
147
150
f.err = CorruptInputError(f.roffset)
151
+ f.b, f.nb = fb, fnb
148
152
return
149
153
}
150
154
151
155
var dist uint32
152
156
if f.hd == nil {
153
- for f.nb < 5 {
157
+ for fnb < 5 {
154
158
c, err := fr.ReadByte()
155
159
if err != nil {
160
+ f.b, f.nb = fb, fnb
156
161
if debugDecode {
157
162
fmt.Println("morebits f.nb<5:", err)
158
163
}
159
164
f.err = err
160
165
return
161
166
}
162
167
f.roffset++
163
- f.b |= uint32(c) << f.nb
164
- f.nb += 8
168
+ fb |= uint32(c) << (fnb®SizeMaskUint32)
169
+ fnb += 8
165
170
}
166
- dist = uint32(bits.Reverse8(uint8(f.b & 0x1F << 3)))
167
- f.b >>= 5
168
- f.nb -= 5
171
+ dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))
172
+ fb >>= 5
173
+ fnb -= 5
169
174
} else {
170
175
// Since a huffmanDecoder can be empty or be composed of a degenerate tree
171
176
// with single element, huffSym must error on these two edge cases. In both
@@ -175,38 +180,35 @@ readLiteral:
175
180
// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
176
181
// but is smart enough to keep local variables in registers, so use nb and b,
177
182
// inline call to moreBits and reassign b,nb back to f on return.
178
- nb, b := f.nb, f.b
179
183
for {
180
- for nb < n {
184
+ for fnb < n {
181
185
c, err := fr.ReadByte()
182
186
if err != nil {
183
- f.b = b
184
- f.nb = nb
187
+ f.b, f.nb = fb, fnb
185
188
f.err = noEOF(err)
186
189
return
187
190
}
188
191
f.roffset++
189
- b |= uint32(c) << (nb & regSizeMaskUint32)
190
- nb += 8
192
+ fb |= uint32(c) << (fnb & regSizeMaskUint32)
193
+ fnb += 8
191
194
}
192
- chunk := f.hd.chunks[b &(huffmanNumChunks-1)]
195
+ chunk := f.hd.chunks[fb &(huffmanNumChunks-1)]
193
196
n = uint(chunk & huffmanCountMask)
194
197
if n > huffmanChunkBits {
195
- chunk = f.hd.links[chunk>>huffmanValueShift][(b >>huffmanChunkBits)&f.hd.linkMask]
198
+ chunk = f.hd.links[chunk>>huffmanValueShift][(fb >>huffmanChunkBits)&f.hd.linkMask]
196
199
n = uint(chunk & huffmanCountMask)
197
200
}
198
- if n <= nb {
201
+ if n <= fnb {
199
202
if n == 0 {
200
- f.b = b
201
- f.nb = nb
203
+ f.b, f.nb = fb, fnb
202
204
if debugDecode {
203
205
fmt.Println("huffsym: n==0")
204
206
}
205
207
f.err = CorruptInputError(f.roffset)
206
208
return
207
209
}
208
- f.b = b >> (n & regSizeMaskUint32)
209
- f.nb = nb - n
210
+ fb = fb >> (n & regSizeMaskUint32)
211
+ fnb = fnb - n
210
212
dist = uint32(chunk >> huffmanValueShift)
211
213
break
212
214
}
@@ -220,24 +222,27 @@ readLiteral:
220
222
nb := uint(dist-2) >> 1
221
223
// have 1 bit in bottom of dist, need nb more.
222
224
extra := (dist & 1) << (nb & regSizeMaskUint32)
223
- for f.nb < nb {
225
+ for fnb < nb {
224
226
c, err := fr.ReadByte()
225
227
if err != nil {
228
+ f.b, f.nb = fb, fnb
226
229
if debugDecode {
227
230
fmt.Println("morebits f.nb<nb:", err)
228
231
}
229
232
f.err = err
230
233
return
231
234
}
232
235
f.roffset++
233
- f.b |= uint32(c) << f.nb
234
- f.nb += 8
236
+ fb |= uint32(c) << (fnb®SizeMaskUint32)
237
+ fnb += 8
235
238
}
236
- extra |= f.b & uint32(1<<(nb®SizeMaskUint32)-1)
237
- f.b >>= nb & regSizeMaskUint32
238
- f.nb -= nb
239
+ extra |= fb & bitMask32[nb]
240
+ fb >>= nb & regSizeMaskUint32
241
+ fnb -= nb
239
242
dist = 1<<((nb+1)®SizeMaskUint32) + 1 + extra
243
+ // slower: dist = bitMask32[nb+1] + 2 + extra
240
244
default:
245
+ f.b, f.nb = fb, fnb
241
246
if debugDecode {
242
247
fmt.Println("dist too big:", dist, maxNumDist)
243
248
}
@@ -247,6 +252,7 @@ readLiteral:
247
252
248
253
// No check on length; encoding can be prescient.
249
254
if dist > uint32(f.dict.histSize()) {
255
+ f.b, f.nb = fb, fnb
250
256
if debugDecode {
251
257
fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize())
252
258
}
@@ -271,10 +277,12 @@ copyHistory:
271
277
f.toRead = f.dict.readFlush()
272
278
f.step = (*decompressor).$FUNCNAME$ // We need to continue this work
273
279
f.stepState = stateDict
280
+ f.b, f.nb = fb, fnb
274
281
return
275
282
}
276
283
goto readLiteral
277
284
}
285
+ // Not reached
278
286
}
279
287
280
288
`
@@ -290,6 +298,6 @@ copyHistory:
290
298
f .WriteString ("\t \t \t return f.huffman" + names [i ] + "\n " )
291
299
}
292
300
f .WriteString ("\t \t default:\n " )
293
- f .WriteString ("\t \t \t return f.huffmanBlockGeneric " )
301
+ f .WriteString ("\t \t \t return f.huffmanGenericReader \n " )
294
302
f .WriteString ("\t }\n }\n " )
295
303
}
0 commit comments