Update dependencies (#5518)
This commit is contained in:
192
vendor/github.com/klauspost/compress/zstd/framedec.go
generated
vendored
192
vendor/github.com/klauspost/compress/zstd/framedec.go
generated
vendored
@@ -16,20 +16,11 @@ import (
|
||||
)
|
||||
|
||||
type frameDec struct {
|
||||
o decoderOptions
|
||||
crc hash.Hash64
|
||||
frameDone sync.WaitGroup
|
||||
offset int64
|
||||
o decoderOptions
|
||||
crc hash.Hash64
|
||||
offset int64
|
||||
|
||||
WindowSize uint64
|
||||
DictionaryID uint32
|
||||
FrameContentSize uint64
|
||||
HasCheckSum bool
|
||||
SingleSegment bool
|
||||
|
||||
// maxWindowSize is the maximum windows size to support.
|
||||
// should never be bigger than max-int.
|
||||
maxWindowSize uint64
|
||||
WindowSize uint64
|
||||
|
||||
// In order queue of blocks being decoded.
|
||||
decoding chan *blockDec
|
||||
@@ -42,15 +33,25 @@ type frameDec struct {
|
||||
// Byte buffer that can be reused for small input blocks.
|
||||
bBuf byteBuf
|
||||
|
||||
FrameContentSize uint64
|
||||
frameDone sync.WaitGroup
|
||||
|
||||
DictionaryID *uint32
|
||||
HasCheckSum bool
|
||||
SingleSegment bool
|
||||
|
||||
// asyncRunning indicates whether the async routine processes input on 'decoding'.
|
||||
asyncRunning bool
|
||||
asyncRunningMu sync.Mutex
|
||||
asyncRunning bool
|
||||
}
|
||||
|
||||
const (
|
||||
// The minimum Window_Size is 1 KB.
|
||||
// MinWindowSize is the minimum Window Size, which is 1 KB.
|
||||
MinWindowSize = 1 << 10
|
||||
MaxWindowSize = 1 << 30
|
||||
|
||||
// MaxWindowSize is the maximum encoder window size
|
||||
// and the default decoder maximum window size.
|
||||
MaxWindowSize = 1 << 29
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -59,12 +60,11 @@ var (
|
||||
)
|
||||
|
||||
func newFrameDec(o decoderOptions) *frameDec {
|
||||
d := frameDec{
|
||||
o: o,
|
||||
maxWindowSize: MaxWindowSize,
|
||||
if o.maxWindowSize > o.maxDecodedSize {
|
||||
o.maxWindowSize = o.maxDecodedSize
|
||||
}
|
||||
if d.maxWindowSize > o.maxDecodedSize {
|
||||
d.maxWindowSize = o.maxDecodedSize
|
||||
d := frameDec{
|
||||
o: o,
|
||||
}
|
||||
return &d
|
||||
}
|
||||
@@ -76,50 +76,74 @@ func newFrameDec(o decoderOptions) *frameDec {
|
||||
func (d *frameDec) reset(br byteBuffer) error {
|
||||
d.HasCheckSum = false
|
||||
d.WindowSize = 0
|
||||
var b []byte
|
||||
var signature [4]byte
|
||||
for {
|
||||
b = br.readSmall(4)
|
||||
if b == nil {
|
||||
var err error
|
||||
// Check if we can read more...
|
||||
b, err := br.readSmall(1)
|
||||
switch err {
|
||||
case io.EOF, io.ErrUnexpectedEOF:
|
||||
return io.EOF
|
||||
default:
|
||||
return err
|
||||
case nil:
|
||||
signature[0] = b[0]
|
||||
}
|
||||
if !bytes.Equal(b[1:4], skippableFrameMagic) || b[0]&0xf0 != 0x50 {
|
||||
if debug {
|
||||
println("Not skippable", hex.EncodeToString(b), hex.EncodeToString(skippableFrameMagic))
|
||||
// Read the rest, don't allow io.ErrUnexpectedEOF
|
||||
b, err = br.readSmall(3)
|
||||
switch err {
|
||||
case io.EOF:
|
||||
return io.EOF
|
||||
default:
|
||||
return err
|
||||
case nil:
|
||||
copy(signature[1:], b)
|
||||
}
|
||||
|
||||
if !bytes.Equal(signature[1:4], skippableFrameMagic) || signature[0]&0xf0 != 0x50 {
|
||||
if debugDecoder {
|
||||
println("Not skippable", hex.EncodeToString(signature[:]), hex.EncodeToString(skippableFrameMagic))
|
||||
}
|
||||
// Break if not skippable frame.
|
||||
break
|
||||
}
|
||||
// Read size to skip
|
||||
b = br.readSmall(4)
|
||||
if b == nil {
|
||||
println("Reading Frame Size EOF")
|
||||
return io.ErrUnexpectedEOF
|
||||
b, err = br.readSmall(4)
|
||||
if err != nil {
|
||||
if debugDecoder {
|
||||
println("Reading Frame Size", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
n := uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)
|
||||
println("Skipping frame with", n, "bytes.")
|
||||
err := br.skipN(int(n))
|
||||
err = br.skipN(int(n))
|
||||
if err != nil {
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("Reading discarded frame", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(b, frameMagic) {
|
||||
println("Got magic numbers: ", b, "want:", frameMagic)
|
||||
if !bytes.Equal(signature[:], frameMagic) {
|
||||
if debugDecoder {
|
||||
println("Got magic numbers: ", signature, "want:", frameMagic)
|
||||
}
|
||||
return ErrMagicMismatch
|
||||
}
|
||||
|
||||
// Read Frame_Header_Descriptor
|
||||
fhd, err := br.readByte()
|
||||
if err != nil {
|
||||
println("Reading Frame_Header_Descriptor", err)
|
||||
if debugDecoder {
|
||||
println("Reading Frame_Header_Descriptor", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
d.SingleSegment = fhd&(1<<5) != 0
|
||||
|
||||
if fhd&(1<<3) != 0 {
|
||||
return errors.New("Reserved bit set on frame header")
|
||||
return errors.New("reserved bit set on frame header")
|
||||
}
|
||||
|
||||
// Read Window_Descriptor
|
||||
@@ -128,7 +152,9 @@ func (d *frameDec) reset(br byteBuffer) error {
|
||||
if !d.SingleSegment {
|
||||
wd, err := br.readByte()
|
||||
if err != nil {
|
||||
println("Reading Window_Descriptor", err)
|
||||
if debugDecoder {
|
||||
println("Reading Window_Descriptor", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
printf("raw: %x, mantissa: %d, exponent: %d\n", wd, wd&7, wd>>3)
|
||||
@@ -140,31 +166,33 @@ func (d *frameDec) reset(br byteBuffer) error {
|
||||
|
||||
// Read Dictionary_ID
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary_id
|
||||
d.DictionaryID = 0
|
||||
d.DictionaryID = nil
|
||||
if size := fhd & 3; size != 0 {
|
||||
if size == 3 {
|
||||
size = 4
|
||||
}
|
||||
b = br.readSmall(int(size))
|
||||
if b == nil {
|
||||
if debug {
|
||||
println("Reading Dictionary_ID", io.ErrUnexpectedEOF)
|
||||
}
|
||||
return io.ErrUnexpectedEOF
|
||||
|
||||
b, err := br.readSmall(int(size))
|
||||
if err != nil {
|
||||
println("Reading Dictionary_ID", err)
|
||||
return err
|
||||
}
|
||||
var id uint32
|
||||
switch size {
|
||||
case 1:
|
||||
d.DictionaryID = uint32(b[0])
|
||||
id = uint32(b[0])
|
||||
case 2:
|
||||
d.DictionaryID = uint32(b[0]) | (uint32(b[1]) << 8)
|
||||
id = uint32(b[0]) | (uint32(b[1]) << 8)
|
||||
case 4:
|
||||
d.DictionaryID = uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)
|
||||
id = uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)
|
||||
}
|
||||
if debug {
|
||||
println("Dict size", size, "ID:", d.DictionaryID)
|
||||
if debugDecoder {
|
||||
println("Dict size", size, "ID:", id)
|
||||
}
|
||||
if d.DictionaryID != 0 {
|
||||
return ErrUnknownDictionary
|
||||
if id > 0 {
|
||||
// ID 0 means "sorry, no dictionary anyway".
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary-format
|
||||
d.DictionaryID = &id
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,10 +210,10 @@ func (d *frameDec) reset(br byteBuffer) error {
|
||||
}
|
||||
d.FrameContentSize = 0
|
||||
if fcsSize > 0 {
|
||||
b := br.readSmall(fcsSize)
|
||||
if b == nil {
|
||||
println("Reading Frame content", io.ErrUnexpectedEOF)
|
||||
return io.ErrUnexpectedEOF
|
||||
b, err := br.readSmall(fcsSize)
|
||||
if err != nil {
|
||||
println("Reading Frame content", err)
|
||||
return err
|
||||
}
|
||||
switch fcsSize {
|
||||
case 1:
|
||||
@@ -200,7 +228,7 @@ func (d *frameDec) reset(br byteBuffer) error {
|
||||
d2 := uint32(b[4]) | (uint32(b[5]) << 8) | (uint32(b[6]) << 16) | (uint32(b[7]) << 24)
|
||||
d.FrameContentSize = uint64(d1) | (uint64(d2) << 32)
|
||||
}
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("field size bits:", v, "fcsSize:", fcsSize, "FrameContentSize:", d.FrameContentSize, hex.EncodeToString(b[:fcsSize]), "singleseg:", d.SingleSegment, "window:", d.WindowSize)
|
||||
}
|
||||
}
|
||||
@@ -221,17 +249,25 @@ func (d *frameDec) reset(br byteBuffer) error {
|
||||
}
|
||||
}
|
||||
|
||||
if d.WindowSize > d.maxWindowSize {
|
||||
printf("window size %d > max %d\n", d.WindowSize, d.maxWindowSize)
|
||||
if d.WindowSize > uint64(d.o.maxWindowSize) {
|
||||
if debugDecoder {
|
||||
printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize)
|
||||
}
|
||||
return ErrWindowSizeExceeded
|
||||
}
|
||||
// The minimum Window_Size is 1 KB.
|
||||
if d.WindowSize < MinWindowSize {
|
||||
println("got window size: ", d.WindowSize)
|
||||
if debugDecoder {
|
||||
println("got window size: ", d.WindowSize)
|
||||
}
|
||||
return ErrWindowSizeTooSmall
|
||||
}
|
||||
d.history.windowSize = int(d.WindowSize)
|
||||
d.history.maxSize = d.history.windowSize + maxBlockSize
|
||||
if d.o.lowMem && d.history.windowSize < maxBlockSize {
|
||||
d.history.maxSize = d.history.windowSize * 2
|
||||
} else {
|
||||
d.history.maxSize = d.history.windowSize + maxBlockSize
|
||||
}
|
||||
// history contains input - maybe we do something
|
||||
d.rawInput = br
|
||||
return nil
|
||||
@@ -239,7 +275,7 @@ func (d *frameDec) reset(br byteBuffer) error {
|
||||
|
||||
// next will start decoding the next block from stream.
|
||||
func (d *frameDec) next(block *blockDec) error {
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
printf("decoding new block %p:%p", block, block.data)
|
||||
}
|
||||
err := block.reset(d.rawInput, d.WindowSize)
|
||||
@@ -250,7 +286,7 @@ func (d *frameDec) next(block *blockDec) error {
|
||||
return err
|
||||
}
|
||||
block.input <- struct{}{}
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("next block:", block)
|
||||
}
|
||||
d.asyncRunningMu.Lock()
|
||||
@@ -298,19 +334,19 @@ func (d *frameDec) checkCRC() error {
|
||||
tmp[3] = byte(got >> 24)
|
||||
|
||||
// We can overwrite upper tmp now
|
||||
want := d.rawInput.readSmall(4)
|
||||
if want == nil {
|
||||
println("CRC missing?")
|
||||
return io.ErrUnexpectedEOF
|
||||
want, err := d.rawInput.readSmall(4)
|
||||
if err != nil {
|
||||
println("CRC missing?", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !bytes.Equal(tmp[:], want) {
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("CRC Check Failed:", tmp[:], "!=", want)
|
||||
}
|
||||
return ErrCRCMismatch
|
||||
}
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("CRC ok", tmp[:])
|
||||
}
|
||||
return nil
|
||||
@@ -318,8 +354,8 @@ func (d *frameDec) checkCRC() error {
|
||||
|
||||
func (d *frameDec) initAsync() {
|
||||
if !d.o.lowMem && !d.SingleSegment {
|
||||
// set max extra size history to 20MB.
|
||||
d.history.maxSize = d.history.windowSize + maxBlockSize*10
|
||||
// set max extra size history to 2MB.
|
||||
d.history.maxSize = d.history.windowSize + maxBlockSize
|
||||
}
|
||||
// re-alloc if more than one extra block size.
|
||||
if d.o.lowMem && cap(d.history.b) > d.history.maxSize+maxBlockSize {
|
||||
@@ -331,7 +367,7 @@ func (d *frameDec) initAsync() {
|
||||
if cap(d.decoding) < d.o.concurrent {
|
||||
d.decoding = make(chan *blockDec, d.o.concurrent)
|
||||
}
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
h := d.history
|
||||
printf("history init. len: %d, cap: %d", len(h.b), cap(h.b))
|
||||
}
|
||||
@@ -345,8 +381,6 @@ func (d *frameDec) initAsync() {
|
||||
// When the frame has finished decoding the *bufio.Reader
|
||||
// containing the remaining input will be sent on frameDec.frameDone.
|
||||
func (d *frameDec) startDecoder(output chan decodeOutput) {
|
||||
// TODO: Init to dictionary
|
||||
d.history.reset()
|
||||
written := int64(0)
|
||||
|
||||
defer func() {
|
||||
@@ -381,7 +415,7 @@ func (d *frameDec) startDecoder(output chan decodeOutput) {
|
||||
output <- r
|
||||
return
|
||||
}
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("got result, from ", d.offset, "to", d.offset+int64(len(r.b)))
|
||||
d.offset += int64(len(r.b))
|
||||
}
|
||||
@@ -389,7 +423,7 @@ func (d *frameDec) startDecoder(output chan decodeOutput) {
|
||||
// Send history to next block
|
||||
select {
|
||||
case next = <-d.decoding:
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("Sending ", len(d.history.b), "bytes as history")
|
||||
}
|
||||
next.history <- &d.history
|
||||
@@ -427,7 +461,7 @@ func (d *frameDec) startDecoder(output chan decodeOutput) {
|
||||
output <- r
|
||||
if next == nil {
|
||||
// There was no decoder available, we wait for one now that we have sent to the writer.
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("Sending ", len(d.history.b), " bytes as history")
|
||||
}
|
||||
next = <-d.decoding
|
||||
@@ -439,8 +473,6 @@ func (d *frameDec) startDecoder(output chan decodeOutput) {
|
||||
|
||||
// runDecoder will create a sync decoder that will decode a block of data.
|
||||
func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) {
|
||||
// TODO: Init to dictionary
|
||||
d.history.reset()
|
||||
saved := d.history.b
|
||||
|
||||
// We use the history for output to avoid copying it.
|
||||
@@ -453,7 +485,7 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) {
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if debug {
|
||||
if debugDecoder {
|
||||
println("next block:", dec)
|
||||
}
|
||||
err = dec.decodeBuf(&d.history)
|
||||
|
||||
Reference in New Issue
Block a user