<commit_before>// Copyright 2015, <NAME>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.md file.

package flate

import (
	"io"

	"github.com/dsnet/compress/internal"
	"github.com/dsnet/compress/internal/prefix"
)

type Reader struct {
	InputOffset  int64 // Total number of bytes read from underlying io.Reader
	OutputOffset int64 // Total number of bytes emitted from Read

	rd     prefixReader // Input source
	toRead []byte       // Uncompressed data ready to be emitted from Read
	dist   int          // The current distance
	blkLen int          // Uncompressed bytes left to read in meta-block
	cpyLen int          // Bytes left to backward dictionary copy
	last   bool         // Last block bit detected
	err    error        // Persistent error

	step      func(*Reader) // Single step of decompression work (can panic)
	stepState int           // The sub-step state for certain steps

	dict     dictDecoder    // Dynamic sliding dictionary
	litTree  prefix.Decoder // Literal and length symbol prefix decoder
	distTree prefix.Decoder // Backward distance symbol prefix decoder
}

func NewReader(r io.Reader) *Reader {
	zr := new(Reader)
	zr.Reset(r)
	return zr
}

func (zr *Reader) Read(buf []byte) (int, error) {
	for {
		if len(zr.toRead) > 0 {
			cnt := copy(buf, zr.toRead)
			zr.toRead = zr.toRead[cnt:]
			zr.OutputOffset += int64(cnt)
			return cnt, nil
		}
		if zr.err != nil {
			return 0, zr.err
		}

		// Perform next step in decompression process.
		zr.rd.Offset = zr.InputOffset
		func() {
			defer errRecover(&zr.err)
			zr.step(zr)
		}()
		var err error
		if zr.InputOffset, err = zr.rd.Flush(); err != nil {
			zr.err = err
		}
		if zr.err != nil {
			if zr.err == internal.ErrInvalid {
				zr.err = ErrCorrupt
			}
		}
		if zr.err != nil {
			zr.toRead = zr.dict.ReadFlush() // Flush what's left in case of error
		}
	}
}

func (zr *Reader) Close() error {
	if zr.err == io.EOF || zr.err == ErrClosed {
		zr.toRead = nil // Make sure future reads fail
		zr.err = ErrClosed
		return nil
	}
	return zr.err // Return the persistent error
}

func (zr *Reader) Reset(r io.Reader) error {
	*zr = Reader{
		rd:   zr.rd,
		step: (*Reader).readBlockHeader,
		dict: zr.dict,
	}
	zr.rd.Init(r)
	zr.dict.Init(maxHistSize)
	return nil
}

// readBlockHeader reads the block header according to RFC section 3.2.3.
func (zr *Reader) readBlockHeader() {
	if zr.last {
		zr.rd.ReadPads()
		panic(io.EOF)
	}<commit_msg>flate: remove return value from Reader.Reset<commit_after>// Copyright 2015, <NAME>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.md file.

package flate

import (
	"io"

	"github.com/dsnet/compress/internal"
	"github.com/dsnet/compress/internal/prefix"
)

type Reader struct {
	InputOffset  int64 // Total number of bytes read from underlying io.Reader
	OutputOffset int64 // Total number of bytes emitted from Read

	rd     prefixReader // Input source
	toRead []byte       // Uncompressed data ready to be emitted from Read
	dist   int          // The current distance
	blkLen int          // Uncompressed bytes left to read in meta-block
	cpyLen int          // Bytes left to backward dictionary copy
	last   bool         // Last block bit detected
	err    error        // Persistent error

	step      func(*Reader) // Single step of decompression work (can panic)
	stepState int           // The sub-step state for certain steps

	dict     dictDecoder    // Dynamic sliding dictionary
	litTree  prefix.Decoder // Literal and length symbol prefix decoder
	distTree prefix.Decoder // Backward distance symbol prefix decoder
}

func NewReader(r io.Reader) *Reader {
	zr := new(Reader)
	zr.Reset(r)
	return zr
}

func (zr *Reader) Read(buf []byte) (int, error) {
	for {
		if len(zr.toRead) > 0 {
			cnt := copy(buf, zr.toRead)
			zr.toRead = zr.toRead[cnt:]
			zr.OutputOffset += int64(cnt)
			return cnt, nil
		}
		if zr.err != nil {
			return 0, zr.err
		}

		// Perform next step in decompression process.
		zr.rd.Offset = zr.InputOffset
		func() {
			defer errRecover(&zr.err)
			zr.step(zr)
		}()
		var err error
		if zr.InputOffset, err = zr.rd.Flush(); err != nil {
			zr.err = err
		}
		if zr.err != nil {
			if zr.err == internal.ErrInvalid {
				zr.err = ErrCorrupt
			}
		}
		if zr.err != nil {
			zr.toRead = zr.dict.ReadFlush() // Flush what's left in case of error
		}
	}
}

func (zr *Reader) Close() error {
	if zr.err == io.EOF || zr.err == ErrClosed {
		zr.toRead = nil // Make sure future reads fail
		zr.err = ErrClosed
		return nil
	}
	return zr.err // Return the persistent error
}

func (zr *Reader) Reset(r io.Reader) {
	*zr = Reader{
		rd:   zr.rd,
		step: (*Reader).readBlockHeader,
		dict: zr.dict,
	}
	zr.rd.Init(r)
	zr.dict.Init(maxHistSize)
}

// readBlockHeader reads the block header according to RFC section 3.2.3.
func (zr *Reader) readBlockHeader() {
	if zr.last {
		zr.rd.ReadPads()
		panic(io.EOF)
	}
{'fraction_non_alphanumeric': 0.11020163705330405, 'fraction_numerical': 0.005989219405070872, 'mean_word_length': 2.686534216335541, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3047294', 'n_tokens_mistral': 1876, 'n_tokens_neox': 1679, 'n_words': 560}