MatchAndEscape examines components to determine if they match to a Pattern. MatchAndEscape will return an error if no Patterns matched or if a pattern matched but contained malformed escape sequences. If successful, the function returns a mapping from field paths to their captured values.
(components []string, verb string, unescapingMode UnescapingMode)
| 152 | // matched but contained malformed escape sequences. If successful, the function |
| 153 | // returns a mapping from field paths to their captured values. |
| 154 | func (p Pattern) MatchAndEscape(components []string, verb string, unescapingMode UnescapingMode) (map[string]string, error) { |
| 155 | if p.verb != verb { |
| 156 | if p.verb != "" { |
| 157 | return nil, ErrNotMatch |
| 158 | } |
| 159 | if len(components) == 0 { |
| 160 | components = []string{":" + verb} |
| 161 | } else { |
| 162 | components = append([]string{}, components...) |
| 163 | components[len(components)-1] += ":" + verb |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | var pos int |
| 168 | stack := make([]string, 0, p.stacksize) |
| 169 | captured := make([]string, len(p.vars)) |
| 170 | l := len(components) |
| 171 | for _, op := range p.ops { |
| 172 | var err error |
| 173 | |
| 174 | switch op.code { |
| 175 | case utilities.OpNop: |
| 176 | continue |
| 177 | case utilities.OpPush, utilities.OpLitPush: |
| 178 | if pos >= l { |
| 179 | return nil, ErrNotMatch |
| 180 | } |
| 181 | c := components[pos] |
| 182 | if op.code == utilities.OpLitPush { |
| 183 | if lit := p.pool[op.operand]; c != lit { |
| 184 | return nil, ErrNotMatch |
| 185 | } |
| 186 | } else if op.code == utilities.OpPush { |
| 187 | if c, err = unescape(c, unescapingMode, false); err != nil { |
| 188 | return nil, err |
| 189 | } |
| 190 | } |
| 191 | stack = append(stack, c) |
| 192 | pos++ |
| 193 | case utilities.OpPushM: |
| 194 | end := len(components) |
| 195 | if end < pos+p.tailLen { |
| 196 | return nil, ErrNotMatch |
| 197 | } |
| 198 | end -= p.tailLen |
| 199 | c := strings.Join(components[pos:end], "/") |
| 200 | if c, err = unescape(c, unescapingMode, true); err != nil { |
| 201 | return nil, err |
| 202 | } |
| 203 | stack = append(stack, c) |
| 204 | pos = end |
| 205 | case utilities.OpConcatN: |
| 206 | n := op.operand |
| 207 | l := len(stack) - n |
| 208 | stack = append(stack[:l], strings.Join(stack[l:], "/")) |
| 209 | case utilities.OpCapture: |
| 210 | n := len(stack) - 1 |
| 211 | captured[op.operand] = stack[n] |