2020-05-31 19:00:19 +08:00
|
|
|
package segments
|
|
|
|
|
|
|
|
type Int = int64
|
|
|
|
|
|
|
|
type Length = Int
|
|
|
|
|
|
|
|
func min(i Int, rest ...Int) Int {
|
|
|
|
ret := i
|
|
|
|
for _, i := range rest {
|
|
|
|
if i < ret {
|
|
|
|
ret = i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
type Extent struct {
|
|
|
|
Start, Length Int
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e Extent) End() Int {
|
|
|
|
return e.Start + e.Length
|
|
|
|
}
|
|
|
|
|
|
|
|
type (
|
|
|
|
Callback = func(int, Extent) bool
|
|
|
|
LengthIter = func() (Length, bool)
|
|
|
|
)
|
|
|
|
|
2020-06-01 16:25:45 +08:00
|
|
|
func Scan(haystack LengthIter, needle Extent, callback Callback) bool {
|
2020-05-31 19:00:19 +08:00
|
|
|
i := 0
|
|
|
|
for needle.Length != 0 {
|
|
|
|
l, ok := haystack()
|
|
|
|
if !ok {
|
2020-06-01 16:25:45 +08:00
|
|
|
return false
|
2020-05-31 19:00:19 +08:00
|
|
|
}
|
|
|
|
if needle.Start < l || needle.Start == l && l == 0 {
|
|
|
|
e1 := Extent{
|
|
|
|
Start: needle.Start,
|
|
|
|
Length: min(l, needle.End()) - needle.Start,
|
|
|
|
}
|
|
|
|
if e1.Length >= 0 {
|
|
|
|
if !callback(i, e1) {
|
2020-06-01 16:25:45 +08:00
|
|
|
return true
|
2020-05-31 19:00:19 +08:00
|
|
|
}
|
2020-05-31 22:14:51 +08:00
|
|
|
needle.Start = 0
|
2020-05-31 19:00:19 +08:00
|
|
|
needle.Length -= e1.Length
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
needle.Start -= l
|
|
|
|
}
|
|
|
|
i++
|
|
|
|
}
|
2020-06-01 16:25:45 +08:00
|
|
|
return true
|
2020-05-31 19:00:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func LocaterFromLengthIter(li LengthIter) Locater {
|
2020-06-01 16:25:45 +08:00
|
|
|
return func(e Extent, c Callback) bool {
|
|
|
|
return Scan(li, e, c)
|
2020-05-31 19:00:19 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-01 16:25:45 +08:00
|
|
|
type Locater func(Extent, Callback) bool
|