torrent/segments/segments.go

64 lines
1.0 KiB
Go
Raw Normal View History

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 08:25:45 +00:00
func Scan(haystack LengthIter, needle Extent, callback Callback) bool {
i := 0
for needle.Length != 0 {
l, ok := haystack()
if !ok {
2020-06-01 08:25:45 +00:00
return false
}
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 08:25:45 +00:00
return true
}
needle.Start = 0
needle.Length -= e1.Length
}
} else {
needle.Start -= l
}
i++
}
2020-06-01 08:25:45 +00:00
return true
}
func LocaterFromLengthIter(li LengthIter) Locater {
2020-06-01 08:25:45 +00:00
return func(e Extent, c Callback) bool {
return Scan(li, e, c)
}
}
2020-06-01 08:25:45 +00:00
type Locater func(Extent, Callback) bool