More efficient version of MatchOctet.

This commit is contained in:
Maurice Makaay 2019-07-20 01:50:12 +00:00
parent 0c057e4a9a
commit 7998d05113
1 changed files with 42 additions and 12 deletions

View File

@ -736,15 +736,16 @@ func MatchSeq(handlers ...Handler) Handler {
// that applies is used for reporting back a match.
func MatchAny(handlers ...Handler) Handler {
return func(t *API) bool {
child := t.Fork()
for _, handler := range handlers {
child := t.Fork()
if handler(t) {
t.Merge(child)
t.Dispose(child)
return true
}
t.Dispose(child)
t.Input.Reset()
}
t.Dispose(child)
return false
}
@ -1341,21 +1342,50 @@ func MatchHexDigit() Handler {
// When the normalize parameter is set to true, then leading zeroes will be
// stripped from the octet.
func MatchOctet(normalize bool) Handler {
max3Digits := MatchMinMax(1, 3, MatchDigit())
return func(t *API) bool {
if !max3Digits(t) {
// Digit 1
b0, err := t.Input.PeekByte(0)
if err != nil || b0 < '0' || b0 > '9' {
return false
}
value, _ := strconv.ParseInt(t.Output.String(), 10, 16)
if value > 255 {
return false
// Digit 2
b1, err := t.Input.PeekByte(1)
if err != nil || b1 < '0' || b1 > '9' {
// Output 1-digit octet.
t.Input.AcceptByte(b0)
return true
}
if normalize {
runes := t.Output.Runes()
for len(runes) > 1 && runes[0] == '0' {
runes = runes[1:]
// Digit 3
b2, err := t.Input.PeekByte(2)
if err != nil || b2 < '0' || b2 > '9' {
// Output 2-digit octet.
if normalize && b0 == '0' {
t.Input.SkipByte(b0)
t.Input.AcceptByte(b1)
} else {
t.Input.AcceptBytes(b0, b1)
}
t.Output.SetRunes(runes...)
return true
}
// The value of the octet must be between 0 - 255.
if b0 > '2' || (b0 == '2' && b1 > '5') || (b0 == '2' && b1 == '5' && b2 > '5') {
return false
}
// Output 3-digit octet.
if normalize && b0 == '0' {
t.Input.SkipByte(b0)
if b1 == '0' {
t.Input.SkipByte(b1)
} else {
t.Input.AcceptByte(b1)
}
t.Input.AcceptByte(b2)
} else {
t.Input.AcceptBytes(b0, b1, b2)
}
return true
}