src: DRY getsockname/getpeername code
authorBen Noordhuis <info@bnoordhuis.nl>
Wed, 25 Feb 2015 15:40:40 +0000 (16:40 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Thu, 27 Aug 2015 15:44:15 +0000 (17:44 +0200)
Extract the common logic into a template function.  No functional
changes, just code cleanup.

PR-URL: https://github.com/nodejs/node/pull/956
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
src/node_internals.h
src/tcp_wrap.cc
src/tcp_wrap.h
src/udp_wrap.cc
src/udp_wrap.h

index ffb5ec7..aa19866 100644 (file)
@@ -79,6 +79,19 @@ v8::Local<v8::Object> AddressToJS(
     const sockaddr* addr,
     v8::Local<v8::Object> info = v8::Handle<v8::Object>());
 
+template <typename T, int (*F)(const typename T::HandleType*, sockaddr*, int*)>
+void GetSockOrPeerName(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  T* const wrap = Unwrap<T>(args.Holder());
+  CHECK(args[0]->IsObject());
+  sockaddr_storage storage;
+  int addrlen = sizeof(storage);
+  sockaddr* const addr = reinterpret_cast<sockaddr*>(&storage);
+  const int err = F(&wrap->handle_, addr, &addrlen);
+  if (err == 0)
+    AddressToJS(wrap->env(), addr, args[0].As<v8::Object>());
+  args.GetReturnValue().Set(err);
+}
+
 #ifdef _WIN32
 // emulate snprintf() on windows, _snprintf() doesn't zero-terminate the buffer
 // on overflow...
index 6980f8b..d9a3588 100644 (file)
@@ -98,8 +98,10 @@ void TCPWrap::Initialize(Handle<Object> target,
   env->SetProtoMethod(t, "connect", Connect);
   env->SetProtoMethod(t, "bind6", Bind6);
   env->SetProtoMethod(t, "connect6", Connect6);
-  env->SetProtoMethod(t, "getsockname", GetSockName);
-  env->SetProtoMethod(t, "getpeername", GetPeerName);
+  env->SetProtoMethod(t, "getsockname",
+                      GetSockOrPeerName<TCPWrap, uv_tcp_getsockname>);
+  env->SetProtoMethod(t, "getpeername",
+                      GetSockOrPeerName<TCPWrap, uv_tcp_getpeername>);
   env->SetProtoMethod(t, "setNoDelay", SetNoDelay);
   env->SetProtoMethod(t, "setKeepAlive", SetKeepAlive);
 
@@ -162,50 +164,6 @@ TCPWrap::~TCPWrap() {
 }
 
 
-void TCPWrap::GetSockName(const FunctionCallbackInfo<Value>& args) {
-  Environment* env = Environment::GetCurrent(args);
-  struct sockaddr_storage address;
-
-  TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
-
-  CHECK(args[0]->IsObject());
-  Local<Object> out = args[0].As<Object>();
-
-  int addrlen = sizeof(address);
-  int err = uv_tcp_getsockname(&wrap->handle_,
-                               reinterpret_cast<sockaddr*>(&address),
-                               &addrlen);
-  if (err == 0) {
-    const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
-    AddressToJS(env, addr, out);
-  }
-
-  args.GetReturnValue().Set(err);
-}
-
-
-void TCPWrap::GetPeerName(const FunctionCallbackInfo<Value>& args) {
-  Environment* env = Environment::GetCurrent(args);
-  struct sockaddr_storage address;
-
-  TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
-
-  CHECK(args[0]->IsObject());
-  Local<Object> out = args[0].As<Object>();
-
-  int addrlen = sizeof(address);
-  int err = uv_tcp_getpeername(&wrap->handle_,
-                               reinterpret_cast<sockaddr*>(&address),
-                               &addrlen);
-  if (err == 0) {
-    const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
-    AddressToJS(env, addr, out);
-  }
-
-  args.GetReturnValue().Set(err);
-}
-
-
 void TCPWrap::SetNoDelay(const FunctionCallbackInfo<Value>& args) {
   TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
   int enable = static_cast<int>(args[0]->BooleanValue());
index ee1e981..79404a7 100644 (file)
@@ -19,12 +19,16 @@ class TCPWrap : public StreamWrap {
   size_t self_size() const override { return sizeof(*this); }
 
  private:
+  typedef uv_tcp_t HandleType;
+
+  template <typename T,
+            int (*F)(const typename T::HandleType*, sockaddr*, int*)>
+  friend void GetSockOrPeerName(const v8::FunctionCallbackInfo<v8::Value>&);
+
   TCPWrap(Environment* env, v8::Handle<v8::Object> object, AsyncWrap* parent);
   ~TCPWrap();
 
   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
-  static void GetSockName(const v8::FunctionCallbackInfo<v8::Value>& args);
-  static void GetPeerName(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void SetNoDelay(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void SetKeepAlive(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void Bind(const v8::FunctionCallbackInfo<v8::Value>& args);
index dd3958e..71cc547 100644 (file)
@@ -96,7 +96,8 @@ void UDPWrap::Initialize(Handle<Object> target,
   env->SetProtoMethod(t, "close", Close);
   env->SetProtoMethod(t, "recvStart", RecvStart);
   env->SetProtoMethod(t, "recvStop", RecvStop);
-  env->SetProtoMethod(t, "getsockname", GetSockName);
+  env->SetProtoMethod(t, "getsockname",
+                      GetSockOrPeerName<UDPWrap, uv_udp_getsockname>);
   env->SetProtoMethod(t, "addMembership", AddMembership);
   env->SetProtoMethod(t, "dropMembership", DropMembership);
   env->SetProtoMethod(t, "setMulticastTTL", SetMulticastTTL);
@@ -325,29 +326,6 @@ void UDPWrap::RecvStop(const FunctionCallbackInfo<Value>& args) {
 }
 
 
-void UDPWrap::GetSockName(const FunctionCallbackInfo<Value>& args) {
-  Environment* env = Environment::GetCurrent(args);
-
-  struct sockaddr_storage address;
-  UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder());
-
-  CHECK(args[0]->IsObject());
-  Local<Object> obj = args[0].As<Object>();
-
-  int addrlen = sizeof(address);
-  int err = uv_udp_getsockname(&wrap->handle_,
-                               reinterpret_cast<sockaddr*>(&address),
-                               &addrlen);
-
-  if (err == 0) {
-    const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
-    AddressToJS(env, addr, obj);
-  }
-
-  args.GetReturnValue().Set(err);
-}
-
-
 // TODO(bnoordhuis) share with StreamWrap::AfterWrite() in stream_wrap.cc
 void UDPWrap::OnSend(uv_udp_send_t* req, int status) {
   SendWrap* req_wrap = static_cast<SendWrap*>(req->data);
index 3373cb9..1582fb4 100644 (file)
@@ -40,6 +40,12 @@ class UDPWrap: public HandleWrap {
   size_t self_size() const override { return sizeof(*this); }
 
  private:
+  typedef uv_udp_t HandleType;
+
+  template <typename T,
+            int (*F)(const typename T::HandleType*, sockaddr*, int*)>
+  friend void GetSockOrPeerName(const v8::FunctionCallbackInfo<v8::Value>&);
+
   UDPWrap(Environment* env, v8::Handle<v8::Object> object, AsyncWrap* parent);
 
   static void DoBind(const v8::FunctionCallbackInfo<v8::Value>& args,