Repository: qpid-proton
Updated Branches:
  refs/heads/master c63b2bea6 -> 38a71ffe5


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/222574ed/proton-c/bindings/cpp/src/io/windows/socket.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/io/windows/socket.cpp 
b/proton-c/bindings/cpp/src/io/windows/socket.cpp
new file mode 100644
index 0000000..afd3b56
--- /dev/null
+++ b/proton-c/bindings/cpp/src/io/windows/socket.cpp
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "msg.hpp"
+
+#include <proton/io/socket.hpp>
+#include <proton/url.hpp>
+
+#define FD_SETSIZE 2048
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#if _WIN32_WINNT < 0x0501
+#error "Proton requires Windows API support for XP or later."
+#endif
+#include <winsock2.h>
+#include <mswsock.h>
+#include <Ws2tcpip.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <assert.h>
+
+namespace proton {
+namespace io {
+namespace socket {
+
+const descriptor INVALID_DESCRIPTOR = INVALID_SOCKET;
+
+std::string error_str() {
+    HRESULT code = WSAGetLastError();
+    char err[1024] = {0};
+    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
+                  FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, code, 0, (LPSTR)&err, 
sizeof(err), NULL);
+    return err;
+}
+
+io_error::io_error(const std::string& s) : error(s) {}
+
+namespace {
+
+template <class T> T check(T result, const std::string& msg=std::string()) {
+    if (result == SOCKET_ERROR)
+        throw io_error(msg + error_str());
+    return result;
+}
+
+void gai_check(int result, const std::string& msg="") {
+    if (result)
+        throw io_error(msg + gai_strerror(result));
+}
+
+} // namespace
+
+void initialize() {
+    WSADATA unused;
+    check(WSAStartup(0x0202, &unused), "can't load WinSock: "); // Version 2.2
+}
+
+void finalize() {
+    WSACleanup();
+}
+
+void engine::init() {
+    u_long nonblock = 1;
+    check(::ioctlsocket(socket_, FIONBIO, &nonblock), "ioctlsocket: ");
+}
+
+engine::engine(descriptor fd, handler& h, const connection_options &opts)
+    : connection_engine(h, opts), socket_(fd)
+{
+    init();
+}
+
+engine::engine(const url& u, handler& h, const connection_options &opts)
+    : connection_engine(h, opts), socket_(connect(u))
+{
+    init();
+}
+
+engine::~engine() {}
+
+void engine::read() {
+    mutable_buffer rbuf = read_buffer();
+    if (rbuf.size > 0) {
+        int n = ::recv(socket_, rbuf.data, rbuf.size, 0);
+        if (n > 0)
+            read_done(n);
+        else if (n == 0)
+            read_close();
+        else if (n == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
+            close("io_error", error_str());
+    }
+}
+
+void engine::write() {
+    const_buffer wbuf = write_buffer();
+    if (wbuf.size > 0) {
+    int n = ::send(socket_, wbuf.data, wbuf.size, 0);
+    if (n > 0)
+        write_done(n);
+    else if (n == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
+        close("io_error", error_str());
+    }
+}
+
+void engine::run() {
+    while (dispatch()) {
+        fd_set rd, wr;
+        FD_ZERO(&rd);
+        if (read_buffer().size)
+            FD_SET(socket_, &rd);
+        FD_ZERO(&wr);
+        if (write_buffer().size)
+            FD_SET(socket_, &wr);
+        int n = ::select(FD_SETSIZE, &rd, &wr, NULL, NULL);
+        if (n < 0) {
+            close("io_error", error_str());
+            break;
+        }
+        if (FD_ISSET(socket_, &rd)) {
+            read();
+        }
+        if (FD_ISSET(socket_, &wr))
+            write();
+    }
+    ::closesocket(socket_);
+}
+
+namespace {
+struct auto_addrinfo {
+    struct addrinfo *ptr;
+    auto_addrinfo() : ptr(0) {}
+    ~auto_addrinfo() { ::freeaddrinfo(ptr); }
+    addrinfo* operator->() const { return ptr; }
+};
+
+static const char *amqp_service(const char *port) {
+  // Help older Windows to know about amqp[s] ports
+  if (port) {
+    if (!strcmp("amqp", port)) return "5672";
+    if (!strcmp("amqps", port)) return "5671";
+  }
+  return port;
+}
+}
+
+
+descriptor connect(const proton::url& u) {
+    // convert "0.0.0.0" to "127.0.0.1" on Windows for outgoing sockets
+    std::string host = (u.host() == "0.0.0.0") ? "127.0.0.1" : u.host();
+    descriptor fd = INVALID_SOCKET;
+    try{
+        auto_addrinfo addr;
+        gai_check(::getaddrinfo(host.empty() ? 0 : host.c_str(),
+                                amqp_service(u.port().empty() ? 0 : 
u.port().c_str()),
+                                0, &addr.ptr),
+                  "connect address invalid: ");
+        fd = check(::socket(addr->ai_family, SOCK_STREAM, 0), "connect socket: 
");
+        check(::connect(fd, addr->ai_addr, addr->ai_addrlen), "connect: ");
+        return fd;
+    } catch (...) {
+        if (fd != INVALID_SOCKET) ::closesocket(fd);
+        throw;
+    }
+}
+
+listener::listener(const std::string& host, const std::string &port) : 
socket_(INVALID_SOCKET) {
+    try {
+        auto_addrinfo addr;
+        gai_check(::getaddrinfo(host.empty() ? 0 : host.c_str(),
+                                port.empty() ? 0 : port.c_str(), 0, &addr.ptr),
+                  "listener address invalid: ");
+        socket_ = check(::socket(addr->ai_family, SOCK_STREAM, 0), "listener 
socket: ");
+        bool yes = true;
+        check(setsockopt(socket_, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const 
char*)&yes, sizeof(yes)), "setsockopt: ");
+        check(::bind(socket_, addr->ai_addr, addr->ai_addrlen), "listener 
bind: ");
+        check(::listen(socket_, 32), "listener listen: ");
+    } catch (...) {
+        if (socket_ != INVALID_SOCKET) ::closesocket(socket_);
+        throw;
+    }
+}
+
+listener::~listener() { ::closesocket(socket_); }
+
+descriptor listener::accept(std::string& host_str, std::string& port_str) {
+    struct sockaddr_storage addr;
+    socklen_t size = sizeof(addr);
+    int fd = check(::accept(socket_, (struct sockaddr *)&addr, &size), 
"accept: ");
+    char host[NI_MAXHOST], port[NI_MAXSERV];
+    gai_check(getnameinfo((struct sockaddr *) &addr, sizeof(addr),
+                          host, sizeof(host), port, sizeof(port), 0),
+              "accept invalid remote address: ");
+    host_str = host;
+    port_str = port;
+    return fd;
+}
+
+}}}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/222574ed/proton-c/bindings/cpp/src/posix/io.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/posix/io.cpp 
b/proton-c/bindings/cpp/src/posix/io.cpp
deleted file mode 100644
index be9db44..0000000
--- a/proton-c/bindings/cpp/src/posix/io.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "msg.hpp"
-
-#include <proton/io.hpp>
-#include <proton/url.hpp>
-
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace proton {
-namespace io {
-
-const descriptor INVALID_DESCRIPTOR = -1;
-
-std::string error_str() {
-    char buf[512] = "Unknown error";
-#ifdef _GNU_SOURCE
-    // GNU strerror_r returns the message
-    return ::strerror_r(errno, buf, sizeof(buf));
-#else
-    // POSIX strerror_r doesn't return the buffer
-    ::strerror_r(errno, buf, sizeof(buf));
-    return std::string(buf)
-#endif
-}
-
-namespace {
-
-template <class T> T check(T result, const std::string& msg=std::string()) {
-    if (result < 0) throw connection_engine::io_error(msg + error_str());
-    return result;
-}
-
-void gai_check(int result, const std::string& msg="") {
-    if (result) throw connection_engine::io_error(msg + gai_strerror(result));
-}
-
-}
-
-void socket_engine::init() {
-    check(fcntl(socket_, F_SETFL, fcntl(socket_, F_GETFL, 0) | O_NONBLOCK), 
"set nonblock: ");
-}
-
-socket_engine::socket_engine(descriptor fd, handler& h, const 
connection_options &opts)
-    : connection_engine(h, opts), socket_(fd)
-{
-    init();
-}
-
-socket_engine::socket_engine(const url& u, handler& h, const 
connection_options& opts)
-    : connection_engine(h, opts), socket_(connect(u))
-{
-    init();
-}
-
-socket_engine::~socket_engine() {}
-
-std::pair<size_t, bool> socket_engine::io_read(char *buf, size_t size) {
-    ssize_t n = ::read(socket_, buf, size);
-    if (n > 0) return std::make_pair(n, true);
-    if (n == 0) return std::make_pair(0, false);
-    if (errno == EAGAIN || errno == EWOULDBLOCK)
-        return std::make_pair(0, true);
-    throw io_error("read: " + error_str());
-}
-
-size_t socket_engine::io_write(const char *buf, size_t size) {
-    ssize_t n = ::write(socket_, buf, size);
-    if (n == EAGAIN || n == EWOULDBLOCK) return 0;
-    if (n < 0) check(n, "write: ");
-    return n;
-}
-
-void socket_engine::io_close() { ::close(socket_); }
-
-void socket_engine::run() {
-    fd_set self;
-    FD_ZERO(&self);
-    FD_SET(socket_, &self);
-    while (!closed()) {
-        process();
-        if (!closed()) {
-            int n = select(FD_SETSIZE,
-                           can_read() ? &self : NULL,
-                           can_write() ? &self : NULL,
-                           NULL, NULL);
-            check(n, "select: ");
-        }
-    }
-}
-
-namespace {
-struct auto_addrinfo {
-    struct addrinfo *ptr;
-    auto_addrinfo() : ptr(0) {}
-    ~auto_addrinfo() { ::freeaddrinfo(ptr); }
-    addrinfo* operator->() const { return ptr; }
-};
-}
-
-descriptor connect(const proton::url& u) {
-    descriptor fd = INVALID_DESCRIPTOR;
-    try{
-        auto_addrinfo addr;
-        gai_check(::getaddrinfo(u.host().empty() ? 0 : u.host().c_str(),
-                                u.port().empty() ? 0 : u.port().c_str(),
-                                0, &addr.ptr), u.str()+": ");
-        fd = check(::socket(addr->ai_family, SOCK_STREAM, 0), "connect: ");
-        check(::connect(fd, addr->ai_addr, addr->ai_addrlen), "connect: ");
-        return fd;
-    } catch (...) {
-        if (fd >= 0) close(fd);
-        throw;
-    }
-}
-
-listener::listener(const std::string& host, const std::string &port) : 
socket_(INVALID_DESCRIPTOR) {
-    try {
-        auto_addrinfo addr;
-        gai_check(::getaddrinfo(host.empty() ? 0 : host.c_str(),
-                                port.empty() ? 0 : port.c_str(), 0, &addr.ptr),
-                  "listener address invalid: ");
-        socket_ = check(::socket(addr->ai_family, SOCK_STREAM, 0), "listen: ");
-        int yes = 1;
-        check(setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &yes, 
sizeof(yes)), "setsockopt: ");
-        check(::bind(socket_, addr->ai_addr, addr->ai_addrlen), "bind: ");
-        check(::listen(socket_, 32), "listen: ");
-    } catch (...) {
-        if (socket_ >= 0) close(socket_);
-        throw;
-    }
-}
-
-listener::~listener() { ::close(socket_); }
-
-descriptor listener::accept(std::string& host_str, std::string& port_str) {
-    struct sockaddr_storage addr;
-    socklen_t size = sizeof(addr);
-    int fd = check(::accept(socket_, (struct sockaddr *)&addr, &size), 
"accept: ");
-    char host[NI_MAXHOST], port[NI_MAXSERV];
-    gai_check(getnameinfo((struct sockaddr *) &addr, sizeof(addr),
-                          host, sizeof(host), port, sizeof(port), 0),
-              "accept invalid remote address: ");
-    host_str = host;
-    port_str = port;
-    return fd;
-}
-
-// Empty stubs, only needed on windows.
-void initialize() {}
-void finalize() {}
-}}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/222574ed/proton-c/bindings/cpp/src/scalar_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/scalar_test.cpp 
b/proton-c/bindings/cpp/src/scalar_test.cpp
index b5955d5..cd00d31 100644
--- a/proton-c/bindings/cpp/src/scalar_test.cpp
+++ b/proton-c/bindings/cpp/src/scalar_test.cpp
@@ -62,7 +62,6 @@ template <class T> void type_test(T x, type_id tid, T y) {
         FAIL("expected conversion_error: " #EXPR);                      \
     } catch (const conversion_error& e) {}
 
-// FIXME aconway 2016-03-15: new coerce stuff.
 void coerce_test() {
     scalar a;
     ASSERT_EQUAL(NULL_TYPE, a.type());

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/222574ed/proton-c/bindings/cpp/src/test_bits.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/test_bits.hpp 
b/proton-c/bindings/cpp/src/test_bits.hpp
index 38cd7a8..18298cb 100644
--- a/proton-c/bindings/cpp/src/test_bits.hpp
+++ b/proton-c/bindings/cpp/src/test_bits.hpp
@@ -30,18 +30,29 @@
 
 namespace test {
 
-struct fail : public std::logic_error { fail(const std::string& what) : 
logic_error(what) {} };
+struct fail : public std::logic_error {
+    fail(const std::string& what) : logic_error(what) {}
+};
+
+template <class T, class U>
+void assert_equal(const T& want, const U& got, const std::string& what) {
+    if (!(want == got))
+        throw fail(MSG(what << " " << want << " != " << got));
+}
 
-bool close(double want, double got, double delta) {
-    return fabs(want-got) <= delta;
+void assert_equalish(double want, double got, double delta, const std::string& 
what)
+{
+    if (!(fabs(want-got) <= delta))
+        throw fail(MSG(what << " " << want << " !=~ " << got));
 }
 
-#define FAIL(WHAT) throw fail(MSG(__FILE__ << ":" << __LINE__ << ": " << WHAT))
-#define ASSERT(TEST) do { if (!(TEST)) FAIL("assert failed: " << #TEST); } 
while(false)
-#define ASSERT_EQUAL(WANT, GOT) if (!((WANT) == (GOT))) \
-        FAIL(#WANT << " !=  " << #GOT << ": " << (WANT) << " != " << (GOT))
-#define ASSERT_CLOSE(WANT, GOT, DELTA) if (!close((WANT), (GOT), (DELTA))) \
-        FAIL(#WANT << " != " << #GOT << ": " << (WANT) << " != " << (GOT))
+#define FAIL_MSG(WHAT) (MSG(__FILE__ << ":" << __LINE__ << ": " << WHAT).str())
+#define FAIL(WHAT) throw fail(FAIL_MSG(WHAT))
+#define ASSERT(TEST) do { if (!(TEST)) FAIL("failed ASSERT(" #TEST ")"); } 
while(false)
+#define ASSERT_EQUAL(WANT, GOT) \
+    assert_equal((WANT), (GOT), FAIL_MSG("failed ASSERT_EQUAL(" #WANT ", " 
#GOT ")"))
+#define ASSERT_EQUALISH(WANT, GOT, DELTA) \
+    assert_equalish((WANT), (GOT), (DELTA), FAIL_MSG("failed ASSERT_EQUALISH(" 
#WANT ", " #GOT ")"))
 
 #define RUN_TEST(BAD_COUNT, TEST)                                       \
     do {                                                                \

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/222574ed/proton-c/bindings/cpp/src/value_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/value_test.cpp 
b/proton-c/bindings/cpp/src/value_test.cpp
index d636ffa..7b4940a 100644
--- a/proton-c/bindings/cpp/src/value_test.cpp
+++ b/proton-c/bindings/cpp/src/value_test.cpp
@@ -132,8 +132,8 @@ void get_coerce_test() {
     ASSERT_EQUAL(4, coerce<uint64_t>(value(uint32_t(4))));
     ASSERT_EQUAL(-4, coerce<int64_t>(value(int32_t(-4))));
 
-    ASSERT_CLOSE(1.2, coerce<float>(value(double(1.2))), 0.001);
-    ASSERT_CLOSE(3.4, coerce<double>(value(float(3.4))), 0.001);
+    ASSERT_EQUALISH(1.2, coerce<float>(value(double(1.2))), 0.001);
+    ASSERT_EQUALISH(3.4, coerce<double>(value(float(3.4))), 0.001);
 
     ASSERT_EQUAL(std::string("foo"), 
coerce<std::string>(value(symbol("foo"))));
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/222574ed/proton-c/bindings/cpp/src/windows/io.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/windows/io.cpp 
b/proton-c/bindings/cpp/src/windows/io.cpp
deleted file mode 100644
index 52f5fc0..0000000
--- a/proton-c/bindings/cpp/src/windows/io.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "msg.hpp"
-#include <proton/io.hpp>
-#include <proton/url.hpp>
-
-#define FD_SETSIZE 2048
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-#if _WIN32_WINNT < 0x0501
-#error "Proton requires Windows API support for XP or later."
-#endif
-#include <winsock2.h>
-#include <mswsock.h>
-#include <Ws2tcpip.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <assert.h>
-
-namespace proton {
-namespace io {
-
-const descriptor INVALID_DESCRIPTOR = INVALID_SOCKET;
-
-std::string error_str() {
-    HRESULT code = WSAGetLastError();
-    char err[1024] = {0};
-    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
-                  FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, code, 0, (LPSTR)&err, 
sizeof(err), NULL);
-    return err;
-}
-
-namespace {
-
-template <class T> T check(T result, const std::string& msg=std::string()) {
-    if (result == SOCKET_ERROR)
-        throw connection_engine::io_error(msg + error_str());
-    return result;
-}
-
-void gai_check(int result, const std::string& msg="") {
-    if (result)
-        throw connection_engine::io_error(msg + gai_strerror(result));
-}
-} // namespace
-
-void initialize() {
-    WSADATA unused;
-    check(WSAStartup(0x0202, &unused), "can't load WinSock: "); // Version 2.2
-}
-
-void finalize() {
-    WSACleanup();
-}
-
-void socket_engine::init() {
-    u_long nonblock = 1;
-    check(::ioctlsocket(socket_, FIONBIO, &nonblock), "ioctlsocket: ");
-}
-
-socket_engine::socket_engine(descriptor fd, handler& h, const 
connection_options &opts)
-    : connection_engine(h, opts), socket_(fd)
-{
-    init();
-}
-
-socket_engine::socket_engine(const url& u, handler& h, const 
connection_options &opts)
-    : connection_engine(h, opts), socket_(connect(u))
-{
-    init();
-}
-
-socket_engine::~socket_engine() {}
-
-std::pair<size_t, bool> socket_engine::io_read(char *buf, size_t size) {
-    int n = ::recv(socket_, buf, size, 0);
-    if (n > 0) return std::make_pair(n, true);
-    if (n == 0) return std::make_pair(0, false);
-    if (n == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
-        return std::make_pair(0, true);
-    throw connection_engine::io_error("read: " + error_str());
-}
-
-size_t socket_engine::io_write(const char *buf, size_t size) {
-    int n = ::send(socket_, buf, size, 0);
-    if (n == SOCKET_ERROR && n == WSAEWOULDBLOCK) return 0;
-    return check(n, "write: ");
-}
-
-void socket_engine::io_close() { ::closesocket(socket_); }
-
-void socket_engine::run() {
-    fd_set self;
-    FD_ZERO(&self);
-    FD_SET(socket_, &self);
-    while (!closed()) {
-        process();
-        if (!closed()) {
-            int n = ::select(FD_SETSIZE,
-                           can_read() ? &self : NULL,
-                           can_write() ? &self : NULL,
-                           NULL, NULL);
-            check(n, "select: ");
-        }
-    }
-}
-
-namespace {
-struct auto_addrinfo {
-    struct addrinfo *ptr;
-    auto_addrinfo() : ptr(0) {}
-    ~auto_addrinfo() { ::freeaddrinfo(ptr); }
-    addrinfo* operator->() const { return ptr; }
-};
-
-static const char *amqp_service(const char *port) {
-  // Help older Windows to know about amqp[s] ports
-  if (port) {
-    if (!strcmp("amqp", port)) return "5672";
-    if (!strcmp("amqps", port)) return "5671";
-  }
-  return port;
-}
-}
-
-descriptor connect(const proton::url& u) {
-    // convert "0.0.0.0" to "127.0.0.1" on Windows for outgoing sockets
-    std::string host = (u.host() == "0.0.0.0") ? "127.0.0.1" : u.host();
-    descriptor fd = INVALID_SOCKET;
-    try{
-        auto_addrinfo addr;
-        gai_check(::getaddrinfo(host.empty() ? 0 : host.c_str(),
-                                amqp_service(u.port().empty() ? 0 : 
u.port().c_str()),
-                                0, &addr.ptr),
-                  "connect address invalid: ");
-        fd = check(::socket(addr->ai_family, SOCK_STREAM, 0), "connect socket: 
");
-        check(::connect(fd, addr->ai_addr, addr->ai_addrlen), "connect: ");
-        return fd;
-    } catch (...) {
-        if (fd != INVALID_SOCKET) ::closesocket(fd);
-        throw;
-    }
-}
-
-listener::listener(const std::string& host, const std::string &port) : 
socket_(INVALID_SOCKET) {
-    try {
-        auto_addrinfo addr;
-        gai_check(::getaddrinfo(host.empty() ? 0 : host.c_str(),
-                                port.empty() ? 0 : port.c_str(), 0, &addr.ptr),
-                  "listener address invalid: ");
-        socket_ = check(::socket(addr->ai_family, SOCK_STREAM, 0), "listener 
socket: ");
-        bool yes = true;
-        check(setsockopt(socket_, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const 
char*)&yes, sizeof(yes)), "setsockopt: ");
-        check(::bind(socket_, addr->ai_addr, addr->ai_addrlen), "listener 
bind: ");
-        check(::listen(socket_, 32), "listener listen: ");
-    } catch (...) {
-        if (socket_ != INVALID_SOCKET) ::closesocket(socket_);
-        throw;
-    }
-}
-
-listener::~listener() { ::closesocket(socket_); }
-
-descriptor listener::accept(std::string& host_str, std::string& port_str) {
-    struct sockaddr_storage addr;
-    socklen_t size = sizeof(addr);
-    int fd = check(::accept(socket_, (struct sockaddr *)&addr, &size), 
"accept: ");
-    char host[NI_MAXHOST], port[NI_MAXSERV];
-    gai_check(getnameinfo((struct sockaddr *) &addr, sizeof(addr),
-                          host, sizeof(host), port, sizeof(port), 0),
-              "accept invalid remote address: ");
-    host_str = host;
-    port_str = port;
-    return fd;
-}
-
-}}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to