Move include files in debian packge into 'senf' subdirectory
[senf.git] / Socket / ClientSocketHandle.ct
index 17a518e..1b8190c 100644 (file)
     \brief ClientSocketHandle non-inline template implementation
  */
 
-//#include "ClientSocketHandle.ih"
+#include "ClientSocketHandle.ih"
 
 // Custom includes
+#include <algorithm>
+#include "../Utils/Buffer.hh"
 
 #define prefix_
 ///////////////////////////////ct.p////////////////////////////////////////
 
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::ReadRange<Handle,ForwardWritableRange,IsContiguous>
+
+template <class Handle, class ForwardWritableRange, bool IsContiguous>
+prefix_ typename boost::range_iterator<ForwardWritableRange>::type
+senf::detail::ReadRange<Handle,ForwardWritableRange,IsContiguous>::
+read(Handle & handle, ForwardWritableRange & range)
+{
+    typename boost::range_size<ForwardWritableRange>::type nread (boost::size(range));
+    SENF_SCOPED_BUFFER(char, buffer, nread);
+    return std::copy(buffer, handle.read(buffer,buffer+nread), boost::begin(range));
+}
+
+template <class Handle, class ForwardWritableRange, bool IsContiguous>
+prefix_ typename boost::range_iterator<ForwardWritableRange>::type
+senf::detail::ReadRange<Handle,ForwardWritableRange,IsContiguous>::
+readfrom(Handle & handle, ForwardWritableRange & range, typename Handle::Address & addr)
+{
+    typename boost::range_size<ForwardWritableRange>::type nread (boost::size(range));
+    SENF_SCOPED_BUFFER(char, buffer, nread);
+    return std::copy(buffer, handle.readfrom(buffer,buffer+nread,addr), boost::begin(range));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::WriteRange<Handle,ForwardReadableRange,IsContiguous>
+
+template <class Handle, class ForwardReadableRange, bool IsContiguous>
+prefix_ typename boost::range_iterator<ForwardReadableRange>::type
+senf::detail::WriteRange<Handle,ForwardReadableRange,IsContiguous>::
+write(Handle & handle, ForwardReadableRange & range)
+{
+    typename boost::range_size<ForwardReadableRange>::type nwrite (boost::size(range));
+    SENF_SCOPED_BUFFER(char, buffer, nwrite);
+    std::copy(boost::begin(range), boost::end(range), buffer);
+    return handle.write(std::make_pair(buffer, buffer+nwrite));
+}
+
+template <class Handle, class ForwardReadableRange, bool IsContiguous>
+prefix_ typename boost::range_iterator<ForwardReadableRange>::type
+senf::detail::WriteRange<Handle,ForwardReadableRange,IsContiguous>::
+writeto(Handle & handle, ForwardReadableRange & range, typename Handle::Address const & addr)
+{
+    typename boost::range_size<ForwardReadableRange>::type nwrite (boost::size(range));
+    SENF_SCOPED_BUFFER(char, buffer, nwrite);
+    std::copy(boost::begin(range), boost::end(range), buffer);
+    return handle.writeto(std::make_pair(buffer, buffer+nwrite), addr);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::ClientSocketHandle<Policy>
+
+////////////////////////////////////////
+// reading and writing
+
+// senf::ClientSocketHandle<Policy>::read
+
 template <class Policy>
 prefix_ std::string senf::ClientSocketHandle<Policy>::read(unsigned limit)
 {
@@ -40,60 +98,46 @@ prefix_ std::string senf::ClientSocketHandle<Policy>::read(unsigned limit)
 }
 
 template <class Policy>
-prefix_ void senf::ClientSocketHandle<Policy>::read(std::string & buffer, unsigned limit)
+template <class Sequence>
+prefix_ void senf::ClientSocketHandle<Policy>::read(Sequence & container, unsigned limit)
 {
-    unsigned nread = available();
+    unsigned nread (available());
     if (limit>0 && nread>limit)
         nread = limit;
-    /** \fixme This is not necessary correct and more or less a hack ... */
-    buffer.assign(nread,0);
-    unsigned rv = this->read(const_cast<char *>(buffer.data()),nread);
-    if (rv < nread)
-        buffer.erase(buffer.begin()+rv,buffer.end());
+    container.resize(nread);
+    container.erase(read( std::make_pair(container.begin(), container.end()) ), 
+                    container.end());
 }
 
+// senf::ClientSocketHandle<Policy>::readfrom
+
 template <class Policy>
 prefix_ std::pair<std::string, typename Policy::AddressingPolicy::Address>
-senf::ClientSocketHandle<Policy>::readfrom()
+senf::ClientSocketHandle<Policy>::readfrom(unsigned limit)
 {
     std::string rv;
     typename Policy::AddressingPolicy::Address addr;
-    this->readfrom(rv,addr);
+    this->readfrom(rv,addr,limit);
     return std::make_pair(rv,addr);
 }
 
 template <class Policy>
-prefix_ void senf::ClientSocketHandle<Policy>::
-readfrom(std::string & buffer, typename Policy::AddressingPolicy::Address & from)
+template <class Sequence>
+prefix_ void senf::ClientSocketHandle<Policy>::readfrom(Sequence & container, Address & from,
+                                                        unsigned limit)
 {
-    unsigned nread = available();
-    /** \fixme This is not necessary correct and more or less a hack ... */
-    buffer.assign(nread,0);
-    unsigned rv = this->readfrom(const_cast<char *>(buffer.data()), nread, from);
-    if (rv < nread)
-        buffer.erase(buffer.begin()+rv,buffer.end());
+    unsigned nread (available());
+    if (limit>0 && nread>limit)
+        nread = limit;
+    container.resize(nread);
+    container.erase(readfrom( std::make_pair(container.begin(), container.end()), from ), 
+                    container.end());
 }
 
-template <class Policy>
-prefix_ unsigned senf::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;
-}
+////////////////////////////////////////
+// private members
+
+// senf::ClientSocketHandle<Policy>::available
 
 template <class Policy>
 prefix_ unsigned senf::ClientSocketHandle<Policy>::available()
@@ -122,4 +166,6 @@ prefix_ unsigned senf::ClientSocketHandle<Policy>::available()
 // c-file-style: "senf"
 // indent-tabs-mode: nil
 // ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
 // End: