本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
1.7KB

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