Skip will skip n bytes forward in the decompressed output. For larger skips this consumes less CPU and is faster than reading output and discarding it. CRC is not checked on skipped blocks. io.ErrUnexpectedEOF is returned if the stream ends before all bytes have been skipped. If a decoding error is
(n int64)
| 667 | // io.ErrUnexpectedEOF is returned if the stream ends before all bytes have been skipped. |
| 668 | // If a decoding error is encountered subsequent calls to Read will also fail. |
| 669 | func (r *Reader) Skip(n int64) error { |
| 670 | if n < 0 { |
| 671 | return errors.New("attempted negative skip") |
| 672 | } |
| 673 | if r.err != nil { |
| 674 | return r.err |
| 675 | } |
| 676 | |
| 677 | for n > 0 { |
| 678 | if r.i < r.j { |
| 679 | // Skip in buffer. |
| 680 | // decoded[i:j] contains decoded bytes that have not yet been passed on. |
| 681 | left := int64(r.j - r.i) |
| 682 | if left >= n { |
| 683 | tmp := int64(r.i) + n |
| 684 | if tmp > math.MaxInt32 { |
| 685 | return errors.New("s2: internal overflow in skip") |
| 686 | } |
| 687 | r.i = int(tmp) |
| 688 | return nil |
| 689 | } |
| 690 | n -= int64(r.j - r.i) |
| 691 | r.i = r.j |
| 692 | } |
| 693 | |
| 694 | // Buffer empty; read blocks until we have content. |
| 695 | if !r.readFull(r.buf[:4], true) { |
| 696 | if r.err == io.EOF { |
| 697 | r.err = io.ErrUnexpectedEOF |
| 698 | } |
| 699 | return r.err |
| 700 | } |
| 701 | chunkType := r.buf[0] |
| 702 | if !r.readHeader { |
| 703 | if chunkType != chunkTypeStreamIdentifier { |
| 704 | r.err = ErrCorrupt |
| 705 | return r.err |
| 706 | } |
| 707 | r.readHeader = true |
| 708 | } |
| 709 | chunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16 |
| 710 | |
| 711 | // The chunk types are specified at |
| 712 | // https://github.com/google/snappy/blob/master/framing_format.txt |
| 713 | switch chunkType { |
| 714 | case chunkTypeCompressedData: |
| 715 | r.blockStart += int64(r.j) |
| 716 | // Section 4.2. Compressed data (chunk type 0x00). |
| 717 | if chunkLen < checksumSize { |
| 718 | r.err = ErrCorrupt |
| 719 | return r.err |
| 720 | } |
| 721 | if !r.ensureBufferSize(chunkLen) { |
| 722 | if r.err == nil { |
| 723 | r.err = ErrUnsupported |
| 724 | } |
| 725 | return r.err |
| 726 | } |