github.com/blong14/gache@v0.0.0-20240124023949-89416fd8bbfa/internal/io/file/csv.go (about)

     1  package file
     2  
     3  import (
     4  	"encoding/csv"
     5  	"io"
     6  	"math"
     7  	"os"
     8  	"runtime"
     9  
    10  	gerrors "github.com/blong14/gache/internal/errors"
    11  )
    12  
    13  type Reader struct {
    14  	max       int
    15  	token     [][]string
    16  	errs      *gerrors.Error
    17  	data      string
    18  	handle    *os.File
    19  	csvReader *csv.Reader
    20  }
    21  
    22  func (s *Reader) Init() {
    23  	f, err := os.Open(s.data)
    24  	if err != nil {
    25  		panic(err)
    26  	}
    27  	s.handle = f
    28  	s.csvReader = csv.NewReader(s.handle)
    29  	s.csvReader.ReuseRecord = false
    30  	s.token = make([][]string, s.max)
    31  }
    32  
    33  func (s *Reader) Err() *gerrors.Error {
    34  	return s.errs
    35  }
    36  
    37  func (s *Reader) Rows() [][]string {
    38  	return s.token
    39  }
    40  
    41  func (s *Reader) Close() {
    42  	if err := s.handle.Close(); err != nil {
    43  		s.errs = gerrors.Append(s.errs, err)
    44  	}
    45  }
    46  
    47  func (s *Reader) Scan() bool {
    48  	if err := s.errs.ErrorOrNil(); err != nil {
    49  		return false
    50  	}
    51  	out := make([][]string, 0, s.max)
    52  	for {
    53  		row, err := s.csvReader.Read()
    54  		if err == io.EOF {
    55  			break
    56  		}
    57  		if err != nil {
    58  			s.errs = gerrors.Append(s.errs, err)
    59  			break
    60  		}
    61  		out = append(out, row)
    62  		if len(out) == s.max {
    63  			copy(s.token, out)
    64  			return true
    65  		}
    66  	}
    67  	if len(out) > 0 {
    68  		s.token = out
    69  		return true
    70  	}
    71  	return false
    72  }
    73  
    74  var (
    75  	base     = float64(2)
    76  	exponent = float64(14)
    77  )
    78  
    79  func ScanCSV(data string) *Reader {
    80  	return &Reader{
    81  		data: data,
    82  		max:  int(math.Pow(base, exponent)) / (runtime.NumCPU() / int(base)),
    83  	}
    84  }