-
Notifications
You must be signed in to change notification settings - Fork 0
/
regexwriter.go
111 lines (89 loc) · 2.95 KB
/
regexwriter.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
108
109
110
111
package regexwriter
import "regexp"
// RegexAction is a combination of a regular expression and a function
type RegexAction struct {
// Search expression
regex *regexp.Regexp
// Action to take on matched/non-matched bytes
action func([][]byte)
}
// IsMatch returns whether the regular expresion is a match for the
// given bytes
func (r RegexAction) IsMatch(b []byte) bool {
return r.regex.Match(b)
}
// Matches returns all regular expression matches in the given bytes
func (r RegexAction) Matches(b []byte) [][][]byte {
return r.regex.FindAllSubmatch(b, -1)
}
// PerformAction executes the defined function on the given multidimensional
// byte array
func (r RegexAction) PerformAction(bytes [][]byte) {
r.action(bytes)
}
// CreateAction returns a RegexAction object
func CreateAction(r *regexp.Regexp, a func([][]byte)) RegexAction {
return RegexAction{r, a}
}
// RegexWriter allows binding of matching and non-matching actions to
// a writer interface
type RegexWriter struct {
// RawOutput contains the full output of the writer
RawOutput string
matchActions []RegexAction
nonMatchActions []RegexAction
}
// Reset clears this RegexWriter's set members
func (re *RegexWriter) Reset() {
re.ClearMatchActions()
re.ClearNonMatchActions()
re.RawOutput = ""
}
// Write is the implementation of the Writer interface
func (re RegexWriter) Write(b []byte) (n int, err error) {
out := string(b[:])
re.RawOutput += out
for _, v := range re.matchActions {
if v.IsMatch(b) {
for _, match := range v.Matches(b) {
v.PerformAction(match)
}
}
}
for _, v := range re.nonMatchActions {
if !v.IsMatch(b) {
// Since there's no match here and we're reusing the same function
// definition, simply make the bytes look like [][]byte
v.PerformAction([][]byte{b[:]})
}
}
return len(b), nil
}
// AddMatchAction adds a match action to the RegexWriter instance
func (re *RegexWriter) AddMatchAction(pattern string, handler func([][]byte)) {
regex := regexp.MustCompile(pattern)
if re.matchActions == nil {
re.matchActions = make([]RegexAction, 0)
}
re.matchActions = append(re.matchActions, CreateAction(regex, handler))
}
// ClearMatchActions clears the matchActions array
func (re *RegexWriter) ClearMatchActions() {
re.matchActions = nil
}
// AddNonMatchAction adds a non-matching action to the RegexWriter instance
func (re *RegexWriter) AddNonMatchAction(pattern string, handler func([][]byte)) {
regex := regexp.MustCompile(pattern)
if re.nonMatchActions == nil {
re.nonMatchActions = make([]RegexAction, 0)
}
re.nonMatchActions = append(re.nonMatchActions, CreateAction(regex, handler))
}
// ClearNonMatchActions clears the nonMatchActions array
func (re *RegexWriter) ClearNonMatchActions() {
re.nonMatchActions = nil
}
// ClearRawOutput clears the raw output member
func (re *RegexWriter) ClearRawOutput() {
re.RawOutput = ""
}