// Copyright 2023 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package zstdimport ()// maxHuffmanBits is the largest possible Huffman table bits.const maxHuffmanBits = 11// readHuff reads Huffman table from data starting at off into table.// Each entry in a Huffman table is a pair of bytes.// The high byte is the encoded value. The low byte is the number// of bits used to encode that value. We index into the table// with a value of size tableBits. A value that requires fewer bits// appear in the table multiple times.// This returns the number of bits in the Huffman table and the new offset.// RFC 4.2.1.func ( *Reader) ( block, int, []uint16) (, int, error) {if >= len() {return0, 0, .makeEOFError() } := [] ++var [256]uint8varintif < 128 {// The table is compressed using an FSE. RFC 4.2.1.2.iflen(.fseScratch) < 1<<6 { .fseScratch = make([]fseEntry, 1<<6) } , , := .readFSE(, , 255, 6, .fseScratch)if != nil {return0, 0, } := .fseScratchif +int() > len() {return0, 0, .makeEOFError() } , := .makeReverseBitReader(, +int()-1, )if != nil {return0, 0, } , := .val(uint8())if != nil {return0, 0, } , := .val(uint8())if != nil {return0, 0, }// There are two independent FSE streams, tracked by // state1 and state2. We decode them alternately.for { := &[]if !.fetch(.bits) {if >= 254 {return0, 0, .makeError("Huffman count overflow") } [] = .sym [+1] = [].sym += 2break } , := .val(.bits)if != nil {return0, 0, } = uint32(.base) + if >= 255 {return0, 0, .makeError("Huffman count overflow") } [] = .sym ++ = &[]if !.fetch(.bits) {if >= 254 {return0, 0, .makeError("Huffman count overflow") } [] = .sym [+1] = [].sym += 2break } , = .val(.bits)if != nil {return0, 0, } = uint32(.base) + if >= 255 {return0, 0, .makeError("Huffman count overflow") } [] = .sym ++ } += int() } else {// The table is not compressed. Each weight is 4 bits. = int() - 127if +((+1)/2) >= len() {return0, 0, io.ErrUnexpectedEOF }for := 0; < ; += 2 { := [] ++ [] = >> 4 [+1] = & 0xf } }// RFC 4.2.1.3.var [13]uint32 := uint32(0)for , := range [:] {if > 12 {return0, 0, .makeError(, "Huffman weight overflow") } []++if > 0 { += 1 << ( - 1) } }if == 0 {return0, 0, .makeError(, "bad Huffman weights") } = 32 - bits.LeadingZeros32()if > maxHuffmanBits {return0, 0, .makeError(, "bad Huffman weights") }iflen() < 1<< {return0, 0, .makeError(, "Huffman table too small") }// Work out the last weight value, which is omitted because // the weights must sum to a power of two. := (uint32(1) << ) - if == 0 {return0, 0, .makeError(, "bad Huffman weights") } := 31 - bits.LeadingZeros32()ifuint32(1)<< != {return0, 0, .makeError(, "bad Huffman weights") }if >= 256 {return0, 0, .makeError(, "Huffman weight overflow") } [] = uint8( + 1) ++ [+1]++if [1] < 2 || [1]&1 != 0 {return0, 0, .makeError(, "bad Huffman weights") }// Change weightMark from a count of weights to the index of // the first symbol for that weight. We shift the indexes to // also store how many we have seen so far, := uint32(0)for := 0; < ; ++ { := += [+1] << [+1] = }for , := range [:] {if == 0 {continue } := uint32(1) << ( - 1) := uint16()<<8 | (uint16() + 1 - uint16()) := []for := uint32(0); < ; ++ { [+] = } [] += }return , , nil}
The pages are generated with Goldsv0.7.0-preview. (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 @zigo_101 (reachable from the left QR code) to get the latest news of Golds.