github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/common/strmatcher/indexmatcher_linear.go (about) 1 package strmatcher 2 3 // LinearIndexMatcher is an implementation of IndexMatcher. 4 type LinearIndexMatcher struct { 5 count uint32 6 full *FullMatcherGroup 7 domain *DomainMatcherGroup 8 substr *SubstrMatcherGroup 9 regex *SimpleMatcherGroup 10 } 11 12 func NewLinearIndexMatcher() *LinearIndexMatcher { 13 return new(LinearIndexMatcher) 14 } 15 16 // Add implements IndexMatcher.Add. 17 func (g *LinearIndexMatcher) Add(matcher Matcher) uint32 { 18 g.count++ 19 index := g.count 20 21 switch matcher := matcher.(type) { 22 case FullMatcher: 23 if g.full == nil { 24 g.full = NewFullMatcherGroup() 25 } 26 g.full.AddFullMatcher(matcher, index) 27 case DomainMatcher: 28 if g.domain == nil { 29 g.domain = NewDomainMatcherGroup() 30 } 31 g.domain.AddDomainMatcher(matcher, index) 32 case SubstrMatcher: 33 if g.substr == nil { 34 g.substr = new(SubstrMatcherGroup) 35 } 36 g.substr.AddSubstrMatcher(matcher, index) 37 default: 38 if g.regex == nil { 39 g.regex = new(SimpleMatcherGroup) 40 } 41 g.regex.AddMatcher(matcher, index) 42 } 43 44 return index 45 } 46 47 // Build implements IndexMatcher.Build. 48 func (*LinearIndexMatcher) Build() error { 49 return nil 50 } 51 52 // Match implements IndexMatcher.Match. 53 func (g *LinearIndexMatcher) Match(input string) []uint32 { 54 // Allocate capacity to prevent matches escaping to heap 55 result := make([][]uint32, 0, 5) 56 if g.full != nil { 57 if matches := g.full.Match(input); len(matches) > 0 { 58 result = append(result, matches) 59 } 60 } 61 if g.domain != nil { 62 if matches := g.domain.Match(input); len(matches) > 0 { 63 result = append(result, matches) 64 } 65 } 66 if g.substr != nil { 67 if matches := g.substr.Match(input); len(matches) > 0 { 68 result = append(result, matches) 69 } 70 } 71 if g.regex != nil { 72 if matches := g.regex.Match(input); len(matches) > 0 { 73 result = append(result, matches) 74 } 75 } 76 return CompositeMatches(result) 77 } 78 79 // MatchAny implements IndexMatcher.MatchAny. 80 func (g *LinearIndexMatcher) MatchAny(input string) bool { 81 if g.full != nil && g.full.MatchAny(input) { 82 return true 83 } 84 if g.domain != nil && g.domain.MatchAny(input) { 85 return true 86 } 87 if g.substr != nil && g.substr.MatchAny(input) { 88 return true 89 } 90 return g.regex != nil && g.regex.MatchAny(input) 91 } 92 93 // Size implements IndexMatcher.Size. 94 func (g *LinearIndexMatcher) Size() uint32 { 95 return g.count 96 }