1
2
3
4
5 package main
6
7 import (
8 "bufio"
9 "io"
10 )
11
12
13 type NamedScanner struct {
14 Name string
15 Scanner *bufio.Scanner
16 }
17
18
19
20 type NamedReader struct {
21 Name string
22 Reader io.Reader
23 }
24
25
26
27 type MultiScanner struct {
28 scanners []NamedScanner
29 scannerIdx int
30 line int
31 totalLine int
32 err error
33 }
34
35
36 func NewMultiScanner(scanners []NamedScanner) *MultiScanner {
37 return &MultiScanner{
38 scanners: scanners,
39 scannerIdx: -1,
40 }
41 }
42
43
44 func MultiScannerFromReaders(readers []NamedReader) *MultiScanner {
45 var scanners []NamedScanner
46 for _, r := range readers {
47 scanners = append(scanners, NamedScanner{
48 Name: r.Name,
49 Scanner: bufio.NewScanner(r.Reader),
50 })
51 }
52 return NewMultiScanner(scanners)
53 }
54
55
56
57
58
59
60
61 func (ms *MultiScanner) Scan() bool {
62 if ms.scannerIdx == -1 {
63 ms.scannerIdx = 0
64 }
65
66 for ms.scannerIdx < len(ms.scanners) {
67 current := ms.scanners[ms.scannerIdx]
68 if current.Scanner.Scan() {
69 ms.line++
70 ms.totalLine++
71 return true
72 }
73 if err := current.Scanner.Err(); err != nil {
74 ms.err = err
75 return false
76 }
77
78 ms.scannerIdx++
79 ms.line = 0
80 }
81
82 return false
83 }
84
85
86 func (ms *MultiScanner) Text() string {
87 if ms.scannerIdx < 0 || ms.scannerIdx >= len(ms.scanners) {
88 return ""
89 }
90 return ms.scanners[ms.scannerIdx].Scanner.Text()
91 }
92
93
94 func (ms *MultiScanner) Err() error {
95 return ms.err
96 }
97
98
99 func (ms *MultiScanner) Name() string {
100 if ms.scannerIdx < 0 {
101 return "<before first>"
102 }
103 if ms.scannerIdx >= len(ms.scanners) {
104 return "<after last>"
105 }
106 return ms.scanners[ms.scannerIdx].Name
107 }
108
109
110 func (ms *MultiScanner) Line() int {
111 return ms.line
112 }
113
114
115 func (ms *MultiScanner) TotalLine() int {
116 return ms.totalLine
117 }
118
View as plain text