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...
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);
}
-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());
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);
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);
}
-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);
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,