1
1
mirror of https://github.com/wader/fq.git synced 2024-12-23 21:31:33 +03:00
fq/format/apple/loop_detector.go

34 lines
960 B
Go
Raw Normal View History

package apple
import (
"golang.org/x/exp/constraints"
)
// PosLoopDetector is used for detecting loops when writing decoders, and can
// short-circuit infinite recursion that can cause stack overflows.
type PosLoopDetector[T constraints.Integer] []T
// Push adds the current offset to the stack and executes the supplied
// detection function
func (pld *PosLoopDetector[T]) Push(offset T, detect func()) {
for _, o := range *pld {
if offset == o {
detect()
}
}
*pld = append(*pld, offset)
}
// Pop removes the most recently added offset from the stack.
func (pld *PosLoopDetector[T]) Pop() {
*pld = (*pld)[:len(*pld)-1]
}
// PushAndPop adds the current offset to the stack, executes the supplied
// detection function, and returns the Pop method. A good usage of this is to
// pair this method call with a defer statement.
func (pld *PosLoopDetector[T]) PushAndPop(offset T, detect func()) func() {
pld.Push(offset, detect)
return pld.Pop
}