Move include files in debian packge into 'senf' subdirectory
[senf.git] / Socket / ClientSocketHandle.ct
index 9379c7c..1b8190c 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2006 
+// Copyright (C) 2006
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
 //     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief senf::ClientSocketHandle non-inline template implementation
+    \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,74 +98,60 @@ 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();
-    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());
+    unsigned nread (available());
+    if (limit>0 && nread>limit)
+        nread = limit;
+    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()
 {
     unsigned nread = this->protocol().available();
     if (nread == 0 && this->blocking()) {
-       // We have to block explicitly here so we can return the
-       // number of bytes available explicitly. If no more date can
-       // be expected to arive (i.e. the other end has closed the
-       // connection), the socket will always be in the readable
-       // state. This is the only case when available() will return
-       // 0.
-       this->waitReadable();
-       nread = this->protocol().available();
+        // We have to block explicitly here so we can return the
+        // number of bytes available explicitly. If no more date can
+        // be expected to arive (i.e. the other end has closed the
+        // connection), the socket will always be in the readable
+        // state. This is the only case when available() will return
+        // 0.
+        this->waitReadable();
+        nread = this->protocol().available();
     }
     return nread;
 }
@@ -118,5 +162,10 @@ prefix_ unsigned senf::ClientSocketHandle<Policy>::available()
 \f
 // Local Variables:
 // mode: c++
+// fill-column: 100
 // c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
 // End: