package flate
import (
"encoding/binary"
"fmt"
)
type fastEnc interface {
Encode (dst *tokens , src []byte )
Reset ()
}
func newFastEnc (level int ) fastEnc {
switch level {
case 1 :
return &fastEncL1 {fastGen : fastGen {cur : maxStoreBlockSize }}
case 2 :
return &fastEncL2 {fastGen : fastGen {cur : maxStoreBlockSize }}
case 3 :
return &fastEncL3 {fastGen : fastGen {cur : maxStoreBlockSize }}
case 4 :
return &fastEncL4 {fastGen : fastGen {cur : maxStoreBlockSize }}
case 5 :
return &fastEncL5 {fastGen : fastGen {cur : maxStoreBlockSize }}
case 6 :
return &fastEncL6 {fastGen : fastGen {cur : maxStoreBlockSize }}
default :
panic ("invalid level specified" )
}
}
const (
tableBits = 15
tableSize = 1 << tableBits
tableShift = 32 - tableBits
baseMatchOffset = 1
baseMatchLength = 3
maxMatchOffset = 1 << 15
bTableBits = 17
bTableSize = 1 << bTableBits
allocHistory = maxStoreBlockSize * 5
bufferReset = (1 << 31 ) - allocHistory - maxStoreBlockSize - 1
)
const (
prime3bytes = 506832829
prime4bytes = 2654435761
prime5bytes = 889523592379
prime6bytes = 227718039650203
prime7bytes = 58295818150454627
prime8bytes = 0xcf1bbcdcb7a56463
)
func load3232 (b []byte , i int32 ) uint32 {
return binary .LittleEndian .Uint32 (b [i :])
}
func load6432 (b []byte , i int32 ) uint64 {
return binary .LittleEndian .Uint64 (b [i :])
}
type tableEntry struct {
offset int32
}
type fastGen struct {
hist []byte
cur int32
}
func (e *fastGen ) addBlock (src []byte ) int32 {
if len (e .hist )+len (src ) > cap (e .hist ) {
if cap (e .hist ) == 0 {
e .hist = make ([]byte , 0 , allocHistory )
} else {
if cap (e .hist ) < maxMatchOffset *2 {
panic ("unexpected buffer size" )
}
offset := int32 (len (e .hist )) - maxMatchOffset
*(*[maxMatchOffset ]byte )(e .hist ) = *(*[maxMatchOffset ]byte )(e .hist [offset :])
e .cur += offset
e .hist = e .hist [:maxMatchOffset ]
}
}
s := int32 (len (e .hist ))
e .hist = append (e .hist , src ...)
return s
}
type tableEntryPrev struct {
Cur tableEntry
Prev tableEntry
}
func hash7 (u uint64 , h uint8 ) uint32 {
return uint32 (((u << (64 - 56 )) * prime7bytes ) >> ((64 - h ) & reg8SizeMask64 ))
}
func hashLen (u uint64 , length , mls uint8 ) uint32 {
switch mls {
case 3 :
return (uint32 (u <<8 ) * prime3bytes ) >> (32 - length )
case 5 :
return uint32 (((u << (64 - 40 )) * prime5bytes ) >> (64 - length ))
case 6 :
return uint32 (((u << (64 - 48 )) * prime6bytes ) >> (64 - length ))
case 7 :
return uint32 (((u << (64 - 56 )) * prime7bytes ) >> (64 - length ))
case 8 :
return uint32 ((u * prime8bytes ) >> (64 - length ))
default :
return (uint32 (u ) * prime4bytes ) >> (32 - length )
}
}
func (e *fastGen ) matchlen (s , t int32 , src []byte ) int32 {
if debugDecode {
if t >= s {
panic (fmt .Sprint ("t >=s:" , t , s ))
}
if int (s ) >= len (src ) {
panic (fmt .Sprint ("s >= len(src):" , s , len (src )))
}
if t < 0 {
panic (fmt .Sprint ("t < 0:" , t ))
}
if s -t > maxMatchOffset {
panic (fmt .Sprint (s , "-" , t , "(" , s -t , ") > maxMatchLength (" , maxMatchOffset , ")" ))
}
}
s1 := int (s ) + maxMatchLength - 4
if s1 > len (src ) {
s1 = len (src )
}
return int32 (matchLen (src [s :s1 ], src [t :]))
}
func (e *fastGen ) matchlenLong (s , t int32 , src []byte ) int32 {
if debugDeflate {
if t >= s {
panic (fmt .Sprint ("t >=s:" , t , s ))
}
if int (s ) >= len (src ) {
panic (fmt .Sprint ("s >= len(src):" , s , len (src )))
}
if t < 0 {
panic (fmt .Sprint ("t < 0:" , t ))
}
if s -t > maxMatchOffset {
panic (fmt .Sprint (s , "-" , t , "(" , s -t , ") > maxMatchLength (" , maxMatchOffset , ")" ))
}
}
return int32 (matchLen (src [s :], src [t :]))
}
func (e *fastGen ) Reset () {
if cap (e .hist ) < allocHistory {
e .hist = make ([]byte , 0 , allocHistory )
}
if e .cur <= bufferReset {
e .cur += maxMatchOffset + int32 (len (e .hist ))
}
e .hist = e .hist [:0 ]
}
The pages are generated with Golds v0.6.7 . (GOOS=linux 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 .