package extraio

import (
	
	
	
)

// ErrCounterOverflow is an error that CountReader returns when the counter
// overflows 64-bit unsigned integer.
var ErrCounterOverflow = errors.New("extraio: counter overflow")

// CountReader counts bytes read from the underlying io.Reader. It is implicitly
// limited to at most math.MaxUint64 bytes and returns ErrCounterOverflow error
// if the limit is exceeded. In practice, that would require counting thousands
// of petabytes to reach this limitation.
type CountReader struct {
	reader io.Reader
	count  uint64 // mutable
}

// NewCountReader returns a new reader that counts bytes read from r.
func ( io.Reader) *CountReader {
	return &CountReader{reader: }
}

// Count returns the count of bytes read.
func ( *CountReader) () uint64 {
	return .count
}

// Read implements the io.Reader interface. It reads from the underlying
// io.Reader and increments read bytes counter.
func ( *CountReader) ( []byte) (int, error) {
	switch  := math.MaxUint64 - .count; {
	case  == 0:
		return 0, ErrCounterOverflow
	case  < uint64(len()):
		 = [:]
	}
	,  := .reader.Read()
	if  > 0 {
		.count += uint64()
	}
	return , 
}