hasToken reports whether token appears with v, ASCII case-insensitive, with space or comma boundaries. token must be all lowercase. v may contain mixed cased.
(v, token string)
| 83 | // token must be all lowercase. |
| 84 | // v may contain mixed cased. |
| 85 | func hasToken(v, token string) bool { |
| 86 | if len(token) > len(v) || token == "" { |
| 87 | return false |
| 88 | } |
| 89 | if v == token { |
| 90 | return true |
| 91 | } |
| 92 | for sp := 0; sp <= len(v)-len(token); sp++ { |
| 93 | // Check that first character is good. |
| 94 | // The token is ASCII, so checking only a single byte |
| 95 | // is sufficient. We skip this potential starting |
| 96 | // position if both the first byte and its potential |
| 97 | // ASCII uppercase equivalent (b|0x20) don't match. |
| 98 | // False positives ('^' => '~') are caught by EqualFold. |
| 99 | if b := v[sp]; b != token[0] && b|0x20 != token[0] { |
| 100 | continue |
| 101 | } |
| 102 | // Check that start pos is on a valid token boundary. |
| 103 | if sp > 0 && !isTokenBoundary(v[sp-1]) { |
| 104 | continue |
| 105 | } |
| 106 | // Check that end pos is on a valid token boundary. |
| 107 | if endPos := sp + len(token); endPos != len(v) && !isTokenBoundary(v[endPos]) { |
| 108 | continue |
| 109 | } |
| 110 | if ascii.EqualFold(v[sp:sp+len(token)], token) { |
| 111 | return true |
| 112 | } |
| 113 | } |
| 114 | return false |
| 115 | } |
| 116 | |
| 117 | func isTokenBoundary(b byte) bool { |
| 118 | return b == ' ' || b == ',' || b == '\t' |
no test coverage detected
searching dependent graphs…