/
string-scanner.go
86 lines (78 loc) · 1.86 KB
/
string-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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package sam
import (
"fmt"
)
// A StringScanner can be used scan/parse ASCII strings representing
// lines in SAM files.
//
// The zero StringScanner is valid and empty.
type StringScanner struct {
index int
data string
err error
}
// Err returns the error that occurred during scanning/parsing.
func (sc *StringScanner) Err() error {
return sc.err
}
// Reset resets the scanner, and initializes it with the given string.
func (sc *StringScanner) Reset(s string) {
sc.index = 0
sc.data = s
sc.err = nil
}
// Len returns the number of ASCII characters that still need to be
// scanned/parsed. Returns 0 if Err() would return a non-nil value.
func (sc *StringScanner) Len() int {
if sc.err != nil {
return 0
}
return len(sc.data) - sc.index
}
func (sc *StringScanner) readByteUntil(c byte) (b byte, found bool) {
if sc.err != nil {
return 0, false
}
start := sc.index
next := start + 1
if next >= len(sc.data) {
sc.index = len(sc.data)
return sc.data[start], false
} else if sc.data[next] != c {
if sc.err == nil {
sc.err = fmt.Errorf("unexpected character %v in StringScanner.ReadByteUntil", sc.data[next])
}
return 0, false
} else {
sc.index = next + 1
return sc.data[start], true
}
}
func (sc *StringScanner) readUntil(c byte) (s string, found bool) {
if sc.err != nil {
return "", false
}
start := sc.index
for end := sc.index; end < len(sc.data); end++ {
if sc.data[end] == c {
sc.index = end + 1
return sc.data[start:end], true
}
}
sc.index = len(sc.data)
return sc.data[start:], false
}
func (sc *StringScanner) readUntil2(c1, c2 byte) (s string, b byte) {
if sc.err != nil {
return "", 0
}
start := sc.index
for end := sc.index; end < len(sc.data); end++ {
if c := sc.data[end]; (c == c1) || (c == c2) {
sc.index = end + 1
return sc.data[start:end], c
}
}
sc.index = len(sc.data)
return sc.data[start:], 0
}