Source File
inflate.go
Belonging Package
compress/flate
package flate
import (
)
const (
maxNumLit = 286
maxNumDist = 30
numCodes = 19 // number of codes in Huffman meta-code
)
type CorruptInputError int64
func ( CorruptInputError) () string {
return "flate: corrupt input before offset " + strconv.FormatInt(int64(), 10)
}
type InternalError string
func ( InternalError) () string { return "flate: internal error: " + string() }
const (
huffmanChunkBits = 9
huffmanNumChunks = 1 << huffmanChunkBits
huffmanCountMask = 15
huffmanValueShift = 4
)
type huffmanDecoder struct {
min int // the minimum code length
chunks [huffmanNumChunks]uint32 // chunks as described above
links [][]uint32 // overflow links
linkMask uint32 // mask the width of the link table
}
const = false
if .min != 0 {
* = huffmanDecoder{}
}
var [maxCodeLen]int
var , int
for , := range {
if == 0 {
continue
}
if == 0 || < {
=
}
if > {
=
}
[]++
}
if == 0 {
return true
}
:= 0
var [maxCodeLen]int
for := ; <= ; ++ {
<<= 1
[] =
+= []
}
if != 1<<uint() && !( == 1 && == 1) {
return false
}
.min =
if > huffmanChunkBits {
:= 1 << (uint() - huffmanChunkBits)
.linkMask = uint32( - 1)
:= [huffmanChunkBits+1] >> 1
.links = make([][]uint32, huffmanNumChunks-)
for := uint(); < huffmanNumChunks; ++ {
:= int(bits.Reverse16(uint16()))
>>= uint(16 - huffmanChunkBits)
:= - uint()
if && .chunks[] != 0 {
panic("impossible: overwriting existing chunk")
}
.chunks[] = uint32(<<huffmanValueShift | (huffmanChunkBits + 1))
.links[] = make([]uint32, )
}
}
for , := range {
if == 0 {
continue
}
:= []
[]++
:= uint32(<<huffmanValueShift | )
:= int(bits.Reverse16(uint16()))
>>= uint(16 - )
if <= huffmanChunkBits {
if && .chunks[] != 0 {
panic("impossible: overwriting existing chunk")
}
.chunks[] =
}
} else {
:= & (huffmanNumChunks - 1)
panic("impossible: not an indirect chunk")
}
:= .chunks[] >> huffmanValueShift
:= .links[]
>>= huffmanChunkBits
for := ; < len(); += 1 << uint(-huffmanChunkBits) {
if && [] != 0 {
panic("impossible: overwriting existing chunk")
}
[] =
}
}
}
for , := range .chunks {
type Reader interface {
io.Reader
io.ByteReader
}
step func(*decompressor)
stepState int
final bool
err error
toRead []byte
hl, hd *huffmanDecoder
copyLen int
copyDist int
}
func ( *decompressor) () {
for .nb < 1+2 {
if .err = .moreBits(); .err != nil {
return
}
}
.final = .b&1 == 1
.b >>= 1
:= .b & 3
.b >>= 2
.nb -= 1 + 2
switch {
case 0:
.dataBlock()
.hl = &fixedHuffmanDecoder
.hd = nil
.huffmanBlock()
if .err = .readHuffman(); .err != nil {
break
}
.hl = &.h1
.hd = &.h2
.huffmanBlock()
.err = CorruptInputError(.roffset)
}
}
func ( *decompressor) ( []byte) (int, error) {
for {
if len(.toRead) > 0 {
:= copy(, .toRead)
.toRead = .toRead[:]
if len(.toRead) == 0 {
return , .err
}
return , nil
}
if .err != nil {
return 0, .err
}
.step()
if .err != nil && len(.toRead) == 0 {
.toRead = .dict.readFlush() // Flush what's left in case of error
}
}
}
func ( *decompressor) () error {
if .err == io.EOF {
return nil
}
return .err
}
for .nb < 5+5+4 {
if := .moreBits(); != nil {
return
}
}
:= int(.b&0x1F) + 257
if > maxNumLit {
return CorruptInputError(.roffset)
}
.b >>= 5
:= int(.b&0x1F) + 1
if > maxNumDist {
return CorruptInputError(.roffset)
}
.b >>= 5
.bits[] =
++
continue
var int
var uint
var int
switch {
default:
return InternalError("unexpected length code")
case 16:
= 3
= 2
if == 0 {
return CorruptInputError(.roffset)
}
= .bits[-1]
case 17:
= 3
= 3
= 0
case 18:
= 11
= 7
= 0
}
for .nb < {
if := .moreBits(); != nil {
return
}
}
+= int(.b & uint32(1<<-1))
.b >>=
.nb -=
if + > {
return CorruptInputError(.roffset)
}
for := 0; < ; ++ {
.bits[] =
++
}
}
if !.h1.init(.bits[0:]) || !.h2.init(.bits[:+]) {
return CorruptInputError(.roffset)
}
if .h1.min < .bits[endBlockMarker] {
.h1.min = .bits[endBlockMarker]
}
return nil
}
func ( *decompressor) () {
const (
= iota // Zero value must be stateInit
)
switch .stepState {
case :
goto
case :
goto
}
case < 265:
= - (257 - 3)
= 0
case < 269:
= *2 - (265*2 - 11)
= 1
case < 273:
= *4 - (269*4 - 19)
= 2
case < 277:
= *8 - (273*8 - 35)
= 3
case < 281:
= *16 - (277*16 - 67)
= 4
case < 285:
= *32 - (281*32 - 131)
= 5
case < maxNumLit:
= 258
= 0
default:
.err = CorruptInputError(.roffset)
return
}
if > 0 {
for .nb < {
if = .moreBits(); != nil {
.err =
return
}
}
+= int(.b & uint32(1<<-1))
.b >>=
.nb -=
}
var int
if .hd == nil {
for .nb < 5 {
if = .moreBits(); != nil {
.err =
return
}
}
= int(bits.Reverse8(uint8(.b & 0x1F << 3)))
.b >>= 5
.nb -= 5
} else {
if , = .huffSym(.hd); != nil {
.err =
return
}
}
switch {
case < 4:
++
case < maxNumDist:
, := io.ReadFull(.r, .buf[0:4])
.roffset += int64()
if != nil {
.err = noEOF()
return
}
:= int(.buf[0]) | int(.buf[1])<<8
:= int(.buf[2]) | int(.buf[3])<<8
if uint16() != uint16(^) {
.err = CorruptInputError(.roffset)
return
}
if == 0 {
.toRead = .dict.readFlush()
.finishBlock()
return
}
.copyLen =
.copyData()
}
func ( *decompressor) () {
:= .dict.writeSlice()
if len() > .copyLen {
= [:.copyLen]
}
, := io.ReadFull(.r, )
.roffset += int64()
.copyLen -=
.dict.writeMark()
if != nil {
.err = noEOF()
return
}
if .dict.availWrite() == 0 || .copyLen > 0 {
.toRead = .dict.readFlush()
.step = (*decompressor).
return
}
.finishBlock()
}
func ( *decompressor) () {
if .final {
if .dict.availRead() > 0 {
.toRead = .dict.readFlush()
}
.err = io.EOF
}
.step = (*decompressor).nextBlock
}
, := .nb, .b
for {
for < {
, := .r.ReadByte()
if != nil {
.b =
.nb =
return 0, noEOF()
}
.roffset++
|= uint32() << ( & 31)
+= 8
}
:= .chunks[&(huffmanNumChunks-1)]
= uint( & huffmanCountMask)
if > huffmanChunkBits {
= .links[>>huffmanValueShift][(>>huffmanChunkBits)&.linkMask]
= uint( & huffmanCountMask)
}
if <= {
if == 0 {
.b =
.nb =
.err = CorruptInputError(.roffset)
return 0, .err
}
.b = >> ( & 31)
.nb = -
return int( >> huffmanValueShift), nil
}
}
}
func ( io.Reader) Reader {
if , := .(Reader); {
return
}
return bufio.NewReader()
}
func () {
var [288]int
for := 0; < 144; ++ {
[] = 8
}
for := 144; < 256; ++ {
[] = 9
}
for := 256; < 280; ++ {
[] = 7
}
for := 280; < 288; ++ {
[] = 8
}
fixedHuffmanDecoder.init([:])
})
}
func ( *decompressor) ( io.Reader, []byte) error {
* = decompressor{
r: makeReader(),
bits: .bits,
codebits: .codebits,
dict: .dict,
step: (*decompressor).nextBlock,
}
.dict.init(maxMatchOffset, )
return nil
}
func ( io.Reader) io.ReadCloser {
fixedHuffmanDecoderInit()
var decompressor
.r = makeReader()
.bits = new([maxNumLit + maxNumDist]int)
.codebits = new([numCodes]int)
.step = (*decompressor).nextBlock
.dict.init(maxMatchOffset, nil)
return &
}
func ( io.Reader, []byte) io.ReadCloser {
fixedHuffmanDecoderInit()
var decompressor
.r = makeReader()
.bits = new([maxNumLit + maxNumDist]int)
.codebits = new([numCodes]int)
.step = (*decompressor).nextBlock
.dict.init(maxMatchOffset, )
return &
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin 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 @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |