| 267 | } |
| 268 | |
| 269 | func (n *Node) insertChild(numParams uint8, path, fullPath string, handle RouterHandle, m ...Middleware) *Node { |
| 270 | var offset int // already handled bytes of the path |
| 271 | |
| 272 | // Find prefix until first wildcard (beginning with ':'' or '*'') |
| 273 | for i, max := 0, len(path); numParams > 0; i++ { |
| 274 | c := path[i] |
| 275 | if c != ':' && c != '*' { |
| 276 | continue |
| 277 | } |
| 278 | |
| 279 | // Find wildcard end (either '/' or path end) and check the name for |
| 280 | // invalid characters |
| 281 | end := i + 1 |
| 282 | invalid := false |
| 283 | for end < max { |
| 284 | c := path[end] |
| 285 | if c == '/' { |
| 286 | break |
| 287 | } |
| 288 | if c == ':' || c == '*' { |
| 289 | invalid = true |
| 290 | } |
| 291 | end++ |
| 292 | } |
| 293 | |
| 294 | // The wildcard name must not contain ':' and '*' |
| 295 | if invalid { |
| 296 | panic("only one wildcard per path segment is allowed, has: '" + |
| 297 | path[i:end] + "' in path '" + fullPath + "'") |
| 298 | } |
| 299 | |
| 300 | // Check if the wildcard has a name |
| 301 | if end-i < 2 { |
| 302 | panic("wildcards must be named with a non-empty name in path '" + fullPath + "'") |
| 303 | } |
| 304 | |
| 305 | // Check if this node has existing children which would be |
| 306 | // unreachable if we insert the wildcard here |
| 307 | if len(n.children) > 0 { |
| 308 | panic("wildcard route '" + path[i:end] + |
| 309 | "' conflicts with existing children in path '" + fullPath + "'") |
| 310 | } |
| 311 | |
| 312 | if c == ':' { // param |
| 313 | // Split path at the beginning of the wildcard |
| 314 | if i > 0 { |
| 315 | n.path = path[offset:i] |
| 316 | offset = i |
| 317 | } |
| 318 | |
| 319 | child := &Node{ |
| 320 | nType: param, |
| 321 | maxParams: numParams, |
| 322 | } |
| 323 | n.children = []*Node{child} |
| 324 | n.wildChild = true |
| 325 | n = child |
| 326 | n.priority++ |