-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfilter_windows.go
75 lines (68 loc) · 1.35 KB
/
filter_windows.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
package mbcs
import (
"bufio"
"bytes"
"io"
"unicode/utf8"
)
type _Status int
const (
_GuessMinimum _Status = iota
_GuessAlways
_AnsiFixed
_Utf8Fixed
)
// Filter is the class like bufio.Scanner but detects the encoding-type
// and converts to utf8 on Windows. On other OSes, it works like bufio.Scanner
type Filter struct {
sc *bufio.Scanner
text string
status _Status
err error
codepage uintptr
}
func (f *Filter) forceGuessAlways() {
f.status = _GuessAlways
}
func newFilter(r io.Reader, codepage uintptr) *Filter {
return &Filter{
sc: bufio.NewScanner(r),
codepage: codepage,
}
}
func (f *Filter) scan() bool {
if !f.sc.Scan() {
f.err = f.sc.Err()
return false
}
line := f.sc.Bytes()
if f.status == _Utf8Fixed {
f.text = f.sc.Text()
return true
}
if f.status != _AnsiFixed {
if bytes.HasPrefix(line, _BOM) {
f.text = string(line[len(_BOM):])
if f.status != _GuessAlways {
f.status = _Utf8Fixed
}
return true
}
if utf8.Valid(line) {
f.text = f.sc.Text()
// f.status should not be fixed yet,
// because it does not work expected
// when the first line uses ascii-code only
// and the second line uses CP932.
return true
}
}
f.text, f.err = ansiToUtf8(line, f.codepage)
if f.err != nil {
return false
}
if f.status != _GuessAlways {
f.status = _AnsiFixed
}
return true
}