mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
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>
This commit is contained in:
parent
7972bdf783
commit
628307774e
@ -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
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user