1package match 2 3import ( 4 "fmt" 5) 6 7type EveryOf struct { 8 Matchers Matchers 9} 10 11func NewEveryOf(m ...Matcher) EveryOf { 12 return EveryOf{Matchers(m)} 13} 14 15func (self *EveryOf) Add(m Matcher) error { 16 self.Matchers = append(self.Matchers, m) 17 return nil 18} 19 20func (self EveryOf) Len() (l int) { 21 for _, m := range self.Matchers { 22 if ml := m.Len(); l > 0 { 23 l += ml 24 } else { 25 return -1 26 } 27 } 28 29 return 30} 31 32func (self EveryOf) Index(s string) (int, []int) { 33 var index int 34 var offset int 35 36 // make `in` with cap as len(s), 37 // cause it is the maximum size of output segments values 38 next := acquireSegments(len(s)) 39 current := acquireSegments(len(s)) 40 41 sub := s 42 for i, m := range self.Matchers { 43 idx, seg := m.Index(sub) 44 if idx == -1 { 45 releaseSegments(next) 46 releaseSegments(current) 47 return -1, nil 48 } 49 50 if i == 0 { 51 // we use copy here instead of `current = seg` 52 // cause seg is a slice from reusable buffer `in` 53 // and it could be overwritten in next iteration 54 current = append(current, seg...) 55 } else { 56 // clear the next 57 next = next[:0] 58 59 delta := index - (idx + offset) 60 for _, ex := range current { 61 for _, n := range seg { 62 if ex+delta == n { 63 next = append(next, n) 64 } 65 } 66 } 67 68 if len(next) == 0 { 69 releaseSegments(next) 70 releaseSegments(current) 71 return -1, nil 72 } 73 74 current = append(current[:0], next...) 75 } 76 77 index = idx + offset 78 sub = s[index:] 79 offset += idx 80 } 81 82 releaseSegments(next) 83 84 return index, current 85} 86 87func (self EveryOf) Match(s string) bool { 88 for _, m := range self.Matchers { 89 if !m.Match(s) { 90 return false 91 } 92 } 93 94 return true 95} 96 97func (self EveryOf) String() string { 98 return fmt.Sprintf("<every_of:[%s]>", self.Matchers) 99} 100