Skip to content

Commit 59f1330

Browse files
addaleaxrvagg
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 <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>
1 parent 18fd620 commit 59f1330

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
@@ -74,22 +74,6 @@ const uint32_t kOnMessageComplete = 3;
7474
const uint32_t kOnExecute = 4;
7575

7676

77-
#define HTTP_CB(name) \
78-
static int name(http_parser* p_) { \
79-
Parser* self = ContainerOf(&Parser::parser_, p_); \
80-
return self->name##_(); \
81-
} \
82-
int name##_()
83-
84-
85-
#define HTTP_DATA_CB(name) \
86-
static int name(http_parser* p_, const char* at, size_t length) { \
87-
Parser* self = ContainerOf(&Parser::parser_, p_); \
88-
return self->name##_(at, length); \
89-
} \
90-
int name##_(const char* at, size_t length)
91-
92-
9377
// helper class for the Parser
9478
struct StringPtr {
9579
StringPtr() {
@@ -184,27 +168,27 @@ class Parser : public AsyncWrap {
184168
}
185169

186170

187-
HTTP_CB(on_message_begin) {
171+
int on_message_begin() {
188172
num_fields_ = num_values_ = 0;
189173
url_.Reset();
190174
status_message_.Reset();
191175
return 0;
192176
}
193177

194178

195-
HTTP_DATA_CB(on_url) {
179+
int on_url(const char* at, size_t length) {
196180
url_.Update(at, length);
197181
return 0;
198182
}
199183

200184

201-
HTTP_DATA_CB(on_status) {
185+
int on_status(const char* at, size_t length) {
202186
status_message_.Update(at, length);
203187
return 0;
204188
}
205189

206190

207-
HTTP_DATA_CB(on_header_field) {
191+
int on_header_field(const char* at, size_t length) {
208192
if (num_fields_ == num_values_) {
209193
// start of new field name
210194
num_fields_++;
@@ -226,7 +210,7 @@ class Parser : public AsyncWrap {
226210
}
227211

228212

229-
HTTP_DATA_CB(on_header_value) {
213+
int on_header_value(const char* at, size_t length) {
230214
if (num_values_ != num_fields_) {
231215
// start of new header value
232216
num_values_++;
@@ -242,7 +226,7 @@ class Parser : public AsyncWrap {
242226
}
243227

244228

245-
HTTP_CB(on_headers_complete) {
229+
int on_headers_complete() {
246230
// Arguments for the on-headers-complete javascript callback. This
247231
// list needs to be kept in sync with the actual argument list for
248232
// `parserOnHeadersComplete` in lib/_http_common.js.
@@ -319,7 +303,7 @@ class Parser : public AsyncWrap {
319303
}
320304

321305

322-
HTTP_DATA_CB(on_body) {
306+
int on_body(const char* at, size_t length) {
323307
EscapableHandleScope scope(env()->isolate());
324308

325309
Local<Object> obj = object();
@@ -356,7 +340,7 @@ class Parser : public AsyncWrap {
356340
}
357341

358342

359-
HTTP_CB(on_message_complete) {
343+
int on_message_complete() {
360344
HandleScope scope(env()->isolate());
361345

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

758757
friend class ScopedRetainParser;
759758
};
760759

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

0 commit comments

Comments
 (0)