gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

inflate_gen.go (32522B)


      1 // Code generated by go generate gen_inflate.go. DO NOT EDIT.
      2 
      3 package flate
      4 
      5 import (
      6 	"bufio"
      7 	"bytes"
      8 	"fmt"
      9 	"math/bits"
     10 	"strings"
     11 )
     12 
     13 // Decode a single Huffman block from f.
     14 // hl and hd are the Huffman states for the lit/length values
     15 // and the distance values, respectively. If hd == nil, using the
     16 // fixed distance encoding associated with fixed Huffman blocks.
     17 func (f *decompressor) huffmanBytesBuffer() {
     18 	const (
     19 		stateInit = iota // Zero value must be stateInit
     20 		stateDict
     21 	)
     22 	fr := f.r.(*bytes.Buffer)
     23 
     24 	// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
     25 	// but is smart enough to keep local variables in registers, so use nb and b,
     26 	// inline call to moreBits and reassign b,nb back to f on return.
     27 	fnb, fb, dict := f.nb, f.b, &f.dict
     28 
     29 	switch f.stepState {
     30 	case stateInit:
     31 		goto readLiteral
     32 	case stateDict:
     33 		goto copyHistory
     34 	}
     35 
     36 readLiteral:
     37 	// Read literal and/or (length, distance) according to RFC section 3.2.3.
     38 	{
     39 		var v int
     40 		{
     41 			// Inlined v, err := f.huffSym(f.hl)
     42 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
     43 			// with single element, huffSym must error on these two edge cases. In both
     44 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
     45 			// satisfy the n == 0 check below.
     46 			n := uint(f.hl.maxRead)
     47 			for {
     48 				for fnb < n {
     49 					c, err := fr.ReadByte()
     50 					if err != nil {
     51 						f.b, f.nb = fb, fnb
     52 						f.err = noEOF(err)
     53 						return
     54 					}
     55 					f.roffset++
     56 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
     57 					fnb += 8
     58 				}
     59 				chunk := f.hl.chunks[fb&(huffmanNumChunks-1)]
     60 				n = uint(chunk & huffmanCountMask)
     61 				if n > huffmanChunkBits {
     62 					chunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]
     63 					n = uint(chunk & huffmanCountMask)
     64 				}
     65 				if n <= fnb {
     66 					if n == 0 {
     67 						f.b, f.nb = fb, fnb
     68 						if debugDecode {
     69 							fmt.Println("huffsym: n==0")
     70 						}
     71 						f.err = CorruptInputError(f.roffset)
     72 						return
     73 					}
     74 					fb = fb >> (n & regSizeMaskUint32)
     75 					fnb = fnb - n
     76 					v = int(chunk >> huffmanValueShift)
     77 					break
     78 				}
     79 			}
     80 		}
     81 
     82 		var length int
     83 		switch {
     84 		case v < 256:
     85 			dict.writeByte(byte(v))
     86 			if dict.availWrite() == 0 {
     87 				f.toRead = dict.readFlush()
     88 				f.step = (*decompressor).huffmanBytesBuffer
     89 				f.stepState = stateInit
     90 				f.b, f.nb = fb, fnb
     91 				return
     92 			}
     93 			goto readLiteral
     94 		case v == 256:
     95 			f.b, f.nb = fb, fnb
     96 			f.finishBlock()
     97 			return
     98 		// otherwise, reference to older data
     99 		case v < 265:
    100 			length = v - (257 - 3)
    101 		case v < maxNumLit:
    102 			val := decCodeToLen[(v - 257)]
    103 			length = int(val.length) + 3
    104 			n := uint(val.extra)
    105 			for fnb < n {
    106 				c, err := fr.ReadByte()
    107 				if err != nil {
    108 					f.b, f.nb = fb, fnb
    109 					if debugDecode {
    110 						fmt.Println("morebits n>0:", err)
    111 					}
    112 					f.err = err
    113 					return
    114 				}
    115 				f.roffset++
    116 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    117 				fnb += 8
    118 			}
    119 			length += int(fb & bitMask32[n])
    120 			fb >>= n & regSizeMaskUint32
    121 			fnb -= n
    122 		default:
    123 			if debugDecode {
    124 				fmt.Println(v, ">= maxNumLit")
    125 			}
    126 			f.err = CorruptInputError(f.roffset)
    127 			f.b, f.nb = fb, fnb
    128 			return
    129 		}
    130 
    131 		var dist uint32
    132 		if f.hd == nil {
    133 			for fnb < 5 {
    134 				c, err := fr.ReadByte()
    135 				if err != nil {
    136 					f.b, f.nb = fb, fnb
    137 					if debugDecode {
    138 						fmt.Println("morebits f.nb<5:", err)
    139 					}
    140 					f.err = err
    141 					return
    142 				}
    143 				f.roffset++
    144 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    145 				fnb += 8
    146 			}
    147 			dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))
    148 			fb >>= 5
    149 			fnb -= 5
    150 		} else {
    151 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
    152 			// with single element, huffSym must error on these two edge cases. In both
    153 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
    154 			// satisfy the n == 0 check below.
    155 			n := uint(f.hd.maxRead)
    156 			// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
    157 			// but is smart enough to keep local variables in registers, so use nb and b,
    158 			// inline call to moreBits and reassign b,nb back to f on return.
    159 			for {
    160 				for fnb < n {
    161 					c, err := fr.ReadByte()
    162 					if err != nil {
    163 						f.b, f.nb = fb, fnb
    164 						f.err = noEOF(err)
    165 						return
    166 					}
    167 					f.roffset++
    168 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
    169 					fnb += 8
    170 				}
    171 				chunk := f.hd.chunks[fb&(huffmanNumChunks-1)]
    172 				n = uint(chunk & huffmanCountMask)
    173 				if n > huffmanChunkBits {
    174 					chunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]
    175 					n = uint(chunk & huffmanCountMask)
    176 				}
    177 				if n <= fnb {
    178 					if n == 0 {
    179 						f.b, f.nb = fb, fnb
    180 						if debugDecode {
    181 							fmt.Println("huffsym: n==0")
    182 						}
    183 						f.err = CorruptInputError(f.roffset)
    184 						return
    185 					}
    186 					fb = fb >> (n & regSizeMaskUint32)
    187 					fnb = fnb - n
    188 					dist = uint32(chunk >> huffmanValueShift)
    189 					break
    190 				}
    191 			}
    192 		}
    193 
    194 		switch {
    195 		case dist < 4:
    196 			dist++
    197 		case dist < maxNumDist:
    198 			nb := uint(dist-2) >> 1
    199 			// have 1 bit in bottom of dist, need nb more.
    200 			extra := (dist & 1) << (nb & regSizeMaskUint32)
    201 			for fnb < nb {
    202 				c, err := fr.ReadByte()
    203 				if err != nil {
    204 					f.b, f.nb = fb, fnb
    205 					if debugDecode {
    206 						fmt.Println("morebits f.nb<nb:", err)
    207 					}
    208 					f.err = err
    209 					return
    210 				}
    211 				f.roffset++
    212 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    213 				fnb += 8
    214 			}
    215 			extra |= fb & bitMask32[nb]
    216 			fb >>= nb & regSizeMaskUint32
    217 			fnb -= nb
    218 			dist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra
    219 			// slower: dist = bitMask32[nb+1] + 2 + extra
    220 		default:
    221 			f.b, f.nb = fb, fnb
    222 			if debugDecode {
    223 				fmt.Println("dist too big:", dist, maxNumDist)
    224 			}
    225 			f.err = CorruptInputError(f.roffset)
    226 			return
    227 		}
    228 
    229 		// No check on length; encoding can be prescient.
    230 		if dist > uint32(dict.histSize()) {
    231 			f.b, f.nb = fb, fnb
    232 			if debugDecode {
    233 				fmt.Println("dist > dict.histSize():", dist, dict.histSize())
    234 			}
    235 			f.err = CorruptInputError(f.roffset)
    236 			return
    237 		}
    238 
    239 		f.copyLen, f.copyDist = length, int(dist)
    240 		goto copyHistory
    241 	}
    242 
    243 copyHistory:
    244 	// Perform a backwards copy according to RFC section 3.2.3.
    245 	{
    246 		cnt := dict.tryWriteCopy(f.copyDist, f.copyLen)
    247 		if cnt == 0 {
    248 			cnt = dict.writeCopy(f.copyDist, f.copyLen)
    249 		}
    250 		f.copyLen -= cnt
    251 
    252 		if dict.availWrite() == 0 || f.copyLen > 0 {
    253 			f.toRead = dict.readFlush()
    254 			f.step = (*decompressor).huffmanBytesBuffer // We need to continue this work
    255 			f.stepState = stateDict
    256 			f.b, f.nb = fb, fnb
    257 			return
    258 		}
    259 		goto readLiteral
    260 	}
    261 	// Not reached
    262 }
    263 
    264 // Decode a single Huffman block from f.
    265 // hl and hd are the Huffman states for the lit/length values
    266 // and the distance values, respectively. If hd == nil, using the
    267 // fixed distance encoding associated with fixed Huffman blocks.
    268 func (f *decompressor) huffmanBytesReader() {
    269 	const (
    270 		stateInit = iota // Zero value must be stateInit
    271 		stateDict
    272 	)
    273 	fr := f.r.(*bytes.Reader)
    274 
    275 	// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
    276 	// but is smart enough to keep local variables in registers, so use nb and b,
    277 	// inline call to moreBits and reassign b,nb back to f on return.
    278 	fnb, fb, dict := f.nb, f.b, &f.dict
    279 
    280 	switch f.stepState {
    281 	case stateInit:
    282 		goto readLiteral
    283 	case stateDict:
    284 		goto copyHistory
    285 	}
    286 
    287 readLiteral:
    288 	// Read literal and/or (length, distance) according to RFC section 3.2.3.
    289 	{
    290 		var v int
    291 		{
    292 			// Inlined v, err := f.huffSym(f.hl)
    293 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
    294 			// with single element, huffSym must error on these two edge cases. In both
    295 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
    296 			// satisfy the n == 0 check below.
    297 			n := uint(f.hl.maxRead)
    298 			for {
    299 				for fnb < n {
    300 					c, err := fr.ReadByte()
    301 					if err != nil {
    302 						f.b, f.nb = fb, fnb
    303 						f.err = noEOF(err)
    304 						return
    305 					}
    306 					f.roffset++
    307 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
    308 					fnb += 8
    309 				}
    310 				chunk := f.hl.chunks[fb&(huffmanNumChunks-1)]
    311 				n = uint(chunk & huffmanCountMask)
    312 				if n > huffmanChunkBits {
    313 					chunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]
    314 					n = uint(chunk & huffmanCountMask)
    315 				}
    316 				if n <= fnb {
    317 					if n == 0 {
    318 						f.b, f.nb = fb, fnb
    319 						if debugDecode {
    320 							fmt.Println("huffsym: n==0")
    321 						}
    322 						f.err = CorruptInputError(f.roffset)
    323 						return
    324 					}
    325 					fb = fb >> (n & regSizeMaskUint32)
    326 					fnb = fnb - n
    327 					v = int(chunk >> huffmanValueShift)
    328 					break
    329 				}
    330 			}
    331 		}
    332 
    333 		var length int
    334 		switch {
    335 		case v < 256:
    336 			dict.writeByte(byte(v))
    337 			if dict.availWrite() == 0 {
    338 				f.toRead = dict.readFlush()
    339 				f.step = (*decompressor).huffmanBytesReader
    340 				f.stepState = stateInit
    341 				f.b, f.nb = fb, fnb
    342 				return
    343 			}
    344 			goto readLiteral
    345 		case v == 256:
    346 			f.b, f.nb = fb, fnb
    347 			f.finishBlock()
    348 			return
    349 		// otherwise, reference to older data
    350 		case v < 265:
    351 			length = v - (257 - 3)
    352 		case v < maxNumLit:
    353 			val := decCodeToLen[(v - 257)]
    354 			length = int(val.length) + 3
    355 			n := uint(val.extra)
    356 			for fnb < n {
    357 				c, err := fr.ReadByte()
    358 				if err != nil {
    359 					f.b, f.nb = fb, fnb
    360 					if debugDecode {
    361 						fmt.Println("morebits n>0:", err)
    362 					}
    363 					f.err = err
    364 					return
    365 				}
    366 				f.roffset++
    367 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    368 				fnb += 8
    369 			}
    370 			length += int(fb & bitMask32[n])
    371 			fb >>= n & regSizeMaskUint32
    372 			fnb -= n
    373 		default:
    374 			if debugDecode {
    375 				fmt.Println(v, ">= maxNumLit")
    376 			}
    377 			f.err = CorruptInputError(f.roffset)
    378 			f.b, f.nb = fb, fnb
    379 			return
    380 		}
    381 
    382 		var dist uint32
    383 		if f.hd == nil {
    384 			for fnb < 5 {
    385 				c, err := fr.ReadByte()
    386 				if err != nil {
    387 					f.b, f.nb = fb, fnb
    388 					if debugDecode {
    389 						fmt.Println("morebits f.nb<5:", err)
    390 					}
    391 					f.err = err
    392 					return
    393 				}
    394 				f.roffset++
    395 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    396 				fnb += 8
    397 			}
    398 			dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))
    399 			fb >>= 5
    400 			fnb -= 5
    401 		} else {
    402 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
    403 			// with single element, huffSym must error on these two edge cases. In both
    404 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
    405 			// satisfy the n == 0 check below.
    406 			n := uint(f.hd.maxRead)
    407 			// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
    408 			// but is smart enough to keep local variables in registers, so use nb and b,
    409 			// inline call to moreBits and reassign b,nb back to f on return.
    410 			for {
    411 				for fnb < n {
    412 					c, err := fr.ReadByte()
    413 					if err != nil {
    414 						f.b, f.nb = fb, fnb
    415 						f.err = noEOF(err)
    416 						return
    417 					}
    418 					f.roffset++
    419 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
    420 					fnb += 8
    421 				}
    422 				chunk := f.hd.chunks[fb&(huffmanNumChunks-1)]
    423 				n = uint(chunk & huffmanCountMask)
    424 				if n > huffmanChunkBits {
    425 					chunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]
    426 					n = uint(chunk & huffmanCountMask)
    427 				}
    428 				if n <= fnb {
    429 					if n == 0 {
    430 						f.b, f.nb = fb, fnb
    431 						if debugDecode {
    432 							fmt.Println("huffsym: n==0")
    433 						}
    434 						f.err = CorruptInputError(f.roffset)
    435 						return
    436 					}
    437 					fb = fb >> (n & regSizeMaskUint32)
    438 					fnb = fnb - n
    439 					dist = uint32(chunk >> huffmanValueShift)
    440 					break
    441 				}
    442 			}
    443 		}
    444 
    445 		switch {
    446 		case dist < 4:
    447 			dist++
    448 		case dist < maxNumDist:
    449 			nb := uint(dist-2) >> 1
    450 			// have 1 bit in bottom of dist, need nb more.
    451 			extra := (dist & 1) << (nb & regSizeMaskUint32)
    452 			for fnb < nb {
    453 				c, err := fr.ReadByte()
    454 				if err != nil {
    455 					f.b, f.nb = fb, fnb
    456 					if debugDecode {
    457 						fmt.Println("morebits f.nb<nb:", err)
    458 					}
    459 					f.err = err
    460 					return
    461 				}
    462 				f.roffset++
    463 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    464 				fnb += 8
    465 			}
    466 			extra |= fb & bitMask32[nb]
    467 			fb >>= nb & regSizeMaskUint32
    468 			fnb -= nb
    469 			dist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra
    470 			// slower: dist = bitMask32[nb+1] + 2 + extra
    471 		default:
    472 			f.b, f.nb = fb, fnb
    473 			if debugDecode {
    474 				fmt.Println("dist too big:", dist, maxNumDist)
    475 			}
    476 			f.err = CorruptInputError(f.roffset)
    477 			return
    478 		}
    479 
    480 		// No check on length; encoding can be prescient.
    481 		if dist > uint32(dict.histSize()) {
    482 			f.b, f.nb = fb, fnb
    483 			if debugDecode {
    484 				fmt.Println("dist > dict.histSize():", dist, dict.histSize())
    485 			}
    486 			f.err = CorruptInputError(f.roffset)
    487 			return
    488 		}
    489 
    490 		f.copyLen, f.copyDist = length, int(dist)
    491 		goto copyHistory
    492 	}
    493 
    494 copyHistory:
    495 	// Perform a backwards copy according to RFC section 3.2.3.
    496 	{
    497 		cnt := dict.tryWriteCopy(f.copyDist, f.copyLen)
    498 		if cnt == 0 {
    499 			cnt = dict.writeCopy(f.copyDist, f.copyLen)
    500 		}
    501 		f.copyLen -= cnt
    502 
    503 		if dict.availWrite() == 0 || f.copyLen > 0 {
    504 			f.toRead = dict.readFlush()
    505 			f.step = (*decompressor).huffmanBytesReader // We need to continue this work
    506 			f.stepState = stateDict
    507 			f.b, f.nb = fb, fnb
    508 			return
    509 		}
    510 		goto readLiteral
    511 	}
    512 	// Not reached
    513 }
    514 
    515 // Decode a single Huffman block from f.
    516 // hl and hd are the Huffman states for the lit/length values
    517 // and the distance values, respectively. If hd == nil, using the
    518 // fixed distance encoding associated with fixed Huffman blocks.
    519 func (f *decompressor) huffmanBufioReader() {
    520 	const (
    521 		stateInit = iota // Zero value must be stateInit
    522 		stateDict
    523 	)
    524 	fr := f.r.(*bufio.Reader)
    525 
    526 	// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
    527 	// but is smart enough to keep local variables in registers, so use nb and b,
    528 	// inline call to moreBits and reassign b,nb back to f on return.
    529 	fnb, fb, dict := f.nb, f.b, &f.dict
    530 
    531 	switch f.stepState {
    532 	case stateInit:
    533 		goto readLiteral
    534 	case stateDict:
    535 		goto copyHistory
    536 	}
    537 
    538 readLiteral:
    539 	// Read literal and/or (length, distance) according to RFC section 3.2.3.
    540 	{
    541 		var v int
    542 		{
    543 			// Inlined v, err := f.huffSym(f.hl)
    544 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
    545 			// with single element, huffSym must error on these two edge cases. In both
    546 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
    547 			// satisfy the n == 0 check below.
    548 			n := uint(f.hl.maxRead)
    549 			for {
    550 				for fnb < n {
    551 					c, err := fr.ReadByte()
    552 					if err != nil {
    553 						f.b, f.nb = fb, fnb
    554 						f.err = noEOF(err)
    555 						return
    556 					}
    557 					f.roffset++
    558 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
    559 					fnb += 8
    560 				}
    561 				chunk := f.hl.chunks[fb&(huffmanNumChunks-1)]
    562 				n = uint(chunk & huffmanCountMask)
    563 				if n > huffmanChunkBits {
    564 					chunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]
    565 					n = uint(chunk & huffmanCountMask)
    566 				}
    567 				if n <= fnb {
    568 					if n == 0 {
    569 						f.b, f.nb = fb, fnb
    570 						if debugDecode {
    571 							fmt.Println("huffsym: n==0")
    572 						}
    573 						f.err = CorruptInputError(f.roffset)
    574 						return
    575 					}
    576 					fb = fb >> (n & regSizeMaskUint32)
    577 					fnb = fnb - n
    578 					v = int(chunk >> huffmanValueShift)
    579 					break
    580 				}
    581 			}
    582 		}
    583 
    584 		var length int
    585 		switch {
    586 		case v < 256:
    587 			dict.writeByte(byte(v))
    588 			if dict.availWrite() == 0 {
    589 				f.toRead = dict.readFlush()
    590 				f.step = (*decompressor).huffmanBufioReader
    591 				f.stepState = stateInit
    592 				f.b, f.nb = fb, fnb
    593 				return
    594 			}
    595 			goto readLiteral
    596 		case v == 256:
    597 			f.b, f.nb = fb, fnb
    598 			f.finishBlock()
    599 			return
    600 		// otherwise, reference to older data
    601 		case v < 265:
    602 			length = v - (257 - 3)
    603 		case v < maxNumLit:
    604 			val := decCodeToLen[(v - 257)]
    605 			length = int(val.length) + 3
    606 			n := uint(val.extra)
    607 			for fnb < n {
    608 				c, err := fr.ReadByte()
    609 				if err != nil {
    610 					f.b, f.nb = fb, fnb
    611 					if debugDecode {
    612 						fmt.Println("morebits n>0:", err)
    613 					}
    614 					f.err = err
    615 					return
    616 				}
    617 				f.roffset++
    618 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    619 				fnb += 8
    620 			}
    621 			length += int(fb & bitMask32[n])
    622 			fb >>= n & regSizeMaskUint32
    623 			fnb -= n
    624 		default:
    625 			if debugDecode {
    626 				fmt.Println(v, ">= maxNumLit")
    627 			}
    628 			f.err = CorruptInputError(f.roffset)
    629 			f.b, f.nb = fb, fnb
    630 			return
    631 		}
    632 
    633 		var dist uint32
    634 		if f.hd == nil {
    635 			for fnb < 5 {
    636 				c, err := fr.ReadByte()
    637 				if err != nil {
    638 					f.b, f.nb = fb, fnb
    639 					if debugDecode {
    640 						fmt.Println("morebits f.nb<5:", err)
    641 					}
    642 					f.err = err
    643 					return
    644 				}
    645 				f.roffset++
    646 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    647 				fnb += 8
    648 			}
    649 			dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))
    650 			fb >>= 5
    651 			fnb -= 5
    652 		} else {
    653 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
    654 			// with single element, huffSym must error on these two edge cases. In both
    655 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
    656 			// satisfy the n == 0 check below.
    657 			n := uint(f.hd.maxRead)
    658 			// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
    659 			// but is smart enough to keep local variables in registers, so use nb and b,
    660 			// inline call to moreBits and reassign b,nb back to f on return.
    661 			for {
    662 				for fnb < n {
    663 					c, err := fr.ReadByte()
    664 					if err != nil {
    665 						f.b, f.nb = fb, fnb
    666 						f.err = noEOF(err)
    667 						return
    668 					}
    669 					f.roffset++
    670 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
    671 					fnb += 8
    672 				}
    673 				chunk := f.hd.chunks[fb&(huffmanNumChunks-1)]
    674 				n = uint(chunk & huffmanCountMask)
    675 				if n > huffmanChunkBits {
    676 					chunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]
    677 					n = uint(chunk & huffmanCountMask)
    678 				}
    679 				if n <= fnb {
    680 					if n == 0 {
    681 						f.b, f.nb = fb, fnb
    682 						if debugDecode {
    683 							fmt.Println("huffsym: n==0")
    684 						}
    685 						f.err = CorruptInputError(f.roffset)
    686 						return
    687 					}
    688 					fb = fb >> (n & regSizeMaskUint32)
    689 					fnb = fnb - n
    690 					dist = uint32(chunk >> huffmanValueShift)
    691 					break
    692 				}
    693 			}
    694 		}
    695 
    696 		switch {
    697 		case dist < 4:
    698 			dist++
    699 		case dist < maxNumDist:
    700 			nb := uint(dist-2) >> 1
    701 			// have 1 bit in bottom of dist, need nb more.
    702 			extra := (dist & 1) << (nb & regSizeMaskUint32)
    703 			for fnb < nb {
    704 				c, err := fr.ReadByte()
    705 				if err != nil {
    706 					f.b, f.nb = fb, fnb
    707 					if debugDecode {
    708 						fmt.Println("morebits f.nb<nb:", err)
    709 					}
    710 					f.err = err
    711 					return
    712 				}
    713 				f.roffset++
    714 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    715 				fnb += 8
    716 			}
    717 			extra |= fb & bitMask32[nb]
    718 			fb >>= nb & regSizeMaskUint32
    719 			fnb -= nb
    720 			dist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra
    721 			// slower: dist = bitMask32[nb+1] + 2 + extra
    722 		default:
    723 			f.b, f.nb = fb, fnb
    724 			if debugDecode {
    725 				fmt.Println("dist too big:", dist, maxNumDist)
    726 			}
    727 			f.err = CorruptInputError(f.roffset)
    728 			return
    729 		}
    730 
    731 		// No check on length; encoding can be prescient.
    732 		if dist > uint32(dict.histSize()) {
    733 			f.b, f.nb = fb, fnb
    734 			if debugDecode {
    735 				fmt.Println("dist > dict.histSize():", dist, dict.histSize())
    736 			}
    737 			f.err = CorruptInputError(f.roffset)
    738 			return
    739 		}
    740 
    741 		f.copyLen, f.copyDist = length, int(dist)
    742 		goto copyHistory
    743 	}
    744 
    745 copyHistory:
    746 	// Perform a backwards copy according to RFC section 3.2.3.
    747 	{
    748 		cnt := dict.tryWriteCopy(f.copyDist, f.copyLen)
    749 		if cnt == 0 {
    750 			cnt = dict.writeCopy(f.copyDist, f.copyLen)
    751 		}
    752 		f.copyLen -= cnt
    753 
    754 		if dict.availWrite() == 0 || f.copyLen > 0 {
    755 			f.toRead = dict.readFlush()
    756 			f.step = (*decompressor).huffmanBufioReader // We need to continue this work
    757 			f.stepState = stateDict
    758 			f.b, f.nb = fb, fnb
    759 			return
    760 		}
    761 		goto readLiteral
    762 	}
    763 	// Not reached
    764 }
    765 
    766 // Decode a single Huffman block from f.
    767 // hl and hd are the Huffman states for the lit/length values
    768 // and the distance values, respectively. If hd == nil, using the
    769 // fixed distance encoding associated with fixed Huffman blocks.
    770 func (f *decompressor) huffmanStringsReader() {
    771 	const (
    772 		stateInit = iota // Zero value must be stateInit
    773 		stateDict
    774 	)
    775 	fr := f.r.(*strings.Reader)
    776 
    777 	// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
    778 	// but is smart enough to keep local variables in registers, so use nb and b,
    779 	// inline call to moreBits and reassign b,nb back to f on return.
    780 	fnb, fb, dict := f.nb, f.b, &f.dict
    781 
    782 	switch f.stepState {
    783 	case stateInit:
    784 		goto readLiteral
    785 	case stateDict:
    786 		goto copyHistory
    787 	}
    788 
    789 readLiteral:
    790 	// Read literal and/or (length, distance) according to RFC section 3.2.3.
    791 	{
    792 		var v int
    793 		{
    794 			// Inlined v, err := f.huffSym(f.hl)
    795 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
    796 			// with single element, huffSym must error on these two edge cases. In both
    797 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
    798 			// satisfy the n == 0 check below.
    799 			n := uint(f.hl.maxRead)
    800 			for {
    801 				for fnb < n {
    802 					c, err := fr.ReadByte()
    803 					if err != nil {
    804 						f.b, f.nb = fb, fnb
    805 						f.err = noEOF(err)
    806 						return
    807 					}
    808 					f.roffset++
    809 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
    810 					fnb += 8
    811 				}
    812 				chunk := f.hl.chunks[fb&(huffmanNumChunks-1)]
    813 				n = uint(chunk & huffmanCountMask)
    814 				if n > huffmanChunkBits {
    815 					chunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]
    816 					n = uint(chunk & huffmanCountMask)
    817 				}
    818 				if n <= fnb {
    819 					if n == 0 {
    820 						f.b, f.nb = fb, fnb
    821 						if debugDecode {
    822 							fmt.Println("huffsym: n==0")
    823 						}
    824 						f.err = CorruptInputError(f.roffset)
    825 						return
    826 					}
    827 					fb = fb >> (n & regSizeMaskUint32)
    828 					fnb = fnb - n
    829 					v = int(chunk >> huffmanValueShift)
    830 					break
    831 				}
    832 			}
    833 		}
    834 
    835 		var length int
    836 		switch {
    837 		case v < 256:
    838 			dict.writeByte(byte(v))
    839 			if dict.availWrite() == 0 {
    840 				f.toRead = dict.readFlush()
    841 				f.step = (*decompressor).huffmanStringsReader
    842 				f.stepState = stateInit
    843 				f.b, f.nb = fb, fnb
    844 				return
    845 			}
    846 			goto readLiteral
    847 		case v == 256:
    848 			f.b, f.nb = fb, fnb
    849 			f.finishBlock()
    850 			return
    851 		// otherwise, reference to older data
    852 		case v < 265:
    853 			length = v - (257 - 3)
    854 		case v < maxNumLit:
    855 			val := decCodeToLen[(v - 257)]
    856 			length = int(val.length) + 3
    857 			n := uint(val.extra)
    858 			for fnb < n {
    859 				c, err := fr.ReadByte()
    860 				if err != nil {
    861 					f.b, f.nb = fb, fnb
    862 					if debugDecode {
    863 						fmt.Println("morebits n>0:", err)
    864 					}
    865 					f.err = err
    866 					return
    867 				}
    868 				f.roffset++
    869 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    870 				fnb += 8
    871 			}
    872 			length += int(fb & bitMask32[n])
    873 			fb >>= n & regSizeMaskUint32
    874 			fnb -= n
    875 		default:
    876 			if debugDecode {
    877 				fmt.Println(v, ">= maxNumLit")
    878 			}
    879 			f.err = CorruptInputError(f.roffset)
    880 			f.b, f.nb = fb, fnb
    881 			return
    882 		}
    883 
    884 		var dist uint32
    885 		if f.hd == nil {
    886 			for fnb < 5 {
    887 				c, err := fr.ReadByte()
    888 				if err != nil {
    889 					f.b, f.nb = fb, fnb
    890 					if debugDecode {
    891 						fmt.Println("morebits f.nb<5:", err)
    892 					}
    893 					f.err = err
    894 					return
    895 				}
    896 				f.roffset++
    897 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    898 				fnb += 8
    899 			}
    900 			dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))
    901 			fb >>= 5
    902 			fnb -= 5
    903 		} else {
    904 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
    905 			// with single element, huffSym must error on these two edge cases. In both
    906 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
    907 			// satisfy the n == 0 check below.
    908 			n := uint(f.hd.maxRead)
    909 			// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
    910 			// but is smart enough to keep local variables in registers, so use nb and b,
    911 			// inline call to moreBits and reassign b,nb back to f on return.
    912 			for {
    913 				for fnb < n {
    914 					c, err := fr.ReadByte()
    915 					if err != nil {
    916 						f.b, f.nb = fb, fnb
    917 						f.err = noEOF(err)
    918 						return
    919 					}
    920 					f.roffset++
    921 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
    922 					fnb += 8
    923 				}
    924 				chunk := f.hd.chunks[fb&(huffmanNumChunks-1)]
    925 				n = uint(chunk & huffmanCountMask)
    926 				if n > huffmanChunkBits {
    927 					chunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]
    928 					n = uint(chunk & huffmanCountMask)
    929 				}
    930 				if n <= fnb {
    931 					if n == 0 {
    932 						f.b, f.nb = fb, fnb
    933 						if debugDecode {
    934 							fmt.Println("huffsym: n==0")
    935 						}
    936 						f.err = CorruptInputError(f.roffset)
    937 						return
    938 					}
    939 					fb = fb >> (n & regSizeMaskUint32)
    940 					fnb = fnb - n
    941 					dist = uint32(chunk >> huffmanValueShift)
    942 					break
    943 				}
    944 			}
    945 		}
    946 
    947 		switch {
    948 		case dist < 4:
    949 			dist++
    950 		case dist < maxNumDist:
    951 			nb := uint(dist-2) >> 1
    952 			// have 1 bit in bottom of dist, need nb more.
    953 			extra := (dist & 1) << (nb & regSizeMaskUint32)
    954 			for fnb < nb {
    955 				c, err := fr.ReadByte()
    956 				if err != nil {
    957 					f.b, f.nb = fb, fnb
    958 					if debugDecode {
    959 						fmt.Println("morebits f.nb<nb:", err)
    960 					}
    961 					f.err = err
    962 					return
    963 				}
    964 				f.roffset++
    965 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
    966 				fnb += 8
    967 			}
    968 			extra |= fb & bitMask32[nb]
    969 			fb >>= nb & regSizeMaskUint32
    970 			fnb -= nb
    971 			dist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra
    972 			// slower: dist = bitMask32[nb+1] + 2 + extra
    973 		default:
    974 			f.b, f.nb = fb, fnb
    975 			if debugDecode {
    976 				fmt.Println("dist too big:", dist, maxNumDist)
    977 			}
    978 			f.err = CorruptInputError(f.roffset)
    979 			return
    980 		}
    981 
    982 		// No check on length; encoding can be prescient.
    983 		if dist > uint32(dict.histSize()) {
    984 			f.b, f.nb = fb, fnb
    985 			if debugDecode {
    986 				fmt.Println("dist > dict.histSize():", dist, dict.histSize())
    987 			}
    988 			f.err = CorruptInputError(f.roffset)
    989 			return
    990 		}
    991 
    992 		f.copyLen, f.copyDist = length, int(dist)
    993 		goto copyHistory
    994 	}
    995 
    996 copyHistory:
    997 	// Perform a backwards copy according to RFC section 3.2.3.
    998 	{
    999 		cnt := dict.tryWriteCopy(f.copyDist, f.copyLen)
   1000 		if cnt == 0 {
   1001 			cnt = dict.writeCopy(f.copyDist, f.copyLen)
   1002 		}
   1003 		f.copyLen -= cnt
   1004 
   1005 		if dict.availWrite() == 0 || f.copyLen > 0 {
   1006 			f.toRead = dict.readFlush()
   1007 			f.step = (*decompressor).huffmanStringsReader // We need to continue this work
   1008 			f.stepState = stateDict
   1009 			f.b, f.nb = fb, fnb
   1010 			return
   1011 		}
   1012 		goto readLiteral
   1013 	}
   1014 	// Not reached
   1015 }
   1016 
   1017 // Decode a single Huffman block from f.
   1018 // hl and hd are the Huffman states for the lit/length values
   1019 // and the distance values, respectively. If hd == nil, using the
   1020 // fixed distance encoding associated with fixed Huffman blocks.
   1021 func (f *decompressor) huffmanGenericReader() {
   1022 	const (
   1023 		stateInit = iota // Zero value must be stateInit
   1024 		stateDict
   1025 	)
   1026 	fr := f.r.(Reader)
   1027 
   1028 	// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
   1029 	// but is smart enough to keep local variables in registers, so use nb and b,
   1030 	// inline call to moreBits and reassign b,nb back to f on return.
   1031 	fnb, fb, dict := f.nb, f.b, &f.dict
   1032 
   1033 	switch f.stepState {
   1034 	case stateInit:
   1035 		goto readLiteral
   1036 	case stateDict:
   1037 		goto copyHistory
   1038 	}
   1039 
   1040 readLiteral:
   1041 	// Read literal and/or (length, distance) according to RFC section 3.2.3.
   1042 	{
   1043 		var v int
   1044 		{
   1045 			// Inlined v, err := f.huffSym(f.hl)
   1046 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
   1047 			// with single element, huffSym must error on these two edge cases. In both
   1048 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
   1049 			// satisfy the n == 0 check below.
   1050 			n := uint(f.hl.maxRead)
   1051 			for {
   1052 				for fnb < n {
   1053 					c, err := fr.ReadByte()
   1054 					if err != nil {
   1055 						f.b, f.nb = fb, fnb
   1056 						f.err = noEOF(err)
   1057 						return
   1058 					}
   1059 					f.roffset++
   1060 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
   1061 					fnb += 8
   1062 				}
   1063 				chunk := f.hl.chunks[fb&(huffmanNumChunks-1)]
   1064 				n = uint(chunk & huffmanCountMask)
   1065 				if n > huffmanChunkBits {
   1066 					chunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]
   1067 					n = uint(chunk & huffmanCountMask)
   1068 				}
   1069 				if n <= fnb {
   1070 					if n == 0 {
   1071 						f.b, f.nb = fb, fnb
   1072 						if debugDecode {
   1073 							fmt.Println("huffsym: n==0")
   1074 						}
   1075 						f.err = CorruptInputError(f.roffset)
   1076 						return
   1077 					}
   1078 					fb = fb >> (n & regSizeMaskUint32)
   1079 					fnb = fnb - n
   1080 					v = int(chunk >> huffmanValueShift)
   1081 					break
   1082 				}
   1083 			}
   1084 		}
   1085 
   1086 		var length int
   1087 		switch {
   1088 		case v < 256:
   1089 			dict.writeByte(byte(v))
   1090 			if dict.availWrite() == 0 {
   1091 				f.toRead = dict.readFlush()
   1092 				f.step = (*decompressor).huffmanGenericReader
   1093 				f.stepState = stateInit
   1094 				f.b, f.nb = fb, fnb
   1095 				return
   1096 			}
   1097 			goto readLiteral
   1098 		case v == 256:
   1099 			f.b, f.nb = fb, fnb
   1100 			f.finishBlock()
   1101 			return
   1102 		// otherwise, reference to older data
   1103 		case v < 265:
   1104 			length = v - (257 - 3)
   1105 		case v < maxNumLit:
   1106 			val := decCodeToLen[(v - 257)]
   1107 			length = int(val.length) + 3
   1108 			n := uint(val.extra)
   1109 			for fnb < n {
   1110 				c, err := fr.ReadByte()
   1111 				if err != nil {
   1112 					f.b, f.nb = fb, fnb
   1113 					if debugDecode {
   1114 						fmt.Println("morebits n>0:", err)
   1115 					}
   1116 					f.err = err
   1117 					return
   1118 				}
   1119 				f.roffset++
   1120 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
   1121 				fnb += 8
   1122 			}
   1123 			length += int(fb & bitMask32[n])
   1124 			fb >>= n & regSizeMaskUint32
   1125 			fnb -= n
   1126 		default:
   1127 			if debugDecode {
   1128 				fmt.Println(v, ">= maxNumLit")
   1129 			}
   1130 			f.err = CorruptInputError(f.roffset)
   1131 			f.b, f.nb = fb, fnb
   1132 			return
   1133 		}
   1134 
   1135 		var dist uint32
   1136 		if f.hd == nil {
   1137 			for fnb < 5 {
   1138 				c, err := fr.ReadByte()
   1139 				if err != nil {
   1140 					f.b, f.nb = fb, fnb
   1141 					if debugDecode {
   1142 						fmt.Println("morebits f.nb<5:", err)
   1143 					}
   1144 					f.err = err
   1145 					return
   1146 				}
   1147 				f.roffset++
   1148 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
   1149 				fnb += 8
   1150 			}
   1151 			dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))
   1152 			fb >>= 5
   1153 			fnb -= 5
   1154 		} else {
   1155 			// Since a huffmanDecoder can be empty or be composed of a degenerate tree
   1156 			// with single element, huffSym must error on these two edge cases. In both
   1157 			// cases, the chunks slice will be 0 for the invalid sequence, leading it
   1158 			// satisfy the n == 0 check below.
   1159 			n := uint(f.hd.maxRead)
   1160 			// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
   1161 			// but is smart enough to keep local variables in registers, so use nb and b,
   1162 			// inline call to moreBits and reassign b,nb back to f on return.
   1163 			for {
   1164 				for fnb < n {
   1165 					c, err := fr.ReadByte()
   1166 					if err != nil {
   1167 						f.b, f.nb = fb, fnb
   1168 						f.err = noEOF(err)
   1169 						return
   1170 					}
   1171 					f.roffset++
   1172 					fb |= uint32(c) << (fnb & regSizeMaskUint32)
   1173 					fnb += 8
   1174 				}
   1175 				chunk := f.hd.chunks[fb&(huffmanNumChunks-1)]
   1176 				n = uint(chunk & huffmanCountMask)
   1177 				if n > huffmanChunkBits {
   1178 					chunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]
   1179 					n = uint(chunk & huffmanCountMask)
   1180 				}
   1181 				if n <= fnb {
   1182 					if n == 0 {
   1183 						f.b, f.nb = fb, fnb
   1184 						if debugDecode {
   1185 							fmt.Println("huffsym: n==0")
   1186 						}
   1187 						f.err = CorruptInputError(f.roffset)
   1188 						return
   1189 					}
   1190 					fb = fb >> (n & regSizeMaskUint32)
   1191 					fnb = fnb - n
   1192 					dist = uint32(chunk >> huffmanValueShift)
   1193 					break
   1194 				}
   1195 			}
   1196 		}
   1197 
   1198 		switch {
   1199 		case dist < 4:
   1200 			dist++
   1201 		case dist < maxNumDist:
   1202 			nb := uint(dist-2) >> 1
   1203 			// have 1 bit in bottom of dist, need nb more.
   1204 			extra := (dist & 1) << (nb & regSizeMaskUint32)
   1205 			for fnb < nb {
   1206 				c, err := fr.ReadByte()
   1207 				if err != nil {
   1208 					f.b, f.nb = fb, fnb
   1209 					if debugDecode {
   1210 						fmt.Println("morebits f.nb<nb:", err)
   1211 					}
   1212 					f.err = err
   1213 					return
   1214 				}
   1215 				f.roffset++
   1216 				fb |= uint32(c) << (fnb & regSizeMaskUint32)
   1217 				fnb += 8
   1218 			}
   1219 			extra |= fb & bitMask32[nb]
   1220 			fb >>= nb & regSizeMaskUint32
   1221 			fnb -= nb
   1222 			dist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra
   1223 			// slower: dist = bitMask32[nb+1] + 2 + extra
   1224 		default:
   1225 			f.b, f.nb = fb, fnb
   1226 			if debugDecode {
   1227 				fmt.Println("dist too big:", dist, maxNumDist)
   1228 			}
   1229 			f.err = CorruptInputError(f.roffset)
   1230 			return
   1231 		}
   1232 
   1233 		// No check on length; encoding can be prescient.
   1234 		if dist > uint32(dict.histSize()) {
   1235 			f.b, f.nb = fb, fnb
   1236 			if debugDecode {
   1237 				fmt.Println("dist > dict.histSize():", dist, dict.histSize())
   1238 			}
   1239 			f.err = CorruptInputError(f.roffset)
   1240 			return
   1241 		}
   1242 
   1243 		f.copyLen, f.copyDist = length, int(dist)
   1244 		goto copyHistory
   1245 	}
   1246 
   1247 copyHistory:
   1248 	// Perform a backwards copy according to RFC section 3.2.3.
   1249 	{
   1250 		cnt := dict.tryWriteCopy(f.copyDist, f.copyLen)
   1251 		if cnt == 0 {
   1252 			cnt = dict.writeCopy(f.copyDist, f.copyLen)
   1253 		}
   1254 		f.copyLen -= cnt
   1255 
   1256 		if dict.availWrite() == 0 || f.copyLen > 0 {
   1257 			f.toRead = dict.readFlush()
   1258 			f.step = (*decompressor).huffmanGenericReader // We need to continue this work
   1259 			f.stepState = stateDict
   1260 			f.b, f.nb = fb, fnb
   1261 			return
   1262 		}
   1263 		goto readLiteral
   1264 	}
   1265 	// Not reached
   1266 }
   1267 
   1268 func (f *decompressor) huffmanBlockDecoder() func() {
   1269 	switch f.r.(type) {
   1270 	case *bytes.Buffer:
   1271 		return f.huffmanBytesBuffer
   1272 	case *bytes.Reader:
   1273 		return f.huffmanBytesReader
   1274 	case *bufio.Reader:
   1275 		return f.huffmanBufioReader
   1276 	case *strings.Reader:
   1277 		return f.huffmanStringsReader
   1278 	case Reader:
   1279 		return f.huffmanGenericReader
   1280 	default:
   1281 		return f.huffmanGenericReader
   1282 	}
   1283 }