github.com/bir3/gocompiler@v0.9.2202/extra/compress/zstd/decoder.go (about) 1 // Copyright 2019+ Klaus Post. All rights reserved. 2 // License information can be found in the LICENSE file. 3 // Based on work by Yann Collet, released under BSD License. 4 5 package zstd 6 7 import ( 8 "context" 9 "encoding/binary" 10 "io" 11 "sync" 12 13 "github.com/bir3/gocompiler/extra/compress/zstd/internal/xxhash" 14 ) 15 16 // Decoder provides decoding of zstandard streams. 17 // The decoder has been designed to operate without allocations after a warmup. 18 // This means that you should store the decoder for best performance. 19 // To re-use a stream decoder, use the Reset(r io.Reader) error to switch to another stream. 20 // A decoder can safely be re-used even if the previous stream failed. 21 // To release the resources, you must call the Close() function on a decoder. 22 type Decoder struct { 23 o decoderOptions 24 25 // Unreferenced decoders, ready for use. 26 decoders chan *blockDec 27 28 // Current read position used for Reader functionality. 29 current decoderState 30 31 // sync stream decoding 32 syncStream struct { 33 decodedFrame uint64 34 br readerWrapper 35 enabled bool 36 inFrame bool 37 dstBuf []byte 38 } 39 40 frame *frameDec 41 42 // Custom dictionaries. 43 dicts map[uint32]*dict 44 45 // streamWg is the waitgroup for all streams 46 streamWg sync.WaitGroup 47 } 48 49 // decoderState is used for maintaining state when the decoder 50 // is used for streaming. 51 type decoderState struct { 52 // current block being written to stream. 53 decodeOutput 54 55 // output in order to be written to stream. 56 output chan decodeOutput 57 58 // cancel remaining output. 59 cancel context.CancelFunc 60 61 // crc of current frame 62 crc *xxhash.Digest 63 64 flushed bool 65 } 66 67 var ( 68 // Check the interfaces we want to support. 69 _ = io.WriterTo(&Decoder{}) 70 _ = io.Reader(&Decoder{}) 71 ) 72 73 // NewReader creates a new decoder. 74 // A nil Reader can be provided in which case Reset can be used to start a decode. 75 // 76 // A Decoder can be used in two modes: 77 // 78 // 1) As a stream, or 79 // 2) For stateless decoding using DecodeAll. 80 // 81 // Only a single stream can be decoded concurrently, but the same decoder 82 // can run multiple concurrent stateless decodes. It is even possible to 83 // use stateless decodes while a stream is being decoded. 84 // 85 // The Reset function can be used to initiate a new stream, which is will considerably 86 // reduce the allocations normally caused by NewReader. 87 func NewReader(r io.Reader, opts ...DOption) (*Decoder, error) { 88 initPredefined() 89 var d Decoder 90 d.o.setDefault() 91 for _, o := range opts { 92 err := o(&d.o) 93 if err != nil { 94 return nil, err 95 } 96 } 97 d.current.crc = xxhash.New() 98 d.current.flushed = true 99 100 if r == nil { 101 d.current.err = ErrDecoderNilInput 102 } 103 104 // Transfer option dicts. 105 d.dicts = make(map[uint32]*dict, len(d.o.dicts)) 106 for _, dc := range d.o.dicts { 107 d.dicts[dc.id] = dc 108 } 109 d.o.dicts = nil 110 111 // Create decoders 112 d.decoders = make(chan *blockDec, d.o.concurrent) 113 for i := 0; i < d.o.concurrent; i++ { 114 dec := newBlockDec(d.o.lowMem) 115 dec.localFrame = newFrameDec(d.o) 116 d.decoders <- dec 117 } 118 119 if r == nil { 120 return &d, nil 121 } 122 return &d, d.Reset(r) 123 } 124 125 // Read bytes from the decompressed stream into p. 126 // Returns the number of bytes written and any error that occurred. 127 // When the stream is done, io.EOF will be returned. 128 func (d *Decoder) Read(p []byte) (int, error) { 129 var n int 130 for { 131 if len(d.current.b) > 0 { 132 filled := copy(p, d.current.b) 133 p = p[filled:] 134 d.current.b = d.current.b[filled:] 135 n += filled 136 } 137 if len(p) == 0 { 138 break 139 } 140 if len(d.current.b) == 0 { 141 // We have an error and no more data 142 if d.current.err != nil { 143 break 144 } 145 if !d.nextBlock(n == 0) { 146 return n, d.current.err 147 } 148 } 149 } 150 if len(d.current.b) > 0 { 151 if debugDecoder { 152 println("returning", n, "still bytes left:", len(d.current.b)) 153 } 154 // Only return error at end of block 155 return n, nil 156 } 157 if d.current.err != nil { 158 d.drainOutput() 159 } 160 if debugDecoder { 161 println("returning", n, d.current.err, len(d.decoders)) 162 } 163 return n, d.current.err 164 } 165 166 // Reset will reset the decoder the supplied stream after the current has finished processing. 167 // Note that this functionality cannot be used after Close has been called. 168 // Reset can be called with a nil reader to release references to the previous reader. 169 // After being called with a nil reader, no other operations than Reset or DecodeAll or Close 170 // should be used. 171 func (d *Decoder) Reset(r io.Reader) error { 172 if d.current.err == ErrDecoderClosed { 173 return d.current.err 174 } 175 176 d.drainOutput() 177 178 d.syncStream.br.r = nil 179 if r == nil { 180 d.current.err = ErrDecoderNilInput 181 if len(d.current.b) > 0 { 182 d.current.b = d.current.b[:0] 183 } 184 d.current.flushed = true 185 return nil 186 } 187 188 // If bytes buffer and < 5MB, do sync decoding anyway. 189 if bb, ok := r.(byter); ok && bb.Len() < d.o.decodeBufsBelow && !d.o.limitToCap { 190 bb2 := bb 191 if debugDecoder { 192 println("*bytes.Buffer detected, doing sync decode, len:", bb.Len()) 193 } 194 b := bb2.Bytes() 195 var dst []byte 196 if cap(d.syncStream.dstBuf) > 0 { 197 dst = d.syncStream.dstBuf[:0] 198 } 199 200 dst, err := d.DecodeAll(b, dst) 201 if err == nil { 202 err = io.EOF 203 } 204 // Save output buffer 205 d.syncStream.dstBuf = dst 206 d.current.b = dst 207 d.current.err = err 208 d.current.flushed = true 209 if debugDecoder { 210 println("sync decode to", len(dst), "bytes, err:", err) 211 } 212 return nil 213 } 214 // Remove current block. 215 d.stashDecoder() 216 d.current.decodeOutput = decodeOutput{} 217 d.current.err = nil 218 d.current.flushed = false 219 d.current.d = nil 220 d.syncStream.dstBuf = nil 221 222 // Ensure no-one else is still running... 223 d.streamWg.Wait() 224 if d.frame == nil { 225 d.frame = newFrameDec(d.o) 226 } 227 228 if d.o.concurrent == 1 { 229 return d.startSyncDecoder(r) 230 } 231 232 d.current.output = make(chan decodeOutput, d.o.concurrent) 233 ctx, cancel := context.WithCancel(context.Background()) 234 d.current.cancel = cancel 235 d.streamWg.Add(1) 236 go d.startStreamDecoder(ctx, r, d.current.output) 237 238 return nil 239 } 240 241 // drainOutput will drain the output until errEndOfStream is sent. 242 func (d *Decoder) drainOutput() { 243 if d.current.cancel != nil { 244 if debugDecoder { 245 println("cancelling current") 246 } 247 d.current.cancel() 248 d.current.cancel = nil 249 } 250 if d.current.d != nil { 251 if debugDecoder { 252 printf("re-adding current decoder %p, decoders: %d", d.current.d, len(d.decoders)) 253 } 254 d.decoders <- d.current.d 255 d.current.d = nil 256 d.current.b = nil 257 } 258 if d.current.output == nil || d.current.flushed { 259 println("current already flushed") 260 return 261 } 262 for v := range d.current.output { 263 if v.d != nil { 264 if debugDecoder { 265 printf("re-adding decoder %p", v.d) 266 } 267 d.decoders <- v.d 268 } 269 } 270 d.current.output = nil 271 d.current.flushed = true 272 } 273 274 // WriteTo writes data to w until there's no more data to write or when an error occurs. 275 // The return value n is the number of bytes written. 276 // Any error encountered during the write is also returned. 277 func (d *Decoder) WriteTo(w io.Writer) (int64, error) { 278 var n int64 279 for { 280 if len(d.current.b) > 0 { 281 n2, err2 := w.Write(d.current.b) 282 n += int64(n2) 283 if err2 != nil && (d.current.err == nil || d.current.err == io.EOF) { 284 d.current.err = err2 285 } else if n2 != len(d.current.b) { 286 d.current.err = io.ErrShortWrite 287 } 288 } 289 if d.current.err != nil { 290 break 291 } 292 d.nextBlock(true) 293 } 294 err := d.current.err 295 if err != nil { 296 d.drainOutput() 297 } 298 if err == io.EOF { 299 err = nil 300 } 301 return n, err 302 } 303 304 // DecodeAll allows stateless decoding of a blob of bytes. 305 // Output will be appended to dst, so if the destination size is known 306 // you can pre-allocate the destination slice to avoid allocations. 307 // DecodeAll can be used concurrently. 308 // The Decoder concurrency limits will be respected. 309 func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { 310 if d.decoders == nil { 311 return dst, ErrDecoderClosed 312 } 313 314 // Grab a block decoder and frame decoder. 315 block := <-d.decoders 316 frame := block.localFrame 317 initialSize := len(dst) 318 defer func() { 319 if debugDecoder { 320 printf("re-adding decoder: %p", block) 321 } 322 frame.rawInput = nil 323 frame.bBuf = nil 324 if frame.history.decoders.br != nil { 325 frame.history.decoders.br.in = nil 326 } 327 d.decoders <- block 328 }() 329 frame.bBuf = input 330 331 for { 332 frame.history.reset() 333 err := frame.reset(&frame.bBuf) 334 if err != nil { 335 if err == io.EOF { 336 if debugDecoder { 337 println("frame reset return EOF") 338 } 339 return dst, nil 340 } 341 return dst, err 342 } 343 if err = d.setDict(frame); err != nil { 344 return nil, err 345 } 346 if frame.WindowSize > d.o.maxWindowSize { 347 if debugDecoder { 348 println("window size exceeded:", frame.WindowSize, ">", d.o.maxWindowSize) 349 } 350 return dst, ErrWindowSizeExceeded 351 } 352 if frame.FrameContentSize != fcsUnknown { 353 if frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)-initialSize) { 354 if debugDecoder { 355 println("decoder size exceeded; fcs:", frame.FrameContentSize, "> mcs:", d.o.maxDecodedSize-uint64(len(dst)-initialSize), "len:", len(dst)) 356 } 357 return dst, ErrDecoderSizeExceeded 358 } 359 if d.o.limitToCap && frame.FrameContentSize > uint64(cap(dst)-len(dst)) { 360 if debugDecoder { 361 println("decoder size exceeded; fcs:", frame.FrameContentSize, "> (cap-len)", cap(dst)-len(dst)) 362 } 363 return dst, ErrDecoderSizeExceeded 364 } 365 if cap(dst)-len(dst) < int(frame.FrameContentSize) { 366 dst2 := make([]byte, len(dst), len(dst)+int(frame.FrameContentSize)+compressedBlockOverAlloc) 367 copy(dst2, dst) 368 dst = dst2 369 } 370 } 371 372 if cap(dst) == 0 && !d.o.limitToCap { 373 // Allocate len(input) * 2 by default if nothing is provided 374 // and we didn't get frame content size. 375 size := len(input) * 2 376 // Cap to 1 MB. 377 if size > 1<<20 { 378 size = 1 << 20 379 } 380 if uint64(size) > d.o.maxDecodedSize { 381 size = int(d.o.maxDecodedSize) 382 } 383 dst = make([]byte, 0, size) 384 } 385 386 dst, err = frame.runDecoder(dst, block) 387 if err != nil { 388 return dst, err 389 } 390 if uint64(len(dst)-initialSize) > d.o.maxDecodedSize { 391 return dst, ErrDecoderSizeExceeded 392 } 393 if len(frame.bBuf) == 0 { 394 if debugDecoder { 395 println("frame dbuf empty") 396 } 397 break 398 } 399 } 400 return dst, nil 401 } 402 403 // nextBlock returns the next block. 404 // If an error occurs d.err will be set. 405 // Optionally the function can block for new output. 406 // If non-blocking mode is used the returned boolean will be false 407 // if no data was available without blocking. 408 func (d *Decoder) nextBlock(blocking bool) (ok bool) { 409 if d.current.err != nil { 410 // Keep error state. 411 return false 412 } 413 d.current.b = d.current.b[:0] 414 415 // SYNC: 416 if d.syncStream.enabled { 417 if !blocking { 418 return false 419 } 420 ok = d.nextBlockSync() 421 if !ok { 422 d.stashDecoder() 423 } 424 return ok 425 } 426 427 //ASYNC: 428 d.stashDecoder() 429 if blocking { 430 d.current.decodeOutput, ok = <-d.current.output 431 } else { 432 select { 433 case d.current.decodeOutput, ok = <-d.current.output: 434 default: 435 return false 436 } 437 } 438 if !ok { 439 // This should not happen, so signal error state... 440 d.current.err = io.ErrUnexpectedEOF 441 return false 442 } 443 next := d.current.decodeOutput 444 if next.d != nil && next.d.async.newHist != nil { 445 d.current.crc.Reset() 446 } 447 if debugDecoder { 448 var tmp [4]byte 449 binary.LittleEndian.PutUint32(tmp[:], uint32(xxhash.Sum64(next.b))) 450 println("got", len(d.current.b), "bytes, error:", d.current.err, "data crc:", tmp) 451 } 452 453 if d.o.ignoreChecksum { 454 return true 455 } 456 457 if len(next.b) > 0 { 458 d.current.crc.Write(next.b) 459 } 460 if next.err == nil && next.d != nil && next.d.hasCRC { 461 got := uint32(d.current.crc.Sum64()) 462 if got != next.d.checkCRC { 463 if debugDecoder { 464 printf("CRC Check Failed: %08x (got) != %08x (on stream)\n", got, next.d.checkCRC) 465 } 466 d.current.err = ErrCRCMismatch 467 } else { 468 if debugDecoder { 469 printf("CRC ok %08x\n", got) 470 } 471 } 472 } 473 474 return true 475 } 476 477 func (d *Decoder) nextBlockSync() (ok bool) { 478 if d.current.d == nil { 479 d.current.d = <-d.decoders 480 } 481 for len(d.current.b) == 0 { 482 if !d.syncStream.inFrame { 483 d.frame.history.reset() 484 d.current.err = d.frame.reset(&d.syncStream.br) 485 if d.current.err == nil { 486 d.current.err = d.setDict(d.frame) 487 } 488 if d.current.err != nil { 489 return false 490 } 491 if d.frame.WindowSize > d.o.maxDecodedSize || d.frame.WindowSize > d.o.maxWindowSize { 492 d.current.err = ErrDecoderSizeExceeded 493 return false 494 } 495 496 d.syncStream.decodedFrame = 0 497 d.syncStream.inFrame = true 498 } 499 d.current.err = d.frame.next(d.current.d) 500 if d.current.err != nil { 501 return false 502 } 503 d.frame.history.ensureBlock() 504 if debugDecoder { 505 println("History trimmed:", len(d.frame.history.b), "decoded already:", d.syncStream.decodedFrame) 506 } 507 histBefore := len(d.frame.history.b) 508 d.current.err = d.current.d.decodeBuf(&d.frame.history) 509 510 if d.current.err != nil { 511 println("error after:", d.current.err) 512 return false 513 } 514 d.current.b = d.frame.history.b[histBefore:] 515 if debugDecoder { 516 println("history after:", len(d.frame.history.b)) 517 } 518 519 // Check frame size (before CRC) 520 d.syncStream.decodedFrame += uint64(len(d.current.b)) 521 if d.syncStream.decodedFrame > d.frame.FrameContentSize { 522 if debugDecoder { 523 printf("DecodedFrame (%d) > FrameContentSize (%d)\n", d.syncStream.decodedFrame, d.frame.FrameContentSize) 524 } 525 d.current.err = ErrFrameSizeExceeded 526 return false 527 } 528 529 // Check FCS 530 if d.current.d.Last && d.frame.FrameContentSize != fcsUnknown && d.syncStream.decodedFrame != d.frame.FrameContentSize { 531 if debugDecoder { 532 printf("DecodedFrame (%d) != FrameContentSize (%d)\n", d.syncStream.decodedFrame, d.frame.FrameContentSize) 533 } 534 d.current.err = ErrFrameSizeMismatch 535 return false 536 } 537 538 // Update/Check CRC 539 if d.frame.HasCheckSum { 540 if !d.o.ignoreChecksum { 541 d.frame.crc.Write(d.current.b) 542 } 543 if d.current.d.Last { 544 if !d.o.ignoreChecksum { 545 d.current.err = d.frame.checkCRC() 546 } else { 547 d.current.err = d.frame.consumeCRC() 548 } 549 if d.current.err != nil { 550 println("CRC error:", d.current.err) 551 return false 552 } 553 } 554 } 555 d.syncStream.inFrame = !d.current.d.Last 556 } 557 return true 558 } 559 560 func (d *Decoder) stashDecoder() { 561 if d.current.d != nil { 562 if debugDecoder { 563 printf("re-adding current decoder %p", d.current.d) 564 } 565 d.decoders <- d.current.d 566 d.current.d = nil 567 } 568 } 569 570 // Close will release all resources. 571 // It is NOT possible to reuse the decoder after this. 572 func (d *Decoder) Close() { 573 if d.current.err == ErrDecoderClosed { 574 return 575 } 576 d.drainOutput() 577 if d.current.cancel != nil { 578 d.current.cancel() 579 d.streamWg.Wait() 580 d.current.cancel = nil 581 } 582 if d.decoders != nil { 583 close(d.decoders) 584 for dec := range d.decoders { 585 dec.Close() 586 } 587 d.decoders = nil 588 } 589 if d.current.d != nil { 590 d.current.d.Close() 591 d.current.d = nil 592 } 593 d.current.err = ErrDecoderClosed 594 } 595 596 // IOReadCloser returns the decoder as an io.ReadCloser for convenience. 597 // Any changes to the decoder will be reflected, so the returned ReadCloser 598 // can be reused along with the decoder. 599 // io.WriterTo is also supported by the returned ReadCloser. 600 func (d *Decoder) IOReadCloser() io.ReadCloser { 601 return closeWrapper{d: d} 602 } 603 604 // closeWrapper wraps a function call as a closer. 605 type closeWrapper struct { 606 d *Decoder 607 } 608 609 // WriteTo forwards WriteTo calls to the decoder. 610 func (c closeWrapper) WriteTo(w io.Writer) (n int64, err error) { 611 return c.d.WriteTo(w) 612 } 613 614 // Read forwards read calls to the decoder. 615 func (c closeWrapper) Read(p []byte) (n int, err error) { 616 return c.d.Read(p) 617 } 618 619 // Close closes the decoder. 620 func (c closeWrapper) Close() error { 621 c.d.Close() 622 return nil 623 } 624 625 type decodeOutput struct { 626 d *blockDec 627 b []byte 628 err error 629 } 630 631 func (d *Decoder) startSyncDecoder(r io.Reader) error { 632 d.frame.history.reset() 633 d.syncStream.br = readerWrapper{r: r} 634 d.syncStream.inFrame = false 635 d.syncStream.enabled = true 636 d.syncStream.decodedFrame = 0 637 return nil 638 } 639 640 // Create Decoder: 641 // ASYNC: 642 // Spawn 3 go routines. 643 // 0: Read frames and decode block literals. 644 // 1: Decode sequences. 645 // 2: Execute sequences, send to output. 646 func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output chan decodeOutput) { 647 defer d.streamWg.Done() 648 br := readerWrapper{r: r} 649 650 var seqDecode = make(chan *blockDec, d.o.concurrent) 651 var seqExecute = make(chan *blockDec, d.o.concurrent) 652 653 // Async 1: Decode sequences... 654 go func() { 655 var hist history 656 var hasErr bool 657 658 for block := range seqDecode { 659 if hasErr { 660 if block != nil { 661 seqExecute <- block 662 } 663 continue 664 } 665 if block.async.newHist != nil { 666 if debugDecoder { 667 println("Async 1: new history, recent:", block.async.newHist.recentOffsets) 668 } 669 hist.reset() 670 hist.decoders = block.async.newHist.decoders 671 hist.recentOffsets = block.async.newHist.recentOffsets 672 hist.windowSize = block.async.newHist.windowSize 673 if block.async.newHist.dict != nil { 674 hist.setDict(block.async.newHist.dict) 675 } 676 } 677 if block.err != nil || block.Type != blockTypeCompressed { 678 hasErr = block.err != nil 679 seqExecute <- block 680 continue 681 } 682 683 hist.decoders.literals = block.async.literals 684 block.err = block.prepareSequences(block.async.seqData, &hist) 685 if debugDecoder && block.err != nil { 686 println("prepareSequences returned:", block.err) 687 } 688 hasErr = block.err != nil 689 if block.err == nil { 690 block.err = block.decodeSequences(&hist) 691 if debugDecoder && block.err != nil { 692 println("decodeSequences returned:", block.err) 693 } 694 hasErr = block.err != nil 695 // block.async.sequence = hist.decoders.seq[:hist.decoders.nSeqs] 696 block.async.seqSize = hist.decoders.seqSize 697 } 698 seqExecute <- block 699 } 700 close(seqExecute) 701 hist.reset() 702 }() 703 704 var wg sync.WaitGroup 705 wg.Add(1) 706 707 // Async 3: Execute sequences... 708 frameHistCache := d.frame.history.b 709 go func() { 710 var hist history 711 var decodedFrame uint64 712 var fcs uint64 713 var hasErr bool 714 for block := range seqExecute { 715 out := decodeOutput{err: block.err, d: block} 716 if block.err != nil || hasErr { 717 hasErr = true 718 output <- out 719 continue 720 } 721 if block.async.newHist != nil { 722 if debugDecoder { 723 println("Async 2: new history") 724 } 725 hist.reset() 726 hist.windowSize = block.async.newHist.windowSize 727 hist.allocFrameBuffer = block.async.newHist.allocFrameBuffer 728 if block.async.newHist.dict != nil { 729 hist.setDict(block.async.newHist.dict) 730 } 731 732 if cap(hist.b) < hist.allocFrameBuffer { 733 if cap(frameHistCache) >= hist.allocFrameBuffer { 734 hist.b = frameHistCache 735 } else { 736 hist.b = make([]byte, 0, hist.allocFrameBuffer) 737 println("Alloc history sized", hist.allocFrameBuffer) 738 } 739 } 740 hist.b = hist.b[:0] 741 fcs = block.async.fcs 742 decodedFrame = 0 743 } 744 do := decodeOutput{err: block.err, d: block} 745 switch block.Type { 746 case blockTypeRLE: 747 if debugDecoder { 748 println("add rle block length:", block.RLESize) 749 } 750 751 if cap(block.dst) < int(block.RLESize) { 752 if block.lowMem { 753 block.dst = make([]byte, block.RLESize) 754 } else { 755 block.dst = make([]byte, maxCompressedBlockSize) 756 } 757 } 758 block.dst = block.dst[:block.RLESize] 759 v := block.data[0] 760 for i := range block.dst { 761 block.dst[i] = v 762 } 763 hist.append(block.dst) 764 do.b = block.dst 765 case blockTypeRaw: 766 if debugDecoder { 767 println("add raw block length:", len(block.data)) 768 } 769 hist.append(block.data) 770 do.b = block.data 771 case blockTypeCompressed: 772 if debugDecoder { 773 println("execute with history length:", len(hist.b), "window:", hist.windowSize) 774 } 775 hist.decoders.seqSize = block.async.seqSize 776 hist.decoders.literals = block.async.literals 777 do.err = block.executeSequences(&hist) 778 hasErr = do.err != nil 779 if debugDecoder && hasErr { 780 println("executeSequences returned:", do.err) 781 } 782 do.b = block.dst 783 } 784 if !hasErr { 785 decodedFrame += uint64(len(do.b)) 786 if decodedFrame > fcs { 787 println("fcs exceeded", block.Last, fcs, decodedFrame) 788 do.err = ErrFrameSizeExceeded 789 hasErr = true 790 } else if block.Last && fcs != fcsUnknown && decodedFrame != fcs { 791 do.err = ErrFrameSizeMismatch 792 hasErr = true 793 } else { 794 if debugDecoder { 795 println("fcs ok", block.Last, fcs, decodedFrame) 796 } 797 } 798 } 799 output <- do 800 } 801 close(output) 802 frameHistCache = hist.b 803 wg.Done() 804 if debugDecoder { 805 println("decoder goroutines finished") 806 } 807 hist.reset() 808 }() 809 810 var hist history 811 decodeStream: 812 for { 813 var hasErr bool 814 hist.reset() 815 decodeBlock := func(block *blockDec) { 816 if hasErr { 817 if block != nil { 818 seqDecode <- block 819 } 820 return 821 } 822 if block.err != nil || block.Type != blockTypeCompressed { 823 hasErr = block.err != nil 824 seqDecode <- block 825 return 826 } 827 828 remain, err := block.decodeLiterals(block.data, &hist) 829 block.err = err 830 hasErr = block.err != nil 831 if err == nil { 832 block.async.literals = hist.decoders.literals 833 block.async.seqData = remain 834 } else if debugDecoder { 835 println("decodeLiterals error:", err) 836 } 837 seqDecode <- block 838 } 839 frame := d.frame 840 if debugDecoder { 841 println("New frame...") 842 } 843 var historySent bool 844 frame.history.reset() 845 err := frame.reset(&br) 846 if debugDecoder && err != nil { 847 println("Frame decoder returned", err) 848 } 849 if err == nil { 850 err = d.setDict(frame) 851 } 852 if err == nil && d.frame.WindowSize > d.o.maxWindowSize { 853 if debugDecoder { 854 println("decoder size exceeded, fws:", d.frame.WindowSize, "> mws:", d.o.maxWindowSize) 855 } 856 857 err = ErrDecoderSizeExceeded 858 } 859 if err != nil { 860 select { 861 case <-ctx.Done(): 862 case dec := <-d.decoders: 863 dec.sendErr(err) 864 decodeBlock(dec) 865 } 866 break decodeStream 867 } 868 869 // Go through all blocks of the frame. 870 for { 871 var dec *blockDec 872 select { 873 case <-ctx.Done(): 874 break decodeStream 875 case dec = <-d.decoders: 876 // Once we have a decoder, we MUST return it. 877 } 878 err := frame.next(dec) 879 if !historySent { 880 h := frame.history 881 if debugDecoder { 882 println("Alloc History:", h.allocFrameBuffer) 883 } 884 hist.reset() 885 if h.dict != nil { 886 hist.setDict(h.dict) 887 } 888 dec.async.newHist = &h 889 dec.async.fcs = frame.FrameContentSize 890 historySent = true 891 } else { 892 dec.async.newHist = nil 893 } 894 if debugDecoder && err != nil { 895 println("next block returned error:", err) 896 } 897 dec.err = err 898 dec.hasCRC = false 899 if dec.Last && frame.HasCheckSum && err == nil { 900 crc, err := frame.rawInput.readSmall(4) 901 if len(crc) < 4 { 902 if err == nil { 903 err = io.ErrUnexpectedEOF 904 905 } 906 println("CRC missing?", err) 907 dec.err = err 908 } else { 909 dec.checkCRC = binary.LittleEndian.Uint32(crc) 910 dec.hasCRC = true 911 if debugDecoder { 912 printf("found crc to check: %08x\n", dec.checkCRC) 913 } 914 } 915 } 916 err = dec.err 917 last := dec.Last 918 decodeBlock(dec) 919 if err != nil { 920 break decodeStream 921 } 922 if last { 923 break 924 } 925 } 926 } 927 close(seqDecode) 928 wg.Wait() 929 hist.reset() 930 d.frame.history.b = frameHistCache 931 } 932 933 func (d *Decoder) setDict(frame *frameDec) (err error) { 934 dict, ok := d.dicts[frame.DictionaryID] 935 if ok { 936 if debugDecoder { 937 println("setting dict", frame.DictionaryID) 938 } 939 frame.history.setDict(dict) 940 } else if frame.DictionaryID != 0 { 941 // A zero or missing dictionary id is ambiguous: 942 // either dictionary zero, or no dictionary. In particular, 943 // zstd --patch-from uses this id for the source file, 944 // so only return an error if the dictionary id is not zero. 945 err = ErrUnknownDictionary 946 } 947 return err 948 }