/
io.go
107 lines (99 loc) · 2.09 KB
/
io.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package catlib
import (
"bufio"
"fmt"
"golang.org/x/text/encoding"
"golang.org/x/text/encoding/japanese"
"golang.org/x/text/encoding/korean"
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/encoding/traditionalchinese"
"golang.org/x/text/encoding/unicode"
"golang.org/x/text/transform"
"io"
"os/exec"
"regexp"
"runtime"
"strconv"
)
var enc *encoding.Encoding
func detectEncoding() (*encoding.Encoding, error) {
if runtime.GOOS == `windows` {
c := exec.Command("chcp")
out, e2 := c.StdoutPipe()
if e2 != nil {
return nil, e2
}
c.Start()
s := bufio.NewScanner(out)
codepage := -1
reg := regexp.MustCompile(`^.*\s([0-9]*)\s*$`)
for s.Scan() {
line := s.Text()
if len(line) == 0 {
continue
}
m := reg.FindSubmatch([]byte(line))
if len(m) < 2 {
continue
}
codepageStr := string(m[1])
i, e4 := strconv.Atoi(codepageStr)
if e4 != nil {
continue
}
codepage = i
}
e3 := c.Wait()
if e3 != nil {
return nil, e3
}
switch codepage {
case 932:
return &japanese.ShiftJIS, nil
case 20932:
return &japanese.EUCJP, nil
case 50220, 50221, 50222:
return &japanese.ISO2022JP, nil
case 949:
return &korean.EUCKR, nil
case 54936:
return &simplifiedchinese.GB18030, nil
case 936:
return &simplifiedchinese.GBK, nil
case 52936:
return &simplifiedchinese.HZGB2312, nil
case 950:
return &traditionalchinese.Big5, nil
}
return nil, fmt.Errorf("cannot detect encoding")
} else {
return &unicode.UTF8, nil
}
}
func currentEncoding() encoding.Encoding {
if enc == nil {
ret, err := detectEncoding()
if err != nil {
enc = &unicode.UTF8
} else {
enc = ret
}
}
return *enc
}
func StdoutPipe(cmd *exec.Cmd) (io.Reader, error) {
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
ret := transform.NewReader(stdout, currentEncoding().NewDecoder())
return ret, nil
}
func StderrPipe(cmd *exec.Cmd) (io.Reader, error) {
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, err
}
ret := transform.NewReader(stderr, currentEncoding().NewDecoder())
return ret, nil
}