-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsvutil.go
78 lines (66 loc) · 1.54 KB
/
csvutil.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package csvutil
import (
"bufio"
"encoding/csv"
"io"
"golang.org/x/text/encoding"
"golang.org/x/text/transform"
)
var utf8bom = [...]byte{0xEF, 0xBB, 0xBF}
// UTF8BOM is bytes for byte order mark of UTF8.
func UTF8BOM() []byte {
return utf8bom[:]
}
// NewReader returns *csv.Reader for UTF8.
// If source has BOM, returns true as second return value.
func NewReader(r io.Reader) (*csv.Reader, bool) {
var (
br *bufio.Reader
ok bool
bom bool
)
if br, ok = r.(*bufio.Reader); !ok {
br = bufio.NewReader(r)
}
l := len(utf8bom)
bs, err := br.Peek(l)
if err != nil {
return csv.NewReader(br), false
}
if isSameBytes(bs[:l], UTF8BOM()) {
br.Discard(l)
bom = true
}
return csv.NewReader(br), bom
}
// NewWriter returns *csv.Writer for UTF8.
// If true is given as bom, Writer writes BOM at the top.
func NewWriter(w io.Writer, bom bool) *csv.Writer {
var (
bw *bufio.Writer
ok bool
)
if bw, ok = w.(*bufio.Writer); !ok {
bw = bufio.NewWriter(w)
}
if bom {
bw.Write(UTF8BOM())
}
return csv.NewWriter(bw)
}
// NewReaderWithEnc returns *csv.Reader for given encoding.
func NewReaderWithEnc(r io.Reader, e encoding.Encoding) *csv.Reader {
return csv.NewReader(transform.NewReader(r, e.NewDecoder()))
}
// NewWriterWithEnc returns *csv.Writer for given encoding.
func NewWriterWithEnc(w io.Writer, e encoding.Encoding) *csv.Writer {
return csv.NewWriter(transform.NewWriter(w, e.NewEncoder()))
}
func isSameBytes(bs1 []byte, bs2 []byte) bool {
for i, b := range bs1 {
if b != bs2[i] {
return false
}
}
return true
}