@@ -74,22 +74,6 @@ const uint32_t kOnMessageComplete = 3;
7474const  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
9478struct  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- 
762760const  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