package  flate 
 
import  ( 
	"bytes"  
	"encoding/binary"  
	"fmt"  
	"io"  
	"math"  
) 
 
const  ( 
	 
 
 
 
	lengthShift         = 22  
	offsetMask          = 1 <<lengthShift  - 1  
	typeMask            = 3  << 30  
	literalType         = 0  << 30  
	matchType           = 1  << 30  
	matchOffsetOnlyMask = 0xffff  
) 
 
 
 
var  lengthCodes = [256 ]uint8 { 
	0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 8 , 
	9 , 9 , 10 , 10 , 11 , 11 , 12 , 12 , 12 , 12 , 
	13 , 13 , 13 , 13 , 14 , 14 , 14 , 14 , 15 , 15 , 
	15 , 15 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 
	17 , 17 , 17 , 17 , 17 , 17 , 17 , 17 , 18 , 18 , 
	18 , 18 , 18 , 18 , 18 , 18 , 19 , 19 , 19 , 19 , 
	19 , 19 , 19 , 19 , 20 , 20 , 20 , 20 , 20 , 20 , 
	20 , 20 , 20 , 20 , 20 , 20 , 20 , 20 , 20 , 20 , 
	21 , 21 , 21 , 21 , 21 , 21 , 21 , 21 , 21 , 21 , 
	21 , 21 , 21 , 21 , 21 , 21 , 22 , 22 , 22 , 22 , 
	22 , 22 , 22 , 22 , 22 , 22 , 22 , 22 , 22 , 22 , 
	22 , 22 , 23 , 23 , 23 , 23 , 23 , 23 , 23 , 23 , 
	23 , 23 , 23 , 23 , 23 , 23 , 23 , 23 , 24 , 24 , 
	24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 
	24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 
	24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 
	25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 
	25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 
	25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 
	25 , 25 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 
	26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 
	26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 
	26 , 26 , 26 , 26 , 27 , 27 , 27 , 27 , 27 , 27 , 
	27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 
	27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 
	27 , 27 , 27 , 27 , 27 , 28 , 
} 
 
 
var  lengthCodes1 = [256 ]uint8 { 
	1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 9 , 
	10 , 10 , 11 , 11 , 12 , 12 , 13 , 13 , 13 , 13 , 
	14 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 16 , 16 , 
	16 , 16 , 17 , 17 , 17 , 17 , 17 , 17 , 17 , 17 , 
	18 , 18 , 18 , 18 , 18 , 18 , 18 , 18 , 19 , 19 , 
	19 , 19 , 19 , 19 , 19 , 19 , 20 , 20 , 20 , 20 , 
	20 , 20 , 20 , 20 , 21 , 21 , 21 , 21 , 21 , 21 , 
	21 , 21 , 21 , 21 , 21 , 21 , 21 , 21 , 21 , 21 , 
	22 , 22 , 22 , 22 , 22 , 22 , 22 , 22 , 22 , 22 , 
	22 , 22 , 22 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 
	23 , 23 , 23 , 23 , 23 , 23 , 23 , 23 , 23 , 23 , 
	23 , 23 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 
	24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 25 , 25 , 
	25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 
	25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 
	25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 
	26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 
	26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 
	26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 
	26 , 26 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 
	27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 
	27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 
	27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 28 , 28 , 
	28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 
	28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 
	28 , 28 , 28 , 28 , 28 , 29 , 
} 
 
var  offsetCodes = [256 ]uint32 { 
	0 , 1 , 2 , 3 , 4 , 4 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 
	8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 
	10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 
	11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 11 , 
	12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 
	12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 
	13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 
	13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 13 , 
	14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 
	14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 
	14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 
	14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 
	15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 
	15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 
	15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 
	15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 
} 
 
 
var  offsetCodes14 = [256 ]uint32 { 
	14 , 15 , 16 , 17 , 18 , 18 , 19 , 19 , 20 , 20 , 20 , 20 , 21 , 21 , 21 , 21 , 
	22 , 22 , 22 , 22 , 22 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 23 , 23 , 23 , 23 , 
	24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 
	25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 25 , 
	26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 
	26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 26 , 
	27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 
	27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 
	28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 
	28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 
	28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 
	28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 
	29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 
	29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 
	29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 
	29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 29 , 
} 
 
