aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoripknHama <ipknhama@gmail.com>2014-12-12 01:48:56 +0900
committeripknHama <ipknhama@gmail.com>2014-12-12 01:48:56 +0900
commitad654da7115353baef19a4c87f53d4b88c02d4e5 (patch)
tree27b86384181a400863580dab1b719ca3b01d2a91
parent21b027774e4c472d27d8726774aad1aaed95ea42 (diff)
parent966867a9ca8ca3dd9e783d628b8184563318d03c (diff)
downloadcrow-ad654da7115353baef19a4c87f53d4b88c02d4e5.tar.gz
crow-ad654da7115353baef19a4c87f53d4b88c02d4e5.zip
Merge branch 'acron0-get-middleware2'
-rw-r--r--amalgamate/crow_all.h344
-rw-r--r--examples/example.cpp33
-rw-r--r--include/crow.h10
-rw-r--r--include/http_connection.h10
-rw-r--r--include/http_server.h8
-rw-r--r--include/json.h166
-rw-r--r--include/mustache.h12
-rw-r--r--include/routing.h8
-rw-r--r--include/settings.h10
-rw-r--r--include/utility.h120
10 files changed, 418 insertions, 303 deletions
diff --git a/amalgamate/crow_all.h b/amalgamate/crow_all.h
index a2f9cc0..911d15d 100644
--- a/amalgamate/crow_all.h
+++ b/amalgamate/crow_all.h
@@ -367,10 +367,10 @@ namespace crow
namespace crow
{
- namespace mustache
- {
- class template_t;
- }
+ namespace mustache
+ {
+ class template_t;
+ }
namespace json
{
@@ -535,8 +535,8 @@ namespace crow
static const int cached_bit = 2;
static const int error_bit = 4;
public:
- rvalue() noexcept : option_{error_bit}
- {}
+ rvalue() noexcept : option_{error_bit}
+ {}
rvalue(type t) noexcept
: lsize_{}, lremain_{}, t_{t}
{}
@@ -743,32 +743,32 @@ namespace crow
return it != end() && it->key_ == str;
}
- int count(const std::string& str)
- {
- return has(str) ? 1 : 0;
- }
+ int count(const std::string& str)
+ {
+ return has(str) ? 1 : 0;
+ }
rvalue* begin() const
- {
+ {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::Object && t() != type::List)
throw std::runtime_error("value is not a container");
#endif
- return l_.get();
- }
+ return l_.get();
+ }
rvalue* end() const
- {
+ {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::Object && t() != type::List)
throw std::runtime_error("value is not a container");
#endif
- return l_.get()+lsize_;
- }
+ return l_.get()+lsize_;
+ }
- const detail::r_string& key() const
- {
- return key_;
- }
+ const detail::r_string& key() const
+ {
+ return key_;
+ }
size_t size() const
{
@@ -781,27 +781,27 @@ namespace crow
return lsize_;
}
- const rvalue& operator[](int index) const
- {
+ const rvalue& operator[](int index) const
+ {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::List)
throw std::runtime_error("value is not a list");
- if (index >= (int)lsize_ || index < 0)
+ if (index >= (int)lsize_ || index < 0)
throw std::runtime_error("list out of bound");
#endif
- return l_[index];
- }
+ return l_[index];
+ }
- const rvalue& operator[](size_t index) const
- {
+ const rvalue& operator[](size_t index) const
+ {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::List)
throw std::runtime_error("value is not a list");
- if (index >= lsize_)
+ if (index >= lsize_)
throw std::runtime_error("list out of bound");
#endif
- return l_[index];
- }
+ return l_[index];
+ }
const rvalue& operator[](const char* str) const
{
@@ -994,14 +994,14 @@ namespace crow
inline rvalue load_nocopy_internal(char* data, size_t size)
{
//static const char* escaped = "\"\\/\b\f\n\r\t";
- struct Parser
- {
- Parser(char* data, size_t size)
- : data(data)
- {
- }
-
- bool consume(char c)
+ struct Parser
+ {
+ Parser(char* data, size_t size)
+ : data(data)
+ {
+ }
+
+ bool consume(char c)
{
if (crow_json_unlikely(*data != c))
return false;
@@ -1009,12 +1009,12 @@ namespace crow
return true;
}
- void ws_skip()
+ void ws_skip()
{
- while(*data == ' ' || *data == '\t' || *data == '\r' || *data == '\n') ++data;
+ while(*data == ' ' || *data == '\t' || *data == '\r' || *data == '\n') ++data;
};
- rvalue decode_string()
+ rvalue decode_string()
{
if (crow_json_unlikely(!consume('"')))
return {};
@@ -1076,30 +1076,30 @@ namespace crow
return {};
}
- rvalue decode_list()
+ rvalue decode_list()
{
- rvalue ret(type::List);
- if (crow_json_unlikely(!consume('[')))
+ rvalue ret(type::List);
+ if (crow_json_unlikely(!consume('[')))
{
ret.set_error();
- return ret;
+ return ret;
}
- ws_skip();
- if (crow_json_unlikely(*data == ']'))
- {
- data++;
- return ret;
- }
-
- while(1)
- {
+ ws_skip();
+ if (crow_json_unlikely(*data == ']'))
+ {
+ data++;
+ return ret;
+ }
+
+ while(1)
+ {
auto v = decode_value();
- if (crow_json_unlikely(!v))
+ if (crow_json_unlikely(!v))
{
ret.set_error();
break;
}
- ws_skip();
+ ws_skip();
ret.emplace_back(std::move(v));
if (*data == ']')
{
@@ -1111,12 +1111,12 @@ namespace crow
ret.set_error();
break;
}
- ws_skip();
- }
+ ws_skip();
+ }
return ret;
}
- rvalue decode_number()
+ rvalue decode_number()
{
char* start = data;
@@ -1153,7 +1153,7 @@ namespace crow
}
else
return {};*/
- break;
+ break;
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
@@ -1234,14 +1234,14 @@ namespace crow
return {};
}
- rvalue decode_value()
+ rvalue decode_value()
{
switch(*data)
{
case '[':
- return decode_list();
+ return decode_list();
case '{':
- return decode_object();
+ return decode_object();
case '"':
return decode_string();
case 't':
@@ -1288,7 +1288,7 @@ namespace crow
return {};
}
- rvalue decode_object()
+ rvalue decode_object()
{
rvalue ret(type::Object);
if (crow_json_unlikely(!consume('{')))
@@ -1297,7 +1297,7 @@ namespace crow
return ret;
}
- ws_skip();
+ ws_skip();
if (crow_json_unlikely(*data == '}'))
{
@@ -1314,24 +1314,24 @@ namespace crow
break;
}
- ws_skip();
+ ws_skip();
if (crow_json_unlikely(!consume(':')))
{
ret.set_error();
break;
}
- // TODO caching key to speed up (flyweight?)
+ // TODO caching key to speed up (flyweight?)
auto key = t.s();
- ws_skip();
+ ws_skip();
auto v = decode_value();
if (crow_json_unlikely(!v))
{
ret.set_error();
break;
}
- ws_skip();
+ ws_skip();
v.key_ = std::move(key);
ret.emplace_back(std::move(v));
@@ -1345,24 +1345,24 @@ namespace crow
ret.set_error();
break;
}
- ws_skip();
+ ws_skip();
}
return ret;
}
- rvalue parse()
- {
+ rvalue parse()
+ {
+ ws_skip();
+ auto ret = decode_value(); // or decode object?
ws_skip();
- auto ret = decode_value(); // or decode object?
- ws_skip();
if (ret && *data != '\0')
ret.set_error();
- return ret;
- }
+ return ret;
+ }
- char* data;
- };
- return Parser(data, size).parse();
+ char* data;
+ };
+ return Parser(data, size).parse();
}
inline rvalue load(const char* data, size_t size)
{
@@ -1389,7 +1389,7 @@ namespace crow
class wvalue
{
- friend class crow::mustache::template_t;
+ friend class crow::mustache::template_t;
public:
type t() const { return t_; }
private:
@@ -1597,14 +1597,14 @@ namespace crow
return (*l)[index];
}
- int count(const std::string& str)
- {
+ int count(const std::string& str)
+ {
if (t_ != type::Object)
return 0;
if (!o)
return 0;
return o->count(str);
- }
+ }
wvalue& operator[](const std::string& str)
{
@@ -2035,9 +2035,9 @@ namespace crow
public:
std::string render()
{
- context empty_ctx;
- std::vector<context*> stack;
- stack.emplace_back(&empty_ctx);
+ context empty_ctx;
+ std::vector<context*> stack;
+ stack.emplace_back(&empty_ctx);
std::string ret;
render_internal(0, fragments_.size()-1, stack, ret, 0);
@@ -2045,8 +2045,8 @@ namespace crow
}
std::string render(context& ctx)
{
- std::vector<context*> stack;
- stack.emplace_back(&ctx);
+ std::vector<context*> stack;
+ stack.emplace_back(&ctx);
std::string ret;
render_internal(0, fragments_.size()-1, stack, ret, 0);
@@ -2108,7 +2108,7 @@ namespace crow
body_.substr(matched.start, matched.end - matched.start) + ", " +
body_.substr(idx, endIdx-idx));
}
- matched.pos = actions_.size();
+ matched.pos = actions_.size();
}
actions_.emplace_back(ActionType::CloseBlock, idx, endIdx, blockPositions.back());
blockPositions.pop_back();
@@ -5083,11 +5083,11 @@ namespace crow
/* #define - specifies log level */
/*
- DEBUG = 0
- INFO = 1
- WARNING = 2
- ERROR = 3
- CRITICAL = 4
+ DEBUG = 0
+ INFO = 1
+ WARNING = 2
+ ERROR = 3
+ CRITICAL = 4
default to INFO
*/
@@ -5324,48 +5324,48 @@ namespace crow
namespace crow
{
- namespace black_magic
- {
- struct OutOfRange
- {
- OutOfRange(unsigned pos, unsigned length) {}
- };
- constexpr unsigned requires_in_range( unsigned i, unsigned len )
- {
- return i >= len ? throw OutOfRange(i, len) : i;
- }
-
- class const_str
- {
- const char * const begin_;
- unsigned size_;
-
- public:
- template< unsigned N >
- constexpr const_str( const char(&arr)[N] ) : begin_(arr), size_(N - 1) {
- static_assert( N >= 1, "not a string literal");
- }
- constexpr char operator[]( unsigned i ) const {
- return requires_in_range(i, size_), begin_[i];
- }
-
- constexpr operator const char *() const {
- return begin_;
- }
-
- constexpr const char* begin() const { return begin_; }
- constexpr const char* end() const { return begin_ + size_; }
-
- constexpr unsigned size() const {
- return size_;
- }
- };
-
-
- constexpr unsigned find_closing_tag(const_str s, unsigned p)
- {
- return s[p] == '>' ? p : find_closing_tag(s, p+1);
- }
+ namespace black_magic
+ {
+ struct OutOfRange
+ {
+ OutOfRange(unsigned pos, unsigned length) {}
+ };
+ constexpr unsigned requires_in_range( unsigned i, unsigned len )
+ {
+ return i >= len ? throw OutOfRange(i, len) : i;
+ }
+
+ class const_str
+ {
+ const char * const begin_;
+ unsigned size_;
+
+ public:
+ template< unsigned N >
+ constexpr const_str( const char(&arr)[N] ) : begin_(arr), size_(N - 1) {
+ static_assert( N >= 1, "not a string literal");
+ }
+ constexpr char operator[]( unsigned i ) const {
+ return requires_in_range(i, size_), begin_[i];
+ }
+
+ constexpr operator const char *() const {
+ return begin_;
+ }
+
+ constexpr const char* begin() const { return begin_; }
+ constexpr const char* end() const { return begin_ + size_; }
+
+ constexpr unsigned size() const {
+ return size_;
+ }
+ };
+
+
+ constexpr unsigned find_closing_tag(const_str s, unsigned p)
+ {
+ return s[p] == '>' ? p : find_closing_tag(s, p+1);
+ }
constexpr bool is_valid(const_str s, unsigned i = 0, int f = 0)
{
@@ -5610,7 +5610,41 @@ template <typename F, typename Set>
struct empty_context
{
};
- }
+
+ } // namespace black_magic
+
+ namespace detail
+ {
+
+ template <class T, std::size_t N, class... Args>
+ struct get_index_of_element_from_tuple_by_type_impl
+ {
+ static constexpr auto value = N;
+ };
+
+ template <class T, std::size_t N, class... Args>
+ struct get_index_of_element_from_tuple_by_type_impl<T, N, T, Args...>
+ {
+ static constexpr auto value = N;
+ };
+
+ template <class T, std::size_t N, class U, class... Args>
+ struct get_index_of_element_from_tuple_by_type_impl<T, N, U, Args...>
+ {
+ static constexpr auto value = get_index_of_element_from_tuple_by_type_impl<T, N + 1, Args...>::value;
+ };
+
+ } // namespace detail
+
+ namespace utility
+ {
+ template <class T, class... Args>
+ T& get_element_by_type(std::tuple<Args...>& t)
+ {
+ return std::get<detail::get_index_of_element_from_tuple_by_type_impl<T, 0, Args...>::value>(t);
+ }
+
+ } // namespace utility
}
@@ -6913,9 +6947,9 @@ public:
if (!rule_index)
{
- CROW_LOG_DEBUG << "Cannot match rules " << req.url;
+ CROW_LOG_DEBUG << "Cannot match rules " << req.url;
res = response(404);
- res.end();
+ res.end();
return;
}
@@ -6924,9 +6958,9 @@ public:
if ((rules_[rule_index]->methods() & (1<<(uint32_t)req.method)) == 0)
{
- CROW_LOG_DEBUG << "Rule found but method mismatch: " << req.url << " with " << method_name(req.method) << "(" << (uint32_t)req.method << ") / " << rules_[rule_index]->methods();
+ CROW_LOG_DEBUG << "Rule found but method mismatch: " << req.url << " with " << method_name(req.method) << "(" << (uint32_t)req.method << ") / " << rules_[rule_index]->methods();
res = response(404);
- res.end();
+ res.end();
return;
}
@@ -7136,7 +7170,7 @@ namespace crow
boost::asio::io_service& io_service,
Handler* handler,
const std::string& server_name,
- std::tuple<Middlewares...>& middlewares
+ std::tuple<Middlewares...>* middlewares
)
: socket_(io_service),
handler_(handler),
@@ -7233,7 +7267,7 @@ namespace crow
ctx_ = detail::context<Middlewares...>();
req.middleware_context = (void*)&ctx_;
- detail::middleware_call_helper<0, decltype(ctx_), decltype(middlewares_), Middlewares...>(middlewares_, req, res, ctx_);
+ detail::middleware_call_helper<0, decltype(ctx_), decltype(*middlewares_), Middlewares...>(*middlewares_, req, res, ctx_);
if (!res.completed_)
{
@@ -7266,8 +7300,8 @@ namespace crow
detail::after_handlers_call_helper<
((int)sizeof...(Middlewares)-1),
decltype(ctx_),
- decltype(middlewares_)>
- (middlewares_, ctx_, req_, res);
+ decltype(*middlewares_)>
+ (*middlewares_, ctx_, req_, res);
}
//auto self = this->shared_from_this();
@@ -7514,7 +7548,7 @@ namespace crow
bool need_to_start_read_after_complete_{};
bool add_keep_alive_{};
- std::tuple<Middlewares...>& middlewares_;
+ std::tuple<Middlewares...>* middlewares_;
detail::context<Middlewares...> ctx_;
};
@@ -7551,12 +7585,13 @@ namespace crow
class Server
{
public:
- Server(Handler* handler, uint16_t port, uint16_t concurrency = 1)
+ Server(Handler* handler, uint16_t port, std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1)
: acceptor_(io_service_, tcp::endpoint(asio::ip::address(), port)),
signals_(io_service_, SIGINT, SIGTERM),
handler_(handler),
concurrency_(concurrency),
- port_(port)
+ port_(port),
+ middlewares_(middlewares)
{
}
@@ -7649,8 +7684,7 @@ namespace crow
uint16_t port_;
unsigned int roundrobin_index_{};
- std::tuple<Middlewares...> middlewares_;
-
+ std::tuple<Middlewares...>* middlewares_;
};
}
@@ -7734,7 +7768,7 @@ namespace crow
void run()
{
validate();
- server_t server(this, port_, concurrency_);
+ server_t server(this, port_, &middlewares_, concurrency_);
server.run();
}
@@ -7754,11 +7788,19 @@ namespace crow
return ctx.template get<T>();
}
+ template <typename T>
+ T& get_middleware()
+ {
+ return utility::get_element_by_type<T, Middlewares...>(middlewares_);
+ }
+
private:
uint16_t port_ = 80;
uint16_t concurrency_ = 1;
Router router_;
+
+ std::tuple<Middlewares...> middlewares_;
};
template <typename ... Middlewares>
using App = Crow<Middlewares...>;
diff --git a/examples/example.cpp b/examples/example.cpp
index d7a4736..51ce6ed 100644
--- a/examples/example.cpp
+++ b/examples/example.cpp
@@ -10,9 +10,40 @@ class ExampleLogHandler : public crow::ILogHandler {
}
};
+struct ExampleMiddelware
+{
+ std::string message;
+
+ ExampleMiddelware()
+ {
+ message = "foo";
+ }
+
+ void setMessage(std::string newMsg)
+ {
+ message = newMsg;
+ }
+
+ struct context
+ {
+ };
+
+ void before_handle(crow::request& req, crow::response& res, context& ctx)
+ {
+ CROW_LOG_DEBUG << " - MESSAGE: " << message;
+ }
+
+ void after_handle(crow::request& req, crow::response& res, context& ctx)
+ {
+ // no-op
+ }
+};
+
int main()
{
- crow::SimpleApp app;
+ crow::App<ExampleMiddelware> app;
+
+ app.get_middleware<ExampleMiddelware>().setMessage("hello");
CROW_ROUTE(app, "/")
.name("hello")
diff --git a/include/crow.h b/include/crow.h
index fdc5206..3fd55de 100644
--- a/include/crow.h
+++ b/include/crow.h
@@ -69,7 +69,7 @@ namespace crow
void run()
{
validate();
- server_t server(this, port_, concurrency_);
+ server_t server(this, port_, &middlewares_, concurrency_);
server.run();
}
@@ -89,11 +89,19 @@ namespace crow
return ctx.template get<T>();
}
+ template <typename T>
+ T& get_middleware()
+ {
+ return utility::get_element_by_type<T, Middlewares...>(middlewares_);
+ }
+
private:
uint16_t port_ = 80;
uint16_t concurrency_ = 1;
Router router_;
+
+ std::tuple<Middlewares...> middlewares_;
};
template <typename ... Middlewares>
using App = Crow<Middlewares...>;
diff --git a/include/http_connection.h b/include/http_connection.h
index d88bc25..db069c3 100644
--- a/include/http_connection.h
+++ b/include/http_connection.h
@@ -113,7 +113,7 @@ namespace crow
boost::asio::io_service& io_service,
Handler* handler,
const std::string& server_name,
- std::tuple<Middlewares...>& middlewares
+ std::tuple<Middlewares...>* middlewares
)
: socket_(io_service),
handler_(handler),
@@ -210,7 +210,7 @@ namespace crow
ctx_ = detail::context<Middlewares...>();
req.middleware_context = (void*)&ctx_;
- detail::middleware_call_helper<0, decltype(ctx_), decltype(middlewares_), Middlewares...>(middlewares_, req, res, ctx_);
+ detail::middleware_call_helper<0, decltype(ctx_), decltype(*middlewares_), Middlewares...>(*middlewares_, req, res, ctx_);
if (!res.completed_)
{
@@ -243,8 +243,8 @@ namespace crow
detail::after_handlers_call_helper<
((int)sizeof...(Middlewares)-1),
decltype(ctx_),
- decltype(middlewares_)>
- (middlewares_, ctx_, req_, res);
+ decltype(*middlewares_)>
+ (*middlewares_, ctx_, req_, res);
}
//auto self = this->shared_from_this();
@@ -491,7 +491,7 @@ namespace crow
bool need_to_start_read_after_complete_{};
bool add_keep_alive_{};
- std::tuple<Middlewares...>& middlewares_;
+ std::tuple<Middlewares...>* middlewares_;
detail::context<Middlewares...> ctx_;
};
diff --git a/include/http_server.h b/include/http_server.h
index 2241dec..bd35ba1 100644
--- a/include/http_server.h
+++ b/include/http_server.h
@@ -23,12 +23,13 @@ namespace crow
class Server
{
public:
- Server(Handler* handler, uint16_t port, uint16_t concurrency = 1)
+ Server(Handler* handler, uint16_t port, std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1)
: acceptor_(io_service_, tcp::endpoint(asio::ip::address(), port)),
signals_(io_service_, SIGINT, SIGTERM),
handler_(handler),
concurrency_(concurrency),
- port_(port)
+ port_(port),
+ middlewares_(middlewares)
{
}
@@ -121,7 +122,6 @@ namespace crow
uint16_t port_;
unsigned int roundrobin_index_{};
- std::tuple<Middlewares...> middlewares_;
-
+ std::tuple<Middlewares...>* middlewares_;
};
}
diff --git a/include/json.h b/include/json.h
index 68f06a2..0d5d41e 100644
--- a/include/json.h
+++ b/include/json.h
@@ -23,10 +23,10 @@
namespace crow
{
- namespace mustache
- {
- class template_t;
- }
+ namespace mustache
+ {
+ class template_t;
+ }
namespace json
{
@@ -191,8 +191,8 @@ namespace crow
static const int cached_bit = 2;
static const int error_bit = 4;
public:
- rvalue() noexcept : option_{error_bit}
- {}
+ rvalue() noexcept : option_{error_bit}
+ {}
rvalue(type t) noexcept
: lsize_{}, lremain_{}, t_{t}
{}
@@ -399,32 +399,32 @@ namespace crow
return it != end() && it->key_ == str;
}
- int count(const std::string& str)
- {
- return has(str) ? 1 : 0;
- }
+ int count(const std::string& str)
+ {
+ return has(str) ? 1 : 0;
+ }
rvalue* begin() const
- {
+ {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::Object && t() != type::List)
throw std::runtime_error("value is not a container");
#endif
- return l_.get();
- }
+ return l_.get();
+ }
rvalue* end() const
- {
+ {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::Object && t() != type::List)
throw std::runtime_error("value is not a container");
#endif
- return l_.get()+lsize_;
- }
+ return l_.get()+lsize_;
+ }
- const detail::r_string& key() const
- {
- return key_;
- }
+ const detail::r_string& key() const
+ {
+ return key_;
+ }
size_t size() const
{
@@ -437,27 +437,27 @@ namespace crow
return lsize_;
}
- const rvalue& operator[](int index) const
- {
+ const rvalue& operator[](int index) const
+ {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::List)
throw std::runtime_error("value is not a list");
- if (index >= (int)lsize_ || index < 0)
+ if (index >= (int)lsize_ || index < 0)
throw std::runtime_error("list out of bound");
#endif
- return l_[index];
- }
+ return l_[index];
+ }
- const rvalue& operator[](size_t index) const
- {
+ const rvalue& operator[](size_t index) const
+ {
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::List)
throw std::runtime_error("value is not a list");
- if (index >= lsize_)
+ if (index >= lsize_)
throw std::runtime_error("list out of bound");
#endif
- return l_[index];
- }
+ return l_[index];
+ }
const rvalue& operator[](const char* str) const
{
@@ -650,14 +650,14 @@ namespace crow
inline rvalue load_nocopy_internal(char* data, size_t size)
{
//static const char* escaped = "\"\\/\b\f\n\r\t";
- struct Parser
- {
- Parser(char* data, size_t size)
- : data(data)
- {
- }
-
- bool consume(char c)
+ struct Parser
+ {
+ Parser(char* data, size_t size)
+ : data(data)
+ {
+ }
+
+ bool consume(char c)
{
if (crow_json_unlikely(*data != c))
return false;
@@ -665,12 +665,12 @@ namespace crow
return true;
}
- void ws_skip()
+ void ws_skip()
{
- while(*data == ' ' || *data == '\t' || *data == '\r' || *data == '\n') ++data;
+ while(*data == ' ' || *data == '\t' || *data == '\r' || *data == '\n') ++data;
};
- rvalue decode_string()
+ rvalue decode_string()
{
if (crow_json_unlikely(!consume('"')))
return {};
@@ -732,30 +732,30 @@ namespace crow
return {};
}
- rvalue decode_list()
+ rvalue decode_list()
{
- rvalue ret(type::List);
- if (crow_json_unlikely(!consume('[')))
+ rvalue ret(type::List);
+ if (crow_json_unlikely(!consume('[')))
{
ret.set_error();
- return ret;
+ return ret;
}
- ws_skip();
- if (crow_json_unlikely(*data == ']'))
- {
- data++;
- return ret;
- }
-
- while(1)
- {
+ ws_skip();
+ if (crow_json_unlikely(*data == ']'))
+ {
+ data++;
+ return ret;
+ }
+
+ while(1)
+ {
auto v = decode_value();
- if (crow_json_unlikely(!v))
+ if (crow_json_unlikely(!v))
{
ret.set_error();
break;
}
- ws_skip();
+ ws_skip();
ret.emplace_back(std::move(v));
if (*data == ']')
{
@@ -767,12 +767,12 @@ namespace crow
ret.set_error();
break;
}
- ws_skip();
- }
+ ws_skip();
+ }
return ret;
}
- rvalue decode_number()
+ rvalue decode_number()
{
char* start = data;
@@ -809,7 +809,7 @@ namespace crow
}
else
return {};*/
- break;
+ break;
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
@@ -890,14 +890,14 @@ namespace crow
return {};
}
- rvalue decode_value()
+ rvalue decode_value()
{
switch(*data)
{
case '[':
- return decode_list();
+ return decode_list();
case '{':
- return decode_object();
+ return decode_object();
case '"':
return decode_string();
case 't':
@@ -944,7 +944,7 @@ namespace crow
return {};
}
- rvalue decode_object()
+ rvalue decode_object()
{
rvalue ret(type::Object);
if (crow_json_unlikely(!consume('{')))
@@ -953,7 +953,7 @@ namespace crow
return ret;
}
- ws_skip();
+ ws_skip();
if (crow_json_unlikely(*data == '}'))
{
@@ -970,24 +970,24 @@ namespace crow
break;
}
- ws_skip();
+ ws_skip();
if (crow_json_unlikely(!consume(':')))
{
ret.set_error();
break;
}
- // TODO caching key to speed up (flyweight?)
+ // TODO caching key to speed up (flyweight?)
auto key = t.s();
- ws_skip();
+ ws_skip();
auto v = decode_value();
if (crow_json_unlikely(!v))
{
ret.set_error();
break;
}
- ws_skip();
+ ws_skip();
v.key_ = std::move(key);
ret.emplace_back(std::move(v));
@@ -1001,24 +1001,24 @@ namespace crow
ret.set_error();
break;
}
- ws_skip();
+ ws_skip();
}
return ret;
}
- rvalue parse()
- {
+ rvalue parse()
+ {
+ ws_skip();
+ auto ret = decode_value(); // or decode object?
ws_skip();
- auto ret = decode_value(); // or decode object?
- ws_skip();
if (ret && *data != '\0')
ret.set_error();
- return ret;
- }
+ return ret;
+ }
- char* data;
- };
- return Parser(data, size).parse();
+ char* data;
+ };
+ return Parser(data, size).parse();
}
inline rvalue load(const char* data, size_t size)
{
@@ -1045,7 +1045,7 @@ namespace crow
class wvalue
{
- friend class crow::mustache::template_t;
+ friend class crow::mustache::template_t;
public:
type t() const { return t_; }
private:
@@ -1253,14 +1253,14 @@ namespace crow
return (*l)[index];
}
- int count(const std::string& str)
- {
+ int count(const std::string& str)
+ {
if (t_ != type::Object)
return 0;
if (!o)
return 0;
return o->count(str);
- }
+ }
wvalue& operator[](const std::string& str)
{
diff --git a/include/mustache.h b/include/mustache.h
index 6fd210b..b596b45 100644
--- a/include/mustache.h
+++ b/include/mustache.h
@@ -284,9 +284,9 @@ namespace crow
public:
std::string render()
{
- context empty_ctx;
- std::vector<context*> stack;
- stack.emplace_back(&empty_ctx);
+ context empty_ctx;
+ std::vector<context*> stack;
+ stack.emplace_back(&empty_ctx);
std::string ret;
render_internal(0, fragments_.size()-1, stack, ret, 0);
@@ -294,8 +294,8 @@ namespace crow
}
std::string render(context& ctx)
{
- std::vector<context*> stack;
- stack.emplace_back(&ctx);
+ std::vector<context*> stack;
+ stack.emplace_back(&ctx);
std::string ret;
render_internal(0, fragments_.size()-1, stack, ret, 0);
@@ -357,7 +357,7 @@ namespace crow
body_.substr(matched.start, matched.end - matched.start) + ", " +
body_.substr(idx, endIdx-idx));
}
- matched.pos = actions_.size();
+ matched.pos = actions_.size();
}
actions_.emplace_back(ActionType::CloseBlock, idx, endIdx, blockPositions.back());
blockPositions.pop_back();
diff --git a/include/routing.h b/include/routing.h
index 9f607f1..f074b69 100644
--- a/include/routing.h
+++ b/include/routing.h
@@ -636,9 +636,9 @@ public:
if (!rule_index)
{
- CROW_LOG_DEBUG << "Cannot match rules " << req.url;
+ CROW_LOG_DEBUG << "Cannot match rules " << req.url;
res = response(404);
- res.end();
+ res.end();
return;
}
@@ -647,9 +647,9 @@ public:
if ((rules_[rule_index]->methods() & (1<<(uint32_t)req.method)) == 0)
{
- CROW_LOG_DEBUG << "Rule found but method mismatch: " << req.url << " with " << method_name(req.method) << "(" << (uint32_t)req.method << ") / " << rules_[rule_index]->methods();
+ CROW_LOG_DEBUG << "Rule found but method mismatch: " << req.url << " with " << method_name(req.method) << "(" << (uint32_t)req.method << ") / " << rules_[rule_index]->methods();
res = response(404);
- res.end();
+ res.end();
return;
}
diff --git a/include/settings.h b/include/settings.h
index e40f9e4..e6b32cf 100644
--- a/include/settings.h
+++ b/include/settings.h
@@ -10,11 +10,11 @@
/* #define - specifies log level */
/*
- DEBUG = 0
- INFO = 1
- WARNING = 2
- ERROR = 3
- CRITICAL = 4
+ DEBUG = 0
+ INFO = 1
+ WARNING = 2
+ ERROR = 3
+ CRITICAL = 4
default to INFO
*/
diff --git a/include/utility.h b/include/utility.h
index c910eb2..c036d35 100644
--- a/include/utility.h
+++ b/include/utility.h
@@ -7,48 +7,48 @@
namespace crow
{
- namespace black_magic
- {
- struct OutOfRange
- {
- OutOfRange(unsigned pos, unsigned length) {}
- };
- constexpr unsigned requires_in_range( unsigned i, unsigned len )
- {
- return i >= len ? throw OutOfRange(i, len) : i;
- }
-
- class const_str
- {
- const char * const begin_;
- unsigned size_;
-
- public:
- template< unsigned N >
- constexpr const_str( const char(&arr)[N] ) : begin_(arr), size_(N - 1) {
- static_assert( N >= 1, "not a string literal");
- }
- constexpr char operator[]( unsigned i ) const {
- return requires_in_range(i, size_), begin_[i];
- }
-
- constexpr operator const char *() const {
- return begin_;
- }
-
- constexpr const char* begin() const { return begin_; }
- constexpr const char* end() const { return begin_ + size_; }
-
- constexpr unsigned size() const {
- return size_;
- }
- };
-
-
- constexpr unsigned find_closing_tag(const_str s, unsigned p)
- {
- return s[p] == '>' ? p : find_closing_tag(s, p+1);
- }
+ namespace black_magic
+ {
+ struct OutOfRange
+ {
+ OutOfRange(unsigned pos, unsigned length) {}
+ };
+ constexpr unsigned requires_in_range( unsigned i, unsigned len )
+ {
+ return i >= len ? throw OutOfRange(i, len) : i;
+ }
+
+ class const_str
+ {
+ const char * const begin_;
+ unsigned size_;
+
+ public:
+ template< unsigned N >
+ constexpr const_str( const char(&arr)[N] ) : begin_(arr), size_(N - 1) {
+ static_assert( N >= 1, "not a string literal");
+ }
+ constexpr char operator[]( unsigned i ) const {
+ return requires_in_range(i, size_), begin_[i];
+ }
+
+ constexpr operator const char *() const {
+ return begin_;
+ }
+
+ constexpr const char* begin() const { return begin_; }
+ constexpr const char* end() const { return begin_ + size_; }
+
+ constexpr unsigned size() const {
+ return size_;
+ }
+ };
+
+
+ constexpr unsigned find_closing_tag(const_str s, unsigned p)
+ {
+ return s[p] == '>' ? p : find_closing_tag(s, p+1);
+ }
constexpr bool is_valid(const_str s, unsigned i = 0, int f = 0)
{
@@ -293,5 +293,39 @@ template <typename F, typename Set>
struct empty_context
{
};
- }
+
+ } // namespace black_magic
+
+ namespace detail
+ {
+
+ template <class T, std::size_t N, class... Args>
+ struct get_index_of_element_from_tuple_by_type_impl
+ {
+ static constexpr auto value = N;
+ };
+
+ template <class T, std::size_t N, class... Args>
+ struct get_index_of_element_from_tuple_by_type_impl<T, N, T, Args...>
+ {
+ static constexpr auto value = N;
+ };
+
+ template <class T, std::size_t N, class U, class... Args>
+ struct get_index_of_element_from_tuple_by_type_impl<T, N, U, Args...>
+ {
+ static constexpr auto value = get_index_of_element_from_tuple_by_type_impl<T, N + 1, Args...>::value;
+ };
+
+ } // namespace detail
+
+ namespace utility
+ {
+ template <class T, class... Args>
+ T& get_element_by_type(std::tuple<Args...>& t)
+ {
+ return std::get<detail::get_index_of_element_from_tuple_by_type_impl<T, 0, Args...>::value>(t);
+ }
+
+ } // namespace utility
}