diff --git a/Socket/ClientSocketHandle.ct b/Socket/ClientSocketHandle.ct index 267913db89044be40442b76fb04b5b97c8be0184..1e7fa7b93dcca55316ad338d8ccdd846875566fa 100644 --- a/Socket/ClientSocketHandle.ct +++ b/Socket/ClientSocketHandle.ct @@ -70,6 +70,27 @@ readfrom(std::string & buffer, typename Policy::AddressingPolicy::Address & from buffer.erase(buffer.begin()+rv,buffer.end()); } +template <class Policy> +prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::write(std::string const & data) +{ + unsigned written = this->write(data.data(),data.size()); + if (written == 0) + throw SystemException(EPIPE); + // This implementation ensures, we only call blocking() when + // necessary (since it incurs a system call overhead ...) + if (written < data.size() && this->blocking()) + // We need to enforce in the WritePolicy implementation, that + // DatagramFramingPolicy sockets will ALWAYS either write the + // complete datagram or nothing at all + while (written < data.size()) { + unsigned n = this->write(data.data()+written,data.size()-written); + if (n == 0) + throw SystemException(EPIPE); + written += n; + } + return written; +} + template <class Policy> prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::available() { diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti index 096673ed49574d9da59f48e43492e55e430ca339..1e311213388e885ea8781fc1a67073dadbc3237a 100644 --- a/Socket/ClientSocketHandle.cti +++ b/Socket/ClientSocketHandle.cti @@ -80,18 +80,6 @@ readfrom(char * buffer, unsigned size, typename Policy::AddressingPolicy::Addres return Policy::ReadPolicy::readfrom(*this, buffer, size, from); } -template <class Policy> -prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::write(std::string const & data) -{ - if (this->blocking()) { - unsigned written = 0; - while (written < data.size()) - written += this->write(data.data()+written,data.size()-written); - return data.size(); - } else - return this->write(data.data(),data.size()); -} - template <class Policy> prefix_ unsigned satcom::lib::ClientSocketHandle<Policy>::write(char const * buffer, unsigned size) diff --git a/Socket/ClientSocketHandle.hh b/Socket/ClientSocketHandle.hh index e30ac4a5c32a0826e96eebc46a0b2551b7a06c02..3b5b8b57165c1ba5561dcd9f1600e11f4bbc1957 100644 --- a/Socket/ClientSocketHandle.hh +++ b/Socket/ClientSocketHandle.hh @@ -20,6 +20,9 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// TODO: Move all not template-parameter dependent code into a +// non-template base class + #ifndef HH_ClientSocketHandle_ #define HH_ClientSocketHandle_ 1 diff --git a/Socket/ClientSocketHandle.test.cc b/Socket/ClientSocketHandle.test.cc index 16f2a3c1a1d257378b766679f9b5df6ce7cc1071..e82c57da687180c692e2633e649ee999e5a59a62 100644 --- a/Socket/ClientSocketHandle.test.cc +++ b/Socket/ClientSocketHandle.test.cc @@ -54,6 +54,7 @@ namespace { BOOST_AUTO_UNIT_TEST(clientSocketHandle) { + BOOST_CHECKPOINT("Constructing socket handle"); MySocketHandle myh; // conversion to other socket handles @@ -65,12 +66,14 @@ BOOST_AUTO_UNIT_TEST(clientSocketHandle) >::policy OtherSocketPolicy; typedef sl::SocketHandle<OtherSocketPolicy> OtherSocketHandle; + BOOST_CHECKPOINT("Copy-constructing socket handle"); OtherSocketHandle osh (myh); + BOOST_CHECKPOINT("Assigning socket handle"); osh = myh; typedef sl::ClientSocketHandle<sl::test::SomeProtocol::Policy> SomeSocketHandle; + BOOST_CHECKPOINT("static_casting socket handle"); SomeSocketHandle ssh = sl::static_socket_cast<SomeSocketHandle>(osh); - BOOST_CHECK_NO_THROW( sl::dynamic_socket_cast<SomeSocketHandle>(osh) ); typedef sl::ClientSocketHandle<sl::MakeSocketPolicy< OtherSocketPolicy, @@ -81,48 +84,48 @@ BOOST_AUTO_UNIT_TEST(clientSocketHandle) } // reading and writing - BOOST_CHECK_EQUAL( myh.read(), "TEST-READ" ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.read(), "TEST-READ" ) ); { std::string buf("FOO-BAR"); - myh.read(buf); + BOOST_CHECK_NO_THROW( myh.read(buf) ); BOOST_CHECK_EQUAL( buf, "TEST-READ" ); } { char buf[11]; ::strcpy(buf,"0123456789"); - BOOST_CHECK_EQUAL( myh.read(buf,10), 9u ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.read(buf,10), 9u ) ); BOOST_CHECK_EQUAL( buf, "TEST-READ9" ); } - BOOST_CHECK_EQUAL( myh.readfrom().first, "TEST-READ" ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.readfrom().first, "TEST-READ" ) ); { std::string buf("FOO-BAR"); unsigned addr; - myh.readfrom(buf,addr); + BOOST_CHECK_NO_THROW( myh.readfrom(buf,addr) ); BOOST_CHECK_EQUAL( buf, "TEST-READ" ); } { char buf[11]; unsigned addr; ::strcpy(buf,"0123456789"); - BOOST_CHECK_EQUAL( myh.readfrom(buf,10,addr), 9u ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.readfrom(buf,10,addr), 9u ) ); BOOST_CHECK_EQUAL( buf, "TEST-READ9" ); } - BOOST_CHECK_EQUAL( myh.write("TEST-WRITE"), 10u ); - BOOST_CHECK_EQUAL( myh.write("TEST"), 0u ); - BOOST_CHECK_EQUAL( myh.write("TEST-WRITE9",10), 10u ); - BOOST_CHECK_EQUAL( myh.writeto(0,"TEST-WRITE"), 10u ); - BOOST_CHECK_EQUAL( myh.writeto(0,"TEST-WRITE9",10), 10u ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.write("TEST-WRITE"), 10u ) ); + BOOST_CHECK_THROW( myh.write("TEST"),satcom::lib::SystemException ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.write("TEST-WRITE9",10), 10u ) ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.writeto(0,"TEST-WRITE"), 10u ) ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.writeto(0,"TEST-WRITE9",10), 10u ) ); BOOST_CHECK_NO_THROW( myh.connect(0) ); BOOST_CHECK_NO_THROW( myh.bind(0) ); - BOOST_CHECK_EQUAL( myh.peer(), 1u ); - BOOST_CHECK_EQUAL( myh.local(), 2u ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.peer(), 1u ) ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.local(), 2u ) ); - BOOST_CHECK_EQUAL( myh.rcvbuf(), 0u ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.rcvbuf(), 0u ) ); BOOST_CHECK_NO_THROW( myh.rcvbuf(1) ); - BOOST_CHECK_EQUAL( myh.sndbuf(), 0u ); + BOOST_CHECK_NO_THROW( BOOST_CHECK_EQUAL( myh.sndbuf(), 0u ) ); BOOST_CHECK_NO_THROW( myh.sndbuf(1) ); }