| 215 | } |
| 216 | |
| 217 | func (n *node) insertChild(numParams uint8, path, fullPath string, handle Handle) { |
| 218 | var offset int // already handled bytes of the path |
| 219 | |
| 220 | // find prefix until first wildcard (beginning with ':'' or '*'') |
| 221 | for i, max := 0, len(path); numParams > 0; i++ { |
| 222 | c := path[i] |
| 223 | if c != ':' && c != '*' { |
| 224 | continue |
| 225 | } |
| 226 | |
| 227 | // find wildcard end (either '/' or path end) |
| 228 | end := i + 1 |
| 229 | for end < max && path[end] != '/' { |
| 230 | switch path[end] { |
| 231 | // the wildcard name must not contain ':' and '*' |
| 232 | case ':', '*': |
| 233 | panic("only one wildcard per path segment is allowed, has: '" + |
| 234 | path[i:] + "' in path '" + fullPath + "'") |
| 235 | default: |
| 236 | end++ |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | // check if this Node existing children which would be |
| 241 | // unreachable if we insert the wildcard here |
| 242 | if len(n.children) > 0 { |
| 243 | panic("wildcard route '" + path[i:end] + |
| 244 | "' conflicts with existing children in path '" + fullPath + "'") |
| 245 | } |
| 246 | |
| 247 | // check if the wildcard has a name |
| 248 | if end-i < 2 { |
| 249 | panic("wildcards must be named with a non-empty name in path '" + fullPath + "'") |
| 250 | } |
| 251 | |
| 252 | if c == ':' { // param |
| 253 | // split path at the beginning of the wildcard |
| 254 | if i > 0 { |
| 255 | n.path = path[offset:i] |
| 256 | offset = i |
| 257 | } |
| 258 | |
| 259 | child := &node{ |
| 260 | nType: param, |
| 261 | maxParams: numParams, |
| 262 | } |
| 263 | n.children = []*node{child} |
| 264 | n.wildChild = true |
| 265 | n = child |
| 266 | n.priority++ |
| 267 | numParams-- |
| 268 | |
| 269 | // if the path doesn't end with the wildcard, then there |
| 270 | // will be another non-wildcard subpath starting with '/' |
| 271 | if end < max { |
| 272 | n.path = path[offset:end] |
| 273 | offset = end |
| 274 | |