diff options
author | Anna Henningsen <anna@addaleax.net> | 2018-01-13 14:41:16 +0100 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2018-01-13 14:41:16 +0100 |
commit | 628307774eaf013654b3755f8c9ee6935fba06ad (patch) | |
tree | dde79891438f415a91f3543338aedae08e6be8e7 /src/node_http_parser.cc | |
parent | 7972bdf783c62247bea594ebd4bbb3e39925a0de (diff) | |
download | node-new-628307774eaf013654b3755f8c9ee6935fba06ad.tar.gz |
src: refactor callback #defines into C++ templates
Use template helpers instead of `#define`s to generate
the raw C callbacks that are passed to the HTTP parser library.
A nice effect of this is that it is more obvious what
parameters the `Parser` methods take.
PR-URL: https://github.com/nodejs/node/pull/18133
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Diffstat (limited to 'src/node_http_parser.cc')
-rw-r--r-- | src/node_http_parser.cc | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index f378a0475a..0f17050545 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -72,22 +72,6 @@ const uint32_t kOnMessageComplete = 3; const uint32_t kOnExecute = 4; -#define HTTP_CB(name) \ - static int name(http_parser* p_) { \ - Parser* self = ContainerOf(&Parser::parser_, p_); \ - return self->name##_(); \ - } \ - int name##_() - - -#define HTTP_DATA_CB(name) \ - static int name(http_parser* p_, const char* at, size_t length) { \ - Parser* self = ContainerOf(&Parser::parser_, p_); \ - return self->name##_(at, length); \ - } \ - int name##_(const char* at, size_t length) - - // helper class for the Parser struct StringPtr { StringPtr() { @@ -182,7 +166,7 @@ class Parser : public AsyncWrap { } - HTTP_CB(on_message_begin) { + int on_message_begin() { num_fields_ = num_values_ = 0; url_.Reset(); status_message_.Reset(); @@ -190,19 +174,19 @@ class Parser : public AsyncWrap { } - HTTP_DATA_CB(on_url) { + int on_url(const char* at, size_t length) { url_.Update(at, length); return 0; } - HTTP_DATA_CB(on_status) { + int on_status(const char* at, size_t length) { status_message_.Update(at, length); return 0; } - HTTP_DATA_CB(on_header_field) { + int on_header_field(const char* at, size_t length) { if (num_fields_ == num_values_) { // start of new field name num_fields_++; @@ -224,7 +208,7 @@ class Parser : public AsyncWrap { } - HTTP_DATA_CB(on_header_value) { + int on_header_value(const char* at, size_t length) { if (num_values_ != num_fields_) { // start of new header value num_values_++; @@ -240,7 +224,7 @@ class Parser : public AsyncWrap { } - HTTP_CB(on_headers_complete) { + int on_headers_complete() { // Arguments for the on-headers-complete javascript callback. This // list needs to be kept in sync with the actual argument list for // `parserOnHeadersComplete` in lib/_http_common.js. @@ -317,7 +301,7 @@ class Parser : public AsyncWrap { } - HTTP_DATA_CB(on_body) { + int on_body(const char* at, size_t length) { EscapableHandleScope scope(env()->isolate()); Local<Object> obj = object(); @@ -354,7 +338,7 @@ class Parser : public AsyncWrap { } - HTTP_CB(on_message_complete) { + int on_message_complete() { HandleScope scope(env()->isolate()); if (num_fields_) @@ -751,21 +735,35 @@ class Parser : public AsyncWrap { StreamResource::Callback<StreamResource::AllocCb> prev_alloc_cb_; StreamResource::Callback<StreamResource::ReadCb> prev_read_cb_; int refcount_ = 1; + + // These are helper functions for filling `http_parser_settings`, which turn + // a member function of Parser into a C-style HTTP parser callback. + template <typename Parser, Parser> struct Proxy; + template <typename Parser, typename ...Args, int (Parser::*Member)(Args...)> + struct Proxy<int (Parser::*)(Args...), Member> { + static int Raw(http_parser* p, Args ... args) { + Parser* parser = ContainerOf(&Parser::parser_, p); + return (parser->*Member)(std::forward<Args>(args)...); + } + }; + + typedef int (Parser::*Call)(); + typedef int (Parser::*DataCall)(const char* at, size_t length); + static const struct http_parser_settings settings; friend class ScopedRetainParser; }; - const struct http_parser_settings Parser::settings = { - Parser::on_message_begin, - Parser::on_url, - Parser::on_status, - Parser::on_header_field, - Parser::on_header_value, - Parser::on_headers_complete, - Parser::on_body, - Parser::on_message_complete, + Proxy<Call, &Parser::on_message_begin>::Raw, + Proxy<DataCall, &Parser::on_url>::Raw, + Proxy<DataCall, &Parser::on_status>::Raw, + Proxy<DataCall, &Parser::on_header_field>::Raw, + Proxy<DataCall, &Parser::on_header_value>::Raw, + Proxy<Call, &Parser::on_headers_complete>::Raw, + Proxy<DataCall, &Parser::on_body>::Raw, + Proxy<Call, &Parser::on_message_complete>::Raw, nullptr, // on_chunk_header nullptr // on_chunk_complete }; |