github.com/attic-labs/noms@v0.0.0-20210827224422-e5fa29d95e8b/samples/go/csv/csv_reader.go (about) 1 // Copyright 2016 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package csv 6 7 import ( 8 "bufio" 9 "encoding/csv" 10 "io" 11 ) 12 13 var ( 14 rByte byte = 13 // the byte that corresponds to the '\r' rune. 15 nByte byte = 10 // the byte that corresponds to the '\n' rune. 16 ) 17 18 type reader struct { 19 r *bufio.Reader 20 } 21 22 // Read replaces CR line endings in the source reader with LF line endings if the CR is not followed by a LF. 23 func (r reader) Read(p []byte) (n int, err error) { 24 n, err = r.r.Read(p) 25 bn, err := r.r.Peek(1) 26 for i, b := range p { 27 // if the current byte is a CR and the next byte is NOT a LF then replace the current byte with a LF 28 if j := i + 1; b == rByte && ((j < len(p) && p[j] != nByte) || (len(bn) > 0 && bn[0] != nByte)) { 29 p[i] = nByte 30 } 31 } 32 return 33 } 34 35 func SkipRecords(r *csv.Reader, n uint) error { 36 var err error 37 for i := uint(0); i < n; i++ { 38 _, err = r.Read() 39 if err != nil { 40 return err 41 } 42 } 43 return err 44 } 45 46 // NewCSVReader returns a new csv.Reader that splits on comma 47 func NewCSVReader(res io.Reader, comma rune) *csv.Reader { 48 bufRes := bufio.NewReader(res) 49 r := csv.NewReader(reader{r: bufRes}) 50 r.Comma = comma 51 r.FieldsPerRecord = -1 // Don't enforce number of fields. 52 return r 53 }