// $Id$ // // Copyright (C) 2006 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // 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., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file \brief SocketHandle internal header */ #ifndef IH_SENF_Socket_SocketHandle_ #define IH_SENF_Socket_SocketHandle_ 1 // Custom includes #include #include #include #include "FileHandle.hh" //-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { class SocketProtocol; namespace detail { /** \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: using std::string::operator=; template StreamableString & operator<<(T const & other); ///< Value assignment /**< 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::StreamableString > SocketStateMap; namespace detail { /** \brief Helper to convert SocketStateMap to multiline string representation \internal */ std::string dumpState(SocketStateMap const & map); } template class ConcreteSocketProtocol; /** \brief SocketHandle referenced body \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: //-///////////////////////////////////////////////////////////////////////////////////////// // Types typedef boost::intrusive_ptr 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 */ void state(SocketStateMap & map, unsigned lod); std::auto_ptr clone(bool isServer) const; std::auto_ptr clone(int fd, bool isServer) const; private: 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 /**< This override will automatically \c shutdown() the socket whenever it is called. Additionally it will disable SO_LINGER to ensure, that v_terminate will not block. Like the overridden 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() */ virtual SocketProtocol const & v_protocol() const = 0; virtual std::string v_protocolName() const = 0; bool isServer_; }; template class ProtocolSocketBody : public SocketBody, private SProtocol, public senf::pool_alloc_mixin< ProtocolSocketBody > { public: typedef SProtocol Protocol; using senf::pool_alloc_mixin< ProtocolSocketBody >::operator new; using senf::pool_alloc_mixin< ProtocolSocketBody >::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; }; } //-///////////////////////////////////////////////////////////////////////////////////////////////// #endif // 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: