summaryrefslogtreecommitdiff
path: root/src/lib/dcpomatic_socket.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-01-29 20:02:56 +0000
committerCarl Hetherington <cth@carlh.net>2015-01-29 20:02:56 +0000
commitbfe277e664a03ec47cd6bee7e1b1e4aca6eb38e6 (patch)
tree6bdc6fa07f2cde0565c4025ab552f2c0fc9c3b2f /src/lib/dcpomatic_socket.cc
parent6a0da4eb43fc684c0f54a7a3a817a31dc8db7109 (diff)
parent27867be66579551018c926ed3339624e463c1b08 (diff)
Merge branch '2.0' of git.carlh.net:git/dcpomatic into 2.0
Diffstat (limited to 'src/lib/dcpomatic_socket.cc')
-rw-r--r--src/lib/dcpomatic_socket.cc126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/lib/dcpomatic_socket.cc b/src/lib/dcpomatic_socket.cc
new file mode 100644
index 000000000..d575e3230
--- /dev/null
+++ b/src/lib/dcpomatic_socket.cc
@@ -0,0 +1,126 @@
+/*
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "dcpomatic_socket.h"
+#include "compose.hpp"
+#include "exceptions.h"
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+
+#include "i18n.h"
+
+Socket::Socket (int timeout)
+ : _deadline (_io_service)
+ , _socket (_io_service)
+ , _timeout (timeout)
+{
+ _deadline.expires_at (boost::posix_time::pos_infin);
+ check ();
+}
+
+void
+Socket::check ()
+{
+ if (_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now ()) {
+ _socket.close ();
+ _deadline.expires_at (boost::posix_time::pos_infin);
+ }
+
+ _deadline.async_wait (boost::bind (&Socket::check, this));
+}
+
+/** Blocking connect.
+ * @param endpoint End-point to connect to.
+ */
+void
+Socket::connect (boost::asio::ip::tcp::endpoint endpoint)
+{
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
+ _socket.async_connect (endpoint, boost::lambda::var(ec) = boost::lambda::_1);
+ do {
+ _io_service.run_one();
+ } while (ec == boost::asio::error::would_block);
+
+ if (ec) {
+ throw NetworkError (String::compose (_("error during async_connect (%1)"), ec.value ()));
+ }
+
+ if (!_socket.is_open ()) {
+ throw NetworkError (_("connect timed out"));
+ }
+}
+
+/** Blocking write.
+ * @param data Buffer to write.
+ * @param size Number of bytes to write.
+ */
+void
+Socket::write (uint8_t const * data, int size)
+{
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
+
+ boost::asio::async_write (_socket, boost::asio::buffer (data, size), boost::lambda::var(ec) = boost::lambda::_1);
+
+ do {
+ _io_service.run_one ();
+ } while (ec == boost::asio::error::would_block);
+
+ if (ec) {
+ throw NetworkError (String::compose (_("error during async_write (%1)"), ec.value ()));
+ }
+}
+
+void
+Socket::write (uint32_t v)
+{
+ v = htonl (v);
+ write (reinterpret_cast<uint8_t*> (&v), 4);
+}
+
+/** Blocking read.
+ * @param data Buffer to read to.
+ * @param size Number of bytes to read.
+ */
+void
+Socket::read (uint8_t* data, int size)
+{
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
+
+ boost::asio::async_read (_socket, boost::asio::buffer (data, size), boost::lambda::var(ec) = boost::lambda::_1);
+
+ do {
+ _io_service.run_one ();
+ } while (ec == boost::asio::error::would_block);
+
+ if (ec) {
+ throw NetworkError (String::compose (_("error during async_read (%1)"), ec.value ()));
+ }
+}
+
+uint32_t
+Socket::read_uint32 ()
+{
+ uint32_t v;
+ read (reinterpret_cast<uint8_t *> (&v), 4);
+ return ntohl (v);
+}
+