@@ -106,18 +106,31 @@ class WriteWrap: public ReqWrap<uv_write_t>,
106106
107107class StreamResource {
108108 public:
109+ template <class T >
110+ struct Callback {
111+ Callback () : fn(nullptr ), ctx(nullptr ) {}
112+ Callback (T fn, void * ctx) : fn(fn), ctx(ctx) {}
113+ Callback (const Callback&) = default ;
114+
115+ inline bool is_empty () { return fn == nullptr ; }
116+ inline void clear () {
117+ fn = nullptr ;
118+ ctx = nullptr ;
119+ }
120+
121+ T fn;
122+ void * ctx;
123+ };
124+
109125 typedef void (*AfterWriteCb)(WriteWrap* w, void * ctx);
110126 typedef void (*AllocCb)(size_t size, uv_buf_t * buf, void * ctx);
111127 typedef void (*ReadCb)(ssize_t nread,
112128 const uv_buf_t * buf,
113129 uv_handle_type pending,
114130 void * ctx);
115131
116- StreamResource () : after_write_cb_(nullptr ),
117- alloc_cb_ (nullptr ),
118- read_cb_(nullptr ) {
132+ StreamResource () {
119133 }
120-
121134 virtual ~StreamResource () = default ;
122135
123136 virtual int DoShutdown (ShutdownWrap* req_wrap) = 0;
@@ -131,44 +144,37 @@ class StreamResource {
131144
132145 // Events
133146 inline void OnAfterWrite (WriteWrap* w) {
134- if (after_write_cb_ != nullptr )
135- after_write_cb_ (w, after_write_ctx_ );
147+ if (!after_write_cb_. is_empty () )
148+ after_write_cb_. fn (w, after_write_cb_. ctx );
136149 }
137150
138151 inline void OnAlloc (size_t size, uv_buf_t * buf) {
139- if (alloc_cb_ != nullptr )
140- alloc_cb_ (size, buf, alloc_ctx_ );
152+ if (!alloc_cb_. is_empty () )
153+ alloc_cb_. fn (size, buf, alloc_cb_. ctx );
141154 }
142155
143156 inline void OnRead (size_t nread,
144157 const uv_buf_t * buf,
145158 uv_handle_type pending = UV_UNKNOWN_HANDLE) {
146- if (read_cb_ != nullptr )
147- read_cb_ (nread, buf, pending, read_ctx_ );
159+ if (!read_cb_. is_empty () )
160+ read_cb_. fn (nread, buf, pending, read_cb_. ctx );
148161 }
149162
150- inline void set_after_write_cb (AfterWriteCb cb, void * ctx) {
151- after_write_ctx_ = ctx;
152- after_write_cb_ = cb;
163+ inline void set_after_write_cb (Callback<AfterWriteCb> c) {
164+ after_write_cb_ = c;
153165 }
154166
155- inline void set_alloc_cb (AllocCb cb, void * ctx) {
156- alloc_cb_ = cb;
157- alloc_ctx_ = ctx;
158- }
167+ inline void set_alloc_cb (Callback<AllocCb> c) { alloc_cb_ = c; }
168+ inline void set_read_cb (Callback<ReadCb> c) { read_cb_ = c; }
159169
160- inline void set_read_cb (ReadCb cb, void * ctx) {
161- read_cb_ = cb;
162- read_ctx_ = ctx;
163- }
170+ inline Callback<AfterWriteCb> after_write_cb () { return after_write_cb_; }
171+ inline Callback<AllocCb> alloc_cb () { return alloc_cb_; }
172+ inline Callback<ReadCb> read_cb () { return read_cb_; }
164173
165174 private:
166- AfterWriteCb after_write_cb_;
167- void * after_write_ctx_;
168- AllocCb alloc_cb_;
169- void * alloc_ctx_;
170- ReadCb read_cb_;
171- void * read_ctx_;
175+ Callback<AfterWriteCb> after_write_cb_;
176+ Callback<AllocCb> alloc_cb_;
177+ Callback<ReadCb> read_cb_;
172178};
173179
174180class StreamBase : public StreamResource {
@@ -211,7 +217,9 @@ class StreamBase : public StreamResource {
211217
212218 virtual ~StreamBase () = default ;
213219
214- virtual AsyncWrap* GetAsyncWrap () = 0;
220+ // One of these must be implemented
221+ virtual AsyncWrap* GetAsyncWrap ();
222+ virtual v8::Local<v8::Object> GetObject ();
215223
216224 // Libuv callbacks
217225 static void AfterShutdown (ShutdownWrap* req, int status);
@@ -227,8 +235,12 @@ class StreamBase : public StreamResource {
227235 int WriteString (const v8::FunctionCallbackInfo<v8::Value>& args);
228236
229237 template <class Base >
230- static void GetFD (v8::Local<v8::String>,
231- const v8::PropertyCallbackInfo<v8::Value>&);
238+ static void GetFD (v8::Local<v8::String> key,
239+ const v8::PropertyCallbackInfo<v8::Value>& args);
240+
241+ template <class Base >
242+ static void GetExternal (v8::Local<v8::String> key,
243+ const v8::PropertyCallbackInfo<v8::Value>& args);
232244
233245 template <class Base ,
234246 int (StreamBase::*Method)( // NOLINT(whitespace/parens)
0 commit comments