libnhttp/nhttp/server/xfwk/xfwk_route.cpp
/* route the path to target. */
route the path to target.
route the path to target .
bool xfwk_route::route(xfwk_route_state& state, xfwk_path& path) const {
		if (!path.get_size()) {
			state.route = std::const_pointer_cast<xfwk_route>(shared_from_this());
			state.path_remainder = path.get_subpath(0).get_path();
			return true;
		}
		if (!children.size() && !wildcard)
			return false;
		xfwk_path bkp_path = path;
		xfwk_route_state bkp_state = state;
		std::string name = path.get_name_at(0);
		auto child = get_child(name);
		++state.depth;
		if (child && child->is_static()) {
			path.pop_front();
			if (child->route(state, path)) {
				return true;
			}
			path = bkp_path;
			state = bkp_state;
		}
		if (params.size()) {
			xfwk_path deep_path = path;
			xfwk_route_state deep_state = state;
			bool choosen = false;
			--deep_state.depth;
			for (auto each : params) {
				if (each->test(name)) {
					if (!each->route(state, path)) {
						path = bkp_path;
						state = bkp_state;
						continue;
					}
					if (deep_state.depth < state.depth) {
						deep_path = path;
						deep_state = state;
					}
					choosen = true;
				}
			}
			if (choosen) {
				path = std::move(deep_path);
				state = std::move(deep_state);
				return true;
			}
		}
		if (!wildcard || !wildcard->route(state, path)) {
			path = std::move(bkp_path);
			state = std::move(bkp_state);
			return false;
		}
		return true;
	}
bool xfwk_route :: route ( xfwk_route_state & state , xfwk_path & path ) const { if ( ! path . get_size ( ) ) { state . route = std :: const_pointer_cast < xfwk_route > ( shared_from_this ( ) ) ; state . path_remainder = path . get_subpath ( 0 ) . get_path ( ) ; return true ; } if ( ! children . size ( ) && ! wildcard ) return false ; xfwk_path bkp_path = path ; xfwk_route_state bkp_state = state ; std :: string name = path . get_name_at ( 0 ) ; auto child = get_child ( name ) ; ++ state . depth ; if ( child && child -> is_static ( ) ) { path . pop_front ( ) ; if ( child -> route ( state , path ) ) { return true ; } path = bkp_path ; state = bkp_state ; } if ( params . size ( ) ) { xfwk_path deep_path = path ; xfwk_route_state deep_state = state ; bool choosen = false ; -- deep_state . depth ; for ( auto each : params ) { if ( each -> test ( name ) ) { if ( ! each -> route ( state , path ) ) { path = bkp_path ; state = bkp_state ; continue ; } if ( deep_state . depth < state . depth ) { deep_path = path ; deep_state = state ; } choosen = true ; } } if ( choosen ) { path = std :: move ( deep_path ) ; state = std :: move ( deep_state ) ; return true ; } } if ( ! wildcard || ! wildcard -> route ( state , path ) ) { path = std :: move ( bkp_path ) ; state = std :: move ( bkp_state ) ; return false ; } return true ; }
route the path to target.
route the path to target .
/* if no children: */ /* clone for restoring state. */ /* increase depth. */ /* pop front path. */ /* restore previous state. */ /* clone for choosing deep state. */ /* restore previous state. */ /* if found more deep, replace it. */ /* if no wildcard can accept route, restore to original. */