Hunter0x7c7
2022-08-11 a82f9cb69f63aaeba40c024960deda7d75b9fece
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
package strmatcher
 
import (
    "sort"
    "strings"
)
 
// SubstrMatcherGroup is implementation of MatcherGroup,
// It is simply implmeneted to comply with the priority specification of Substr matchers.
type SubstrMatcherGroup struct {
    patterns []string
    values   []uint32
}
 
// AddSubstrMatcher implements MatcherGroupForSubstr.AddSubstrMatcher.
func (g *SubstrMatcherGroup) AddSubstrMatcher(matcher SubstrMatcher, value uint32) {
    g.patterns = append(g.patterns, matcher.Pattern())
    g.values = append(g.values, value)
}
 
// Match implements MatcherGroup.Match.
func (g *SubstrMatcherGroup) Match(input string) []uint32 {
    result := []uint32{}
    for i, pattern := range g.patterns {
        for j := strings.LastIndex(input, pattern); j != -1; j = strings.LastIndex(input[:j], pattern) {
            result = append(result, uint32(j)<<16|uint32(i)&0xffff) // uint32: position (higher 16 bit) | patternIdx (lower 16 bit)
        }
    }
    // Sort the match results in dictionary order, so that:
    //   1. Pattern matched at smaller position (meaning matched further) takes precedence.
    //   2. When patterns matched at same position, pattern with smaller index (meaning inserted early) takes precedence.
    sort.Slice(result, func(i, j int) bool { return result[i] < result[j] })
    for i, entry := range result {
        result[i] = g.values[entry&0xffff] // Get pattern value from its index (the lower 16 bit)
    }
    return result
}
 
// MatchAny implements MatcherGroup.MatchAny.
func (g *SubstrMatcherGroup) MatchAny(input string) bool {
    for _, pattern := range g.patterns {
        if strings.Contains(input, pattern) {
            return true
        }
    }
    return false
}