From 7998d05113755cb851e5267055ee13857a4c6dad Mon Sep 17 00:00:00 2001 From: Maurice Makaay Date: Sat, 20 Jul 2019 01:50:12 +0000 Subject: [PATCH] More efficient version of MatchOctet. --- tokenize/handlers_builtin.go | 54 ++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/tokenize/handlers_builtin.go b/tokenize/handlers_builtin.go index 36cf01d..a8c3ebf 100644 --- a/tokenize/handlers_builtin.go +++ b/tokenize/handlers_builtin.go @@ -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 }