X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FSocketHandle.hh;h=3f3f88ca58417accfb9e651cbffb523d0105afab;hb=9a988902090d28007578e93bffd809f6bd913155;hp=9c1fd1c4dbad4051b525ba0b53da55c96e03bfab;hpb=ac6a813d9d99f7add4e13aff7a4bcd314d5604a6;p=senf.git diff --git a/Socket/SocketHandle.hh b/Socket/SocketHandle.hh index 9c1fd1c..3f3f88c 100644 --- a/Socket/SocketHandle.hh +++ b/Socket/SocketHandle.hh @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2006 +// Copyright (C) 2006 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) // Kompetenzzentrum fuer Satelitenkommunikation (SatCom) // Stefan Bund @@ -20,9 +20,9 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// TODO: Create a SocketHandleBase class and move some non-Policy -// dependent code there - +/** \file + \brief SocketHandle public header + */ #ifndef HH_SocketHandle_ #define HH_SocketHandle_ 1 @@ -39,9 +39,30 @@ namespace senf { + /// \addtogroup handle_group + /// @{ + + /** \brief basic SocketHandle supporting protocol and policy abstraction + + The senf::SocketHandle class introduces the two abstraction layers of the socket + library. senf::SocketHandle does \e not provide socket functions it only provides the + infrastructure necessary to support both, the protocol and the policy interface. + + senf::SocketHandle takes the socket policy as a template argument. senf::SocketHandle also + introduces the protocol class. However, the class has no public constructors (see the + derived classes senf::ProtocolClientSocketHandle and senf::ProtocolServerSocketHandle). + + The most important functionality provided by senf::SocketHandle is the conversion + constructor. This allows to implicitly convert between compatible socket handle types as + specified by the socket policy. The conversion constructor is defined in such a way, that + only valid conversions are possible (see the implementation source for a more complete + discussion). - /** \brief - */ + \note This class is \e not meant to be used as a base-class outside the library + implementation; The protected interface is for internal use only. + + \todo Create a SocketHandleBase class and move some non-Policy dependent code there + */ template class SocketHandle : public FileHandle @@ -52,6 +73,12 @@ namespace senf { typedef SocketPolicy Policy; + /** \brief Check policy compatibility + + IsCompatible is a template meta-function which will check some other socket policy for + conversion compatibility. This check is used in the senf::SocketPolicy implementation to + restrict the conversion operator. + */ template struct IsCompatible : public boost::enable_if< SocketPolicyIsBaseOf, @@ -67,47 +94,155 @@ namespace senf { // default destructor // conversion constructors + template - SocketHandle(SocketHandle other, + SocketHandle(SocketHandle other, typename IsCompatible::type * = 0); + ///< Convert from other socket handle checking policy + ///< compatibility ///@} /////////////////////////////////////////////////////////////////////////// template typename IsCompatible::type const & operator=(SocketHandle other); - - static SocketHandle cast_static(FileHandle handle); - static SocketHandle cast_dynamic(FileHandle handle); + ///< Assign from other socket handle checking policy + ///< compatibility void state(SocketStateMap & map, unsigned lod=0); + ///< Inquire state information of socket handle + /**< The map argument (a string to string mapping) will be + filled with information covering the current state of + the socket. The information provided depends on the + socket protocol. The amount of information returned can + be controlled using the \p lod value. + + See senf::SocketProtocol::state() for more information, + how the Information is generated. + + \param map string to string mapping to be filled with + state information + \param lod level of detail requested. The interpretation + of this value is protocol specific + + \implementation This member will be re-implemented in + every derived class. This is very important since + state() is \e not a virtual function (which we + don't want since we don't want to add a vtable + pointer to every handle instance). */ std::string dumpState(unsigned lod=0); + ///< Format complete state information as string + /**< Formats the complete state map value and returns it as + a single multi-line string. + + \implementation This member will be re-implemented in + every derived class. See the state() + documentation. */ protected: explicit SocketHandle(std::auto_ptr protocol, bool isServer); + ///< Initialize SocketHandle providing the protocol + /**< \param protocol Protocol class of the protocol + implemented by this socket handle + \param isServer \c true, if this SobcketHandle instance + implements a server handle, \c false otherwise */ SocketHandle(FileHandle other, bool isChecked); - - SocketBody & body(); - SocketBody const & body() const; + ///< Initialize SocketHandle from arbitrary checked + ///< FileHandle + /**< This constructor is used to support up- and downcasting + of SocketHandle instances. + + \warning It is absolutely necessary to ensure, that the + FileHandle passed in is \e really a SocketHandle + holding a SocketBody (and not a simple FileBody) + instance. Additionally. the SocketPolicy absolutely + must be compatible. + + \param other FileHandle to assign + \param isChecked has to be \c true + + \todo Answer, why the heck I need the \c isChecked + parameter ?? + */ + + SocketBody & body(); ///< Access socket body + /**< This member replaces the corresponding FileHandle + member and returns an appropriately cast body + reference */ + SocketBody const & body() const; ///< Access socket body in const context + /**< This member replaces the corresponding FileHandle + member and returns an appropriately cast body + reference */ SocketProtocol const & protocol() const; + ///< Access protocol class + + void assign(FileHandle other); /**< \internal */ - void assign(FileHandle other); + public: + static SocketHandle cast_static(FileHandle handle); + /**< \internal */ + static SocketHandle cast_dynamic(FileHandle handle); + /**< \internal */ private: }; + /** \brief Write stream status dump to output stream + + Write senf::SocketHandle::dumpState() to \c os + + \related senf::SocketHandle + */ template std::ostream & operator<<(std::ostream & os, SocketHandle handle); + /** \brief static socket (down-)cast + + This function is like \c static_cast but for socket handles. It allows to downcast any + FileHandle to any SocketHandle (and its derived types). static_socket_cast will \e not check + the validity of the cast, it will assume, that the cast is valid. + + The function will however check, that the cast is possible. Casting between (at compile + time) known incompatible types (like casting a SocketHandle with a communication policy of + ConnectedCommunicationPolicy to a SocketHandle with UnconnectedCommunicationPolicy will fail + at compile time). + + \warning + If the type you cast to is not really a compatible socket handle type you will get undefined + behavior, probably your program will crash (You will get an assertion in debug builds). + + \related senf::SocketHandle + */ template Target static_socket_cast(Source handle); + /** \brief dynamic socket (down-)cast + + This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked + version of static_socket_cast. + + \throws std::bad_cast You have tried to perform an invalid down- or crosscast. + + \related senf::SocketHandle + */ template Target dynamic_socket_cast(Source handle); + /** \brief dynamically check cast validity + + This function will check, whether the given cast is valid. This is the same as checking, that + dynamic_socket_cast does not throw. + + This member is needed, since there is no 'null' SocketHandle (comparable to a null pointer) + which could be returned by a non-throwing variant of dynamic_socket_cast. + + \related senf::SocketHandle + */ template bool check_socket_cast(Source handle); + + /// @} } ///////////////////////////////hh.e//////////////////////////////////////// @@ -119,5 +254,8 @@ namespace senf { // Local Variables: // mode: c++ +// fill-column: 100 // c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" // End: