github.com/KEINOS/go-countline@v1.1.0/cl/_alt/alt3.go (about)

     1  //nolint:revive,stylecheck
     2  package _alt
     3  
     4  import (
     5  	"bufio"
     6  	"io"
     7  
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // ----------------------------------------------------------------------------
    12  //  CountLinesAlt3
    13  // ----------------------------------------------------------------------------
    14  
    15  // CountLinesAlt3 is the 3rd attempt to count the number of lines in a file using
    16  // bufio.Reader without goroutines.
    17  func CountLinesAlt3(inputReader io.Reader) (int, error) {
    18  	if inputReader == nil {
    19  		return 0, errors.New("given reader is nil")
    20  	}
    21  
    22  	bufReader := bufio.NewReader(inputReader)
    23  
    24  	buf := make([]byte, bufio.MaxScanTokenSize)
    25  	hasFragment := false
    26  	count := 0
    27  
    28  	countLF := func(b []byte) int {
    29  		count2 := 0
    30  
    31  		for _, c := range b {
    32  			hasFragment = true
    33  
    34  			if c == '\n' {
    35  				count2++
    36  
    37  				hasFragment = false
    38  			}
    39  		}
    40  
    41  		return count2
    42  	}
    43  
    44  	for {
    45  		numRead, err := bufReader.Read(buf) // loading chunk into buffer
    46  		if err != nil {
    47  			if err == io.EOF {
    48  				break
    49  			}
    50  
    51  			return 0, errors.Wrap(err, "failed to read from reader")
    52  		}
    53  
    54  		if numRead > 0 {
    55  			count += countLF(buf[:numRead])
    56  		}
    57  	}
    58  
    59  	if hasFragment {
    60  		count++
    61  	}
    62  
    63  	return count, nil
    64  }