type  token uint32  
 
type  tokens struct  { 
	extraHist [32 ]uint16    
	offHist   [32 ]uint16    
	litHist   [256 ]uint16   
	nFilled   int  
	n         uint16   
	tokens    [maxStoreBlockSize  + 1 ]token  
} 
 
func  (t  *tokens ) Reset () { 
	if  t .n  == 0  { 
		return  
	} 
	t .n  = 0  
	t .nFilled  = 0  
	for  i  := range  t .litHist [:] { 
		t .litHist [i ] = 0  
	} 
	for  i  := range  t .extraHist [:] { 
		t .extraHist [i ] = 0  
	} 
	for  i  := range  t .offHist [:] { 
		t .offHist [i ] = 0  
	} 
} 
 
func  (t  *tokens ) Fill () { 
	if  t .n  == 0  { 
		return  
	} 
	for  i , v  := range  t .litHist [:] { 
		if  v  == 0  { 
			t .litHist [i ] = 1  
			t .nFilled ++ 
		} 
	} 
	for  i , v  := range  t .extraHist [:literalCount -256 ] { 
		if  v  == 0  { 
			t .nFilled ++ 
			t .extraHist [i ] = 1  
		} 
	} 
	for  i , v  := range  t .offHist [:offsetCodeCount ] { 
		if  v  == 0  { 
			t .offHist [i ] = 1  
		} 
	} 
} 
 
func  indexTokens(in  []token ) tokens  { 
	var  t  tokens  
	t .indexTokens (in ) 
	return  t  
} 
 
func  (t  *tokens ) indexTokens (in  []token ) { 
	t .Reset () 
	for  _ , tok  := range  in  { 
		if  tok  < matchType  { 
			t .AddLiteral (tok .literal ()) 
			continue  
		} 
		t .AddMatch (uint32 (tok .length ()), tok .offset ()&matchOffsetOnlyMask ) 
	} 
} 
 
 
func  emitLiteral(dst  *tokens , lit  []byte ) { 
	for  _ , v  := range  lit  { 
		dst .tokens [dst .n ] = token (v ) 
		dst .litHist [v ]++ 
		dst .n ++ 
	} 
} 
 
func  (t  *tokens ) AddLiteral (lit  byte ) { 
	t .tokens [t .n ] = token (lit ) 
	t .litHist [lit ]++ 
	t .n ++ 
} 
 
 
func  mFastLog2(val  float32 ) float32  { 
	ux  := int32 (math .Float32bits (val )) 
	log2  := (float32 )(((ux  >> 23 ) & 255 ) - 128 ) 
	ux  &= -0x7f800001  
	ux  += 127  << 23  
	uval  := math .Float32frombits (uint32 (ux )) 
	log2  += ((-0.34484843 )*uval +2.02466578 )*uval  - 0.67487759  
	return  log2  
} 
 
 
 
 
func  (t  *tokens ) EstimatedBits () int  { 
	shannon  := float32 (0 ) 
	bits  := int (0 ) 
	nMatches  := 0  
	total  := int (t .n ) + t .nFilled  
	if  total  > 0  { 
		invTotal  := 1.0  / float32 (total ) 
		for  _ , v  := range  t .litHist [:] { 
			if  v  > 0  { 
				n  := float32 (v ) 
				shannon  += atLeastOne (-mFastLog2 (n *invTotal )) * n  
			} 
		} 
		 
		shannon  += 15  
		for  i , v  := range  t .extraHist [1  : literalCount -256 ] { 
			if  v  > 0  { 
				n  := float32 (v ) 
				shannon  += atLeastOne (-mFastLog2 (n *invTotal )) * n  
				bits  += int (lengthExtraBits [i &31 ]) * int (v ) 
				nMatches  += int (v ) 
			} 
		} 
	} 
	if  nMatches  > 0  { 
		invTotal  := 1.0  / float32 (nMatches ) 
		for  i , v  := range  t .offHist [:offsetCodeCount ] { 
			if  v  > 0  { 
				n  := float32 (v ) 
				shannon  += atLeastOne (-mFastLog2 (n *invTotal )) * n  
				bits  += int (offsetExtraBits [i &31 ]) * int (v ) 
			} 
		} 
	} 
	return  int (shannon ) + bits  
} 
 
 
 
func  (t  *tokens ) AddMatch (xlength  uint32 , xoffset  uint32 ) { 
	if  debugDeflate  { 
		if  xlength  >= maxMatchLength +baseMatchLength  { 
			panic (fmt .Errorf ("invalid length: %v" , xlength )) 
		} 
		if  xoffset  >= maxMatchOffset +baseMatchOffset  { 
			panic (fmt .Errorf ("invalid offset: %v" , xoffset )) 
		} 
	} 
	oCode  := offsetCode (xoffset ) 
	xoffset  |= oCode  << 16  
 
	t .extraHist [lengthCodes1 [uint8 (xlength )]]++ 
	t .offHist [oCode &31 ]++ 
	t .tokens [t .n ] = token (matchType  | xlength <<lengthShift  | xoffset ) 
	t .n ++ 
} 
 
 
 
func  (t  *tokens ) AddMatchLong (xlength  int32 , xoffset  uint32 ) { 
	if  debugDeflate  { 
		if  xoffset  >= maxMatchOffset +baseMatchOffset  { 
			panic (fmt .Errorf ("invalid offset: %v" , xoffset )) 
		} 
	} 
	oc  := offsetCode (xoffset ) 
	xoffset  |= oc  << 16  
	for  xlength  > 0  { 
		xl  := xlength  
		if  xl  > 258  { 
			 
			if  xl  > 258 +baseMatchLength  { 
				xl  = 258  
			} else  { 
				xl  = 258  - baseMatchLength  
			} 
		} 
		xlength  -= xl  
		xl  -= baseMatchLength  
		t .extraHist [lengthCodes1 [uint8 (xl )]]++ 
		t .offHist [oc &31 ]++ 
		t .tokens [t .n ] = token (matchType  | uint32 (xl )<<lengthShift  | xoffset ) 
		t .n ++ 
	} 
} 
 
func  (t  *tokens ) AddEOB () { 
	t .tokens [t .n ] = token (endBlockMarker ) 
	t .extraHist [0 ]++ 
	t .n ++ 
} 
 
func  (t  *tokens ) Slice () []token  { 
	return  t .tokens [:t .n ] 
} 
 
 
func  (t  *tokens ) VarInt () []byte  { 
	var  b  = make ([]byte , binary .MaxVarintLen32 *int (t .n )) 
	var  off  int  
	for  _ , v  := range  t .tokens [:t .n ] { 
		off  += binary .PutUvarint (b [off :], uint64 (v )) 
	} 
	return  b [:off ] 
} 
 
 
 
func  (t  *tokens ) FromVarInt (b  []byte ) error  { 
	var  buf  = bytes .NewReader (b ) 
	var  toks  []token  
	for  { 
		r , err  := binary .ReadUvarint (buf ) 
		if  err  == io .EOF  { 
			break  
		} 
		if  err  != nil  { 
			return  err  
		} 
		toks  = append (toks , token (r )) 
	} 
	t .indexTokens (toks ) 
	return  nil  
} 
 
 
func  (t  token ) typ () uint32  { return  uint32 (t ) & typeMask  } 
 
 
func  (t  token ) literal () uint8  { return  uint8 (t ) } 
 
 
func  (t  token ) offset () uint32  { return  uint32 (t ) & offsetMask  } 
 
func  (t  token ) length () uint8  { return  uint8 (t  >> lengthShift ) } 
 
 
func  lengthCode(len  uint8 ) uint8  { return  lengthCodes [len ] } 
 
 
func  offsetCode(off  uint32 ) uint32  { 
	if  false  { 
		if  off  < uint32 (len (offsetCodes )) { 
			return  offsetCodes [off &255 ] 
		} else  if  off >>7  < uint32 (len (offsetCodes )) { 
			return  offsetCodes [(off >>7 )&255 ] + 14  
		} else  { 
			return  offsetCodes [(off >>14 )&255 ] + 28  
		} 
	} 
	if  off  < uint32 (len (offsetCodes )) { 
		return  offsetCodes [uint8 (off )] 
	} 
	return  offsetCodes14 [uint8 (off >>7 )] 
} 
  
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 .