aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoripknHama <ipknhama@gmail.com>2014-04-15 22:46:28 +0900
committeripknHama <ipknhama@gmail.com>2014-04-15 22:46:28 +0900
commit7933427691ec30afd63cde8927b9500237d5b2cb (patch)
treef449e9d2b7625ed8c0dc918307a352e09f43caa9
parent5692ec1cbf0957c526d6c7911c88e35145518839 (diff)
downloadcrow-7933427691ec30afd63cde8927b9500237d5b2cb.tar.gz
crow-7933427691ec30afd63cde8927b9500237d5b2cb.zip
add more parameter types
-rw-r--r--.gitignore2
-rw-r--r--routing.h113
2 files changed, 108 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index 82c6ff6..e86bfe6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,5 @@ covtest
unittest.gcda
unittest.gcno
+http_parser.gcda
+http_parser.gcno
diff --git a/routing.h b/routing.h
index 4515af3..fd8c475 100644
--- a/routing.h
+++ b/routing.h
@@ -35,14 +35,9 @@ namespace flask
return *this;
}
- virtual void validate()
- {
- }
+ virtual void validate() = 0;
- virtual response handle(const request&, const routing_params&)
- {
- return response(400);
- }
+ virtual response handle(const request&, const routing_params&) = 0;
protected:
std::string rule_;
@@ -122,6 +117,39 @@ namespace flask
}
};
+ template <typename F, int NInt, int NUint, int NDouble, int NString, typename ... Args1, typename ... Args2>
+ struct call<F, NInt, NUint, NDouble, NString, black_magic::S<uint64_t, Args1...>, black_magic::S<Args2...>>
+ {
+ response operator()(F& handler, const routing_params& params)
+ {
+ using pushed = typename black_magic::S<Args2...>::template push_back<call_pair<uint64_t, NInt>>;
+ return call<F, NInt, NUint+1, NDouble, NString,
+ black_magic::S<Args1...>, pushed>()(handler, params);
+ }
+ };
+
+ template <typename F, int NInt, int NUint, int NDouble, int NString, typename ... Args1, typename ... Args2>
+ struct call<F, NInt, NUint, NDouble, NString, black_magic::S<double, Args1...>, black_magic::S<Args2...>>
+ {
+ response operator()(F& handler, const routing_params& params)
+ {
+ using pushed = typename black_magic::S<Args2...>::template push_back<call_pair<double, NInt>>;
+ return call<F, NInt, NUint, NDouble+1, NString,
+ black_magic::S<Args1...>, pushed>()(handler, params);
+ }
+ };
+
+ template <typename F, int NInt, int NUint, int NDouble, int NString, typename ... Args1, typename ... Args2>
+ struct call<F, NInt, NUint, NDouble, NString, black_magic::S<std::string, Args1...>, black_magic::S<Args2...>>
+ {
+ response operator()(F& handler, const routing_params& params)
+ {
+ using pushed = typename black_magic::S<Args2...>::template push_back<call_pair<std::string, NInt>>;
+ return call<F, NInt, NUint, NDouble, NString+1,
+ black_magic::S<Args1...>, pushed>()(handler, params);
+ }
+ };
+
template <typename F, int NInt, int NUint, int NDouble, int NString, typename ... Args1>
struct call<F, NInt, NUint, NDouble, NString, black_magic::S<>, black_magic::S<Args1...>>
{
@@ -145,6 +173,10 @@ namespace flask
return *this;
}
+ void validate()
+ {
+ }
+
template <typename Func>
void operator()(Func&& f)
{
@@ -272,6 +304,73 @@ public:
}
}
+ if (node->param_childrens[(int)ParamType::UINT])
+ {
+ char c = req.url[pos];
+ if ((c >= '0' && c <= '9') || c == '+')
+ {
+ char* eptr;
+ errno = 0;
+ unsigned long long int value = strtoull(req.url.data()+pos, &eptr, 10);
+ if (errno != ERANGE && eptr != req.url.data()+pos)
+ {
+ params->uint_params.push_back(value);
+ auto ret = find(req, &nodes_[node->param_childrens[(int)ParamType::UINT]], eptr - req.url.data(), params);
+ update_found(ret);
+ params->uint_params.pop_back();
+ }
+ }
+ }
+
+ if (node->param_childrens[(int)ParamType::DOUBLE])
+ {
+ char c = req.url[pos];
+ if ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.')
+ {
+ char* eptr;
+ errno = 0;
+ double value = strtod(req.url.data()+pos, &eptr);
+ if (errno != ERANGE && eptr != req.url.data()+pos)
+ {
+ params->double_params.push_back(value);
+ auto ret = find(req, &nodes_[node->param_childrens[(int)ParamType::DOUBLE]], eptr - req.url.data(), params);
+ update_found(ret);
+ params->double_params.pop_back();
+ }
+ }
+ }
+
+ if (node->param_childrens[(int)ParamType::STRING])
+ {
+ size_t epos = pos;
+ for(; epos < req.url.size(); epos ++)
+ {
+ if (req.url[epos] == '/')
+ break;
+ }
+
+ if (epos != pos)
+ {
+ params->string_params.push_back(req.url.substr(pos, epos-pos));
+ auto ret = find(req, &nodes_[node->param_childrens[(int)ParamType::STRING]], epos, params);
+ update_found(ret);
+ params->string_params.pop_back();
+ }
+ }
+
+ if (node->param_childrens[(int)ParamType::PATH])
+ {
+ size_t epos = req.url.size();
+
+ if (epos != pos)
+ {
+ params->string_params.push_back(req.url.substr(pos, epos-pos));
+ auto ret = find(req, &nodes_[node->param_childrens[(int)ParamType::PATH]], epos, params);
+ update_found(ret);
+ params->string_params.pop_back();
+ }
+ }
+
for(auto& kv : node->children)
{
const std::string& fragment = kv.first;