// $Id$
//
-// Copyright (C) 2006
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+// Copyright (C) 2006
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
//
// 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
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief senf::SocketHandle internal header
+ \brief SocketHandle internal header
*/
-#ifndef IH_SocketHandle_
-#define IH_SocketHandle_ 1
+#ifndef IH_SENF_Socket_SocketHandle_
+#define IH_SENF_Socket_SocketHandle_ 1
// Custom includes
#include <map>
namespace detail {
- /** \brief String supporting automatic type conversion
-
- The ConvertibleString class is used to simplify creating a text representation of
- arbitrary values. ConvertibleString is an ordinary string with an additional constructor
- which allows constructing the string from any arbitrary, streamable type.
-
- \note It is generally not advisable to derive from the standard library container
- classes. However, in this concrete case, the derivation is safe since only the
- additional functionality is added. It is absolutely safe to convert the derived class
- back to the base type.
- */
- class ConvertibleString : public std::string
+ /** \brief String supporting automatic type conversion
+
+ The StreamableString class is used to simplify creating a text representation of
+ arbitrary values. StreamableString is an ordinary string with an additional constructor
+ which allows constructing the string from any arbitrary, streamable type.
+
+ \note It is generally not advisable to derive from the standard library container
+ classes. However, in this concrete case, the derivation is safe since only the
+ additional functionality is added. It is absolutely safe to convert the derived class
+ back to the base type.
+ */
+ class StreamableString : public std::string
{
public:
- ConvertibleString();
- ConvertibleString(bool v); ///< Bool conversion constructor
- /**< The bool conversion is defined explicitly to use a
- specialized representation (the strings 'true' and
- 'false') */
+ using std::string::operator=;
+
template <class T>
- ConvertibleString(T const & other);
- ///< Conversion constructor
- /**< This constructor will assign the string from any
- arbitrary type. It will use boost::lexical_cast to
- convert the argument to its string representation. */
-
- template <class T>
- ConvertibleString & operator+= (ConvertibleString const & other);
- ///< Add additional values with separator
- /**< This operator facilitates the representation of
- multiple values in a single string. Each value is first
- converted to a string (using the type conversion
- machinery of C++ and the ConvertibleString conversion
- constructors). It is then appended to the current string
- with ', ' as a separator (if the current string is
- non-empty). */
- };
-
- /** \brief Special ordering for the SocketStateMap
- \internal
-
- This special ordering will sort 'hierarchical' strings correctly. A hierarchical string
- in this context is a string like a path- or hostname with '.' as the hierarchical
- separator.
- */
- struct StateMapOrdering
- : public std::binary_function<std::string,std::string,bool>
- {
- bool operator()(std::string const & a1, std::string const & a2) const;
- };
+ StreamableString & operator<<(T const & other);
+ ///< Value assigment
+ /**< This operator will assign the string from any
+ arbitrary type. It will use boost::lexical_cast to
+ convert the argument to its string representation.
+
+ If the string is non-empty, an additional separating
+ comma is added to the string. */
+
+ StreamableString & operator<<(bool v); ///< Bool assignment
+ /**< The bool assignment is defined explicitly to use a
+ specialized representation (the strings 'true' and
+ 'false'). */
+ };
}
- typedef std::map< std::string, detail::ConvertibleString, detail::StateMapOrdering > SocketStateMap;
+ typedef std::map< std::string, detail::StreamableString > SocketStateMap;
namespace detail {
- /** \brief Helper to convert SocketStateMap to multiline string representation
- \internal
- */
- std::string dumpState(SocketStateMap const & map);
+ /** \brief Helper to convert SocketStateMap to multiline string representation
+ \internal
+ */
+ std::string dumpState(SocketStateMap const & map);
}
- /** \brief senf::SocketHandle referenced body
-
- \internal
+ template <class Policy, class Self> class ConcreteSocketProtocol;
+
+ /** \brief SocketHandle referenced body
- senf::SocketBody is the extended (relatively to senf::FileBody) body of
- senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
- FileBody). The casting and conversion operators defined will ensure this if used
- properly. If this invariant is violated, your Program will probably crash.
+ \internal
+
+ senf::SocketBody is the extended (relatively to senf::FileBody) body of
+ senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
+ FileBody). The casting and conversion operators defined will ensure this if used
+ properly. If this invariant is violated, your Program will probably crash.
*/
class SocketBody
- : public FileBody
+ : public FileBody
{
public:
- ///////////////////////////////////////////////////////////////////////////
- // Types
-
- typedef boost::intrusive_ptr<SocketBody> ptr;
-
- ///////////////////////////////////////////////////////////////////////////
- ///\name Structors and default members
- ///@{
-
- SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
- /**<
- \param protocol Protocol class implementing the desired
- protocol
- \param isServer \c true, if this socket is a server
- socket, false otherwise */
- SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
- /**<
- \param protocol Protocol class implementing the desired
- protocol
- \param isServer \c true, if this socket is a server
- socket, false otherwise
- \param fd socket file descriptor */
-
- // no copy
- // no conversion constructors
-
- ///@}
- ///////////////////////////////////////////////////////////////////////////
-
- SocketProtocol const & protocol() const;
- ///< Access the protocol instance
- bool isServer(); ///< Check socket type
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ typedef boost::intrusive_ptr<SocketBody> ptr;
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///@{
+
+ SocketBody(bool isServer); /**< \param isServer \c true, if this socket is a server
+ socket, false otherwise */
+ SocketBody(bool isServer, int fd);
+ /**< \param isServer \c true, if this socket is a server
+ socket, false otherwise
+ \param fd socket file descriptor */
+
+ // no copy
+ // no conversion constructors
+
+ ///@}
+ ///////////////////////////////////////////////////////////////////////////
+
+ SocketProtocol & protocol() const; ///< Access the protocol instance
+
+ bool isServer(); ///< Check socket type
/**< \return \c true, if this is a server socket, \c false
- otherwise */
+ otherwise */
+
+ void state(SocketStateMap & map, unsigned lod);
- void state(SocketStateMap & map, unsigned lod);
+ std::auto_ptr<SocketBody> clone(bool isServer) const;
+ std::auto_ptr<SocketBody> clone(int fd, bool isServer) const;
private:
- virtual void v_close(); ///< Close socket
+ virtual void v_close(); ///< Close socket
/**< This override will automatically \c shutdown() the
- socket whenever it is closed.
- \throws senf::SystemException */
- virtual void v_terminate(); ///< Forcibly close socket
+ socket whenever it is closed.
+ \throws senf::SystemException */
+ virtual void v_terminate(); ///< Forcibly close socket
/**< This override will automatically \c shutfown() the
- socket whenever it is called. Additionally it will
- disable SO_LINGER to ensure, that v_terminate will not
- block. Like the overriden method, this member will ignore
- failures and will never throw. It therefore safe to be
- called from a destructor. */
- virtual bool v_eof() const; ///< Check for eof condition
+ socket whenever it is called. Additionally it will
+ disable SO_LINGER to ensure, that v_terminate will not
+ block. Like the overriden method, this member will ignore
+ failures and will never throw. It therefore safe to be
+ called from a destructor. */
+ virtual bool v_eof() const; ///< Check for eof condition
/**< Since the eof check for sockets is very protocol
- dependent, this member will forward the call to
- senf::SocketPolicy::eof() */
+ dependent, this member will forward the call to
+ senf::SocketPolicy::eof() */
+
+ virtual SocketProtocol const & v_protocol() const = 0;
+ virtual std::string v_protocolName() const = 0;
+
+ bool isServer_;
+ };
- boost::scoped_ptr<SocketProtocol> protocol_;
- bool isServer_;
+ template <class SProtocol>
+ class ProtocolSocketBody
+ : public SocketBody,
+ private SProtocol,
+ public senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >
+ {
+ public:
+ typedef SProtocol Protocol;
+
+ using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator new;
+ using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator delete;
+
+ ProtocolSocketBody(bool isServer); /**< \param isServer \c true, if this socket is a server
+ socket, false otherwise */
+ ProtocolSocketBody(bool isServer, int fd);
+ /**< \param isServer \c true, if this socket is a server
+ socket, false otherwise
+ \param fd socket file descriptor */
+
+ private:
+ virtual SocketProtocol const & v_protocol() const;
+ virtual std::string v_protocolName() const;
+
+ friend class ConcreteSocketProtocol<typename SProtocol::Policy, SProtocol>;
};
}
\f
// Local Variables:
// mode: c++
-// c-file-style: "senf"
// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
// End: