aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/zenazn/goji/web/bytecode_runner.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zenazn/goji/web/bytecode_runner.go')
-rw-r--r--vendor/github.com/zenazn/goji/web/bytecode_runner.go83
1 files changed, 83 insertions, 0 deletions
diff --git a/vendor/github.com/zenazn/goji/web/bytecode_runner.go b/vendor/github.com/zenazn/goji/web/bytecode_runner.go
new file mode 100644
index 0000000..c32b16a
--- /dev/null
+++ b/vendor/github.com/zenazn/goji/web/bytecode_runner.go
@@ -0,0 +1,83 @@
+package web
+
+import "net/http"
+
+type routeMachine struct {
+ sm stateMachine
+ routes []route
+}
+
+func matchRoute(route route, m method, ms *method, r *http.Request, c *C) bool {
+ if !route.pattern.Match(r, c) {
+ return false
+ }
+ *ms |= route.method
+
+ if route.method&m != 0 {
+ route.pattern.Run(r, c)
+ return true
+ }
+ return false
+}
+
+func (rm routeMachine) route(c *C, w http.ResponseWriter, r *http.Request) (method, *route) {
+ m := httpMethod(r.Method)
+ var methods method
+ p := r.URL.Path
+
+ if len(rm.sm) == 0 {
+ return methods, nil
+ }
+
+ var i int
+ for {
+ sm := rm.sm[i].mode
+ if sm&smSetCursor != 0 {
+ si := rm.sm[i].i
+ p = r.URL.Path[si:]
+ i++
+ continue
+ }
+
+ length := int(sm & smLengthMask)
+ match := false
+ if length <= len(p) {
+ bs := rm.sm[i].bs
+ switch length {
+ case 3:
+ if p[2] != bs[2] {
+ break
+ }
+ fallthrough
+ case 2:
+ if p[1] != bs[1] {
+ break
+ }
+ fallthrough
+ case 1:
+ if p[0] != bs[0] {
+ break
+ }
+ fallthrough
+ case 0:
+ p = p[length:]
+ match = true
+ }
+ }
+
+ if match && sm&smRoute != 0 {
+ si := rm.sm[i].i
+ if matchRoute(rm.routes[si], m, &methods, r, c) {
+ return 0, &rm.routes[si]
+ }
+ i++
+ } else if match != (sm&smJumpOnMatch == 0) {
+ if sm&smFail != 0 {
+ return methods, nil
+ }
+ i = int(rm.sm[i].i)
+ } else {
+ i++
+ }
+ }
+}