Skip to content

Commit 4513cbb

Browse files
addaleaxevanlucas
authored andcommitted
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: #18133 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jon Moss <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Franziska Hinkelmann <[email protected]>
1 parent 5b5f5b1 commit 4513cbb

File tree

1 file changed

+31
-33
lines changed

1 file changed

+31
-33
lines changed

src/node_http_parser.cc

+31-33
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,6 @@ const uint32_t kOnMessageComplete = 3;
7272
const uint32_t kOnExecute = 4;
7373

7474

75-
#define HTTP_CB(name) \
76-
static int name(http_parser* p_) { \
77-
Parser* self = ContainerOf(&Parser::parser_, p_); \
78-
return self->name##_(); \
79-
} \
80-
int name##_()
81-
82-
83-
#define HTTP_DATA_CB(name) \
84-
static int name(http_parser* p_, const char* at, size_t length) { \
85-
Parser* self = ContainerOf(&Parser::parser_, p_); \
86-
return self->name##_(at, length); \
87-
} \
88-
int name##_(const char* at, size_t length)
89-
90-
9175
// helper class for the Parser
9276
struct StringPtr {
9377
StringPtr() {
@@ -182,27 +166,27 @@ class Parser : public AsyncWrap {
182166
}
183167

184168

185-
HTTP_CB(on_message_begin) {
169+
int on_message_begin() {
186170
num_fields_ = num_values_ = 0;
187171
url_.Reset();
188172
status_message_.Reset();
189173
return 0;
190174
}
191175

192176

193-
HTTP_DATA_CB(on_url) {
177+
int on_url(const char* at, size_t length) {
194178
url_.Update(at, length);
195179
return 0;
196180
}
197181

198182

199-
HTTP_DATA_CB(on_status) {
183+
int on_status(const char* at, size_t length) {
200184
status_message_.Update(at, length);
201185
return 0;
202186
}
203187

204188

205-
HTTP_DATA_CB(on_header_field) {
189+
int on_header_field(const char* at, size_t length) {
206190
if (num_fields_ == num_values_) {
207191
// start of new field name
208192
num_fields_++;
@@ -224,7 +208,7 @@ class Parser : public AsyncWrap {
224208
}
225209

226210

227-
HTTP_DATA_CB(on_header_value) {
211+
int on_header_value(const char* at, size_t length) {
228212
if (num_values_ != num_fields_) {
229213
// start of new header value
230214
num_values_++;
@@ -240,7 +224,7 @@ class Parser : public AsyncWrap {
240224
}
241225

242226

243-
HTTP_CB(on_headers_complete) {
227+
int on_headers_complete() {
244228
// Arguments for the on-headers-complete javascript callback. This
245229
// list needs to be kept in sync with the actual argument list for
246230
// `parserOnHeadersComplete` in lib/_http_common.js.
@@ -317,7 +301,7 @@ class Parser : public AsyncWrap {
317301
}
318302

319303

320-
HTTP_DATA_CB(on_body) {
304+
int on_body(const char* at, size_t length) {
321305
EscapableHandleScope scope(env()->isolate());
322306

323307
Local<Object> obj = object();
@@ -354,7 +338,7 @@ class Parser : public AsyncWrap {
354338
}
355339

356340

357-
HTTP_CB(on_message_complete) {
341+
int on_message_complete() {
358342
HandleScope scope(env()->isolate());
359343

360344
if (num_fields_)
@@ -751,21 +735,35 @@ class Parser : public AsyncWrap {
751735
StreamResource::Callback<StreamResource::AllocCb> prev_alloc_cb_;
752736
StreamResource::Callback<StreamResource::ReadCb> prev_read_cb_;
753737
int refcount_ = 1;
738+
739+
// These are helper functions for filling `http_parser_settings`, which turn
740+
// a member function of Parser into a C-style HTTP parser callback.
741+
template <typename Parser, Parser> struct Proxy;
742+
template <typename Parser, typename ...Args, int (Parser::*Member)(Args...)>
743+
struct Proxy<int (Parser::*)(Args...), Member> {
744+
static int Raw(http_parser* p, Args ... args) {
745+
Parser* parser = ContainerOf(&Parser::parser_, p);
746+
return (parser->*Member)(std::forward<Args>(args)...);
747+
}
748+
};
749+
750+
typedef int (Parser::*Call)();
751+
typedef int (Parser::*DataCall)(const char* at, size_t length);
752+
754753
static const struct http_parser_settings settings;
755754

756755
friend class ScopedRetainParser;
757756
};
758757

759-
760758
const struct http_parser_settings Parser::settings = {
761-
Parser::on_message_begin,
762-
Parser::on_url,
763-
Parser::on_status,
764-
Parser::on_header_field,
765-
Parser::on_header_value,
766-
Parser::on_headers_complete,
767-
Parser::on_body,
768-
Parser::on_message_complete,
759+
Proxy<Call, &Parser::on_message_begin>::Raw,
760+
Proxy<DataCall, &Parser::on_url>::Raw,
761+
Proxy<DataCall, &Parser::on_status>::Raw,
762+
Proxy<DataCall, &Parser::on_header_field>::Raw,
763+
Proxy<DataCall, &Parser::on_header_value>::Raw,
764+
Proxy<Call, &Parser::on_headers_complete>::Raw,
765+
Proxy<DataCall, &Parser::on_body>::Raw,
766+
Proxy<Call, &Parser::on_message_complete>::Raw,
769767
nullptr, // on_chunk_header
770768
nullptr // on_chunk_complete
771769
};

0 commit comments

Comments
 (0)