Close will flush the final output and close the stream. The function will block until everything has been written. The Encoder can still be re-used after calling this.
()
| 587 | // The function will block until everything has been written. |
| 588 | // The Encoder can still be re-used after calling this. |
| 589 | func (e *Encoder) Close() error { |
| 590 | s := &e.state |
| 591 | if s.encoder == nil { |
| 592 | return nil |
| 593 | } |
| 594 | if e.o.concurrentBlocks { |
| 595 | return e.closeJobs() |
| 596 | } |
| 597 | if s.w == nil { |
| 598 | if len(s.filling) == 0 && !s.headerWritten && !s.eofWritten && s.nInput == 0 { |
| 599 | return nil |
| 600 | } |
| 601 | return errors.New("zstd: encoder has no writer") |
| 602 | } |
| 603 | |
| 604 | err := e.nextBlock(true) |
| 605 | if err != nil { |
| 606 | if errors.Is(s.err, ErrEncoderClosed) { |
| 607 | return nil |
| 608 | } |
| 609 | return err |
| 610 | } |
| 611 | if s.frameContentSize > 0 { |
| 612 | if s.nInput != s.frameContentSize { |
| 613 | return fmt.Errorf("frame content size %d given, but %d bytes was written", s.frameContentSize, s.nInput) |
| 614 | } |
| 615 | } |
| 616 | if e.state.fullFrameWritten { |
| 617 | return s.err |
| 618 | } |
| 619 | s.wg.Wait() |
| 620 | s.wWg.Wait() |
| 621 | |
| 622 | if s.err != nil { |
| 623 | return s.err |
| 624 | } |
| 625 | if s.writeErr != nil { |
| 626 | return s.writeErr |
| 627 | } |
| 628 | |
| 629 | // Write CRC |
| 630 | if e.o.crc && s.err == nil { |
| 631 | // heap alloc. |
| 632 | var tmp [4]byte |
| 633 | _, s.err = s.w.Write(s.encoder.AppendCRC(tmp[:0])) |
| 634 | s.nWritten += 4 |
| 635 | } |
| 636 | |
| 637 | // Add padding with content from crypto/rand.Reader |
| 638 | if s.err == nil && e.o.pad > 0 { |
| 639 | add := calcSkippableFrame(s.nWritten, int64(e.o.pad)) |
| 640 | frame, err := skippableFrame(s.filling[:0], add, rand.Reader) |
| 641 | if err != nil { |
| 642 | return err |
| 643 | } |
| 644 | _, s.err = s.w.Write(frame) |
| 645 | } |
| 646 | if s.err == nil { |