-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscanner.go
71 lines (58 loc) · 1.26 KB
/
scanner.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
package goetf
import (
"fmt"
"io"
"sync"
)
type scanner struct {
// Buffer where readings are stored. Default size is 2048.
buf []byte
// Start of unread data in buf.
scanp int
// Total bytes consumed.
scanned int64
r io.Reader
}
var scannerPool = sync.Pool{
New: func() any {
return &scanner{}
},
}
func newScanner(r io.Reader) *scanner {
scan := scannerPool.Get().(*scanner)
scan.scanned = 0
scan.r = r
scan.buf = make([]byte, 4096)
return scan
}
func (s *scanner) reset(bufinit int) {
newLen := bufinit + len(s.buf)*2
s.buf = make([]byte, newLen)
s.scanp = 0
}
func (s *scanner) readByte() (byte, error) {
_, b, err := s.readN(1)
return b[0], err
}
func (s *scanner) readN(n int) (int, []byte, error) {
if s.buf == nil {
return 0, nil, fmt.Errorf("scanner readN error: invalid buffer")
}
if (s.scanp + n) >= len(s.buf) {
s.reset(n)
}
bytes, err := s.r.Read(s.buf[s.scanp : s.scanp+n])
s.forward(bytes)
if err != nil {
return bytes, s.buf, err
}
return bytes, s.buf[s.scanp-bytes : s.scanp], nil
}
func (s *scanner) forward(steps int) {
s.scanp += steps
s.scanned += int64(steps)
}
func (s *scanner) eof() bool {
_, _, err := s.readN(0)
return err == io.EOF
}