// $Id$ // // Copyright (C) 2006 // Fraunhofer Institute for Open Communication Systems (FOKUS) // // The contents of this file are subject to the Fraunhofer FOKUS Public License // Version 1.0 (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // http://senf.berlios.de/license.html // // The Fraunhofer FOKUS Public License Version 1.0 is based on, // but modifies the Mozilla Public License Version 1.1. // See the full license text for the amendments. // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the License. // // The Original Code is Fraunhofer FOKUS code. // // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. // (registered association), Hansastraße 27 c, 80686 Munich, Germany. // All Rights Reserved. // // Contributor(s): // Stefan Bund /** \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: