Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Directories
  • File List
  • File Members

SocketHandle.cti

Go to the documentation of this file.
00001 // $Id: SocketHandle.cti 1772 2011-03-10 12:45:21Z tho $
00002 //
00003 // Copyright (C) 2006
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00027 #include "SocketHandle.ih"
00028 
00029 // Custom includes
00030 #include <typeinfo>
00031 #include <senf/Utils/senfassert.hh>
00032 #include <senf/Utils/TypeInfo.hh>
00033 
00034 #define prefix_ inline
00035 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00036 
00037 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00038 // senf::SocketHandle<SPolicy>
00039 
00040 template <class SPolicy>
00041 prefix_ senf::SocketHandle<SPolicy>::SocketHandle()
00042 {}
00043 
00044 template <class SPolicy>
00045 template <class OtherPolicy>
00046 prefix_ senf::SocketHandle<SPolicy>::SocketHandle(SocketHandle<OtherPolicy> other,
00047                                                   typename IsCompatible<OtherPolicy>::type *)
00048     : FileHandle(other)
00049 {}
00050 
00051 template <class SPolicy>
00052 template <class OtherPolicy>
00053 prefix_ typename senf::SocketHandle<SPolicy>::template IsCompatible<OtherPolicy>::type const &
00054 senf::SocketHandle<SPolicy>::operator=(SocketHandle<OtherPolicy> other)
00055 {
00056     assign(other);
00057     return *this;
00058 }
00059 
00060 template <class SPolicy>
00061 prefix_
00062 senf::SocketHandle<SPolicy>::SocketHandle(std::auto_ptr<SocketBody> body)
00063     : FileHandle(std::auto_ptr<FileBody>(body.release()))
00064 {}
00065 
00066 template <class SPolicy>
00067 prefix_ senf::SocketHandle<SPolicy>::SocketHandle(FileHandle other, bool isChecked)
00068     : FileHandle(other)
00069 {
00070     SENF_ASSERT( isChecked, "Internal failure: Wrong overload called !!" );
00071     SENF_ASSERT( ! valid() || dynamic_cast<SocketBody *>(&FileHandle::body()),
00072                  "Internal failure: Replacing or re-assigning non-empty incompatible handle");
00073 }
00074 
00075 template <class SPolicy>
00076 prefix_ senf::SocketBody & senf::SocketHandle<SPolicy>::body()
00077 {
00078     SENF_ASSERT( dynamic_cast<SocketBody *>(&FileHandle::body()),
00079                  "Internal failure: Invalid body found it's way into SocketHandle");
00080     return static_cast<SocketBody &>(FileHandle::body());
00081 }
00082 
00083 template <class SPolicy>
00084 prefix_ senf::SocketBody const & senf::SocketHandle<SPolicy>::body()
00085     const
00086 {
00087     SENF_ASSERT( dynamic_cast<SocketBody const *>(&FileHandle::body()),
00088                  "Internal failure: Invalid body found it's way into SocketHandle");
00089     return static_cast<SocketBody const &>(FileHandle::body());
00090 }
00091 
00092 template <class SPolicy>
00093 prefix_ senf::SocketProtocol & senf::SocketHandle<SPolicy>::protocol()
00094     const
00095 {
00096     return body().protocol();
00097 }
00098 
00099 template <class SPolicy>
00100 prefix_ void senf::SocketHandle<SPolicy>::assign(FileHandle other)
00101 {
00102     FileHandle::operator=(other);
00103 }
00104 
00105 template <class SPolicy>
00106 prefix_ senf::SocketHandle<SPolicy>
00107 senf::SocketHandle<SPolicy>::cast_static(FileHandle handle)
00108 {
00109     return SocketHandle(handle,true);
00110 }
00111 
00112 template <class SPolicy>
00113 prefix_ senf::SocketHandle<SPolicy>
00114 senf::SocketHandle<SPolicy>::cast_dynamic(FileHandle handle)
00115 {
00116     // throws bad_cast if the body is not a SocketBody
00117     SocketBody & body (dynamic_cast<SocketBody&>(FileHandle::body(handle)));
00118     // throws bad_cast if the policy is not compatible (already wrapped ...)
00119     SPolicy::checkBaseOf(body.protocol().policy());
00120     return cast_static(handle);
00121 }
00122 
00123 template <class Target, class Source>
00124 prefix_ Target senf::static_socket_cast(Source handle)
00125 {
00126     BOOST_STATIC_ASSERT((
00127         boost::is_convertible<Source*,FileHandle*>::value &&
00128         boost::is_convertible<Target*,FileHandle*>::value &&
00129         ( boost::is_convertible<Source,Target>::value ||
00130           boost::is_convertible<Target,Source>::value ) ));
00131     SENF_ASSERT( check_socket_cast<Target>(handle),
00132                  "Invalid static_socket_cast" );
00133     return Target::cast_static(handle);
00134 }
00135 
00136 template <class Target, class Source>
00137 prefix_ Target senf::dynamic_socket_cast(Source handle)
00138 {
00139 //     BOOST_STATIC_ASSERT((
00140 //         boost::is_convertible<Source*,FileHandle*>::value &&
00141 //         boost::is_convertible<Target*,FileHandle*>::value &&
00142 //         ( boost::is_convertible<Source,Target>::value ||
00143 //           boost::is_convertible<Target,Source>::value ) ));
00144     try {
00145         return Target::cast_dynamic(handle);
00146     }
00147     SENF_WRAP_EXC(std::bad_cast)
00148 }
00149 
00150 template <class Target, class Source>
00151 prefix_ bool senf::check_socket_cast(Source handle)
00152 {
00153 //     BOOST_STATIC_ASSERT((
00154 //         boost::is_convertible<Source*,FileHandle*>::value &&
00155 //         boost::is_convertible<Target*,FileHandle*>::value &&
00156 //         ( boost::is_convertible<Source,Target>::value ||
00157 //           boost::is_convertible<Target,Source>::value ) ));
00158     // we don't have a non-throwing variant of cast_dynamic
00159     // for two reasons:
00160     // a) since the handle is passed back by value, we cannot return
00161     //    something like a null handle
00162     // b) it is simpler to implement cast_dynamic throwig bad_cast on
00163     //    failure than implementing cast_check
00164     try {
00165         Target::cast_dynamic(handle);
00166     }
00167     catch (std::bad_cast const &) {
00168         return false;
00169     }
00170     return true;
00171 }
00172 
00173 template <class SPolicy>
00174 prefix_ void senf::SocketHandle<SPolicy>::state(SocketStateMap & map, unsigned lod)
00175 {
00176     // We use typeid here even though the type of *this is static
00177     // (SocketHandle is not polymorphic and has no vtable). This will
00178     // automatically include the SocketPolicy template parameter in
00179     // the type name and therefore show the \e static policy of the
00180     // socket handle.
00181     map["handle"] << prettyName(typeid(*this));
00182     if (valid()) {
00183         map["valid"] << "true";
00184         body().state(map,lod);
00185     } else
00186         map["valid"] << "false";
00187 }
00188 
00189 template <class SPolicy>
00190 prefix_ std::string senf::SocketHandle<SPolicy>::dumpState(unsigned lod)
00191 {
00192     SocketStateMap map;
00193     state(map,lod);
00194     return detail::dumpState(map);
00195 }
00196 
00197 template <class SPolicy>
00198 template <class Facet>
00199 prefix_ Facet & senf::SocketHandle<SPolicy>::facet()
00200 
00201 {
00202     try {
00203         return dynamic_cast<Facet &>(protocol());
00204     }
00205     SENF_WRAP_EXC(std::bad_cast)
00206 }
00207 
00208 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00209 // senf::ProtocolSocketBody<SProtocol>
00210 
00211 template <class SProtocol>
00212 prefix_ senf::ProtocolSocketBody<SProtocol>::ProtocolSocketBody(bool isServer)
00213     : SocketBody(isServer)
00214 {}
00215 
00216 template <class SProtocol>
00217 prefix_ senf::ProtocolSocketBody<SProtocol>::ProtocolSocketBody(bool isServer, int fd)
00218     : SocketBody(isServer, fd)
00219 {}
00220 
00221 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00222 
00223 template <class SPolicy>
00224 prefix_ std::ostream & senf::operator<<(std::ostream & os, SocketHandle<SPolicy> handle)
00225 {
00226     os << handle.dumpState();
00227     return os;
00228 }
00229 
00230 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00231 #undef prefix_
00232 
00233 
00234 // Local Variables:
00235 // mode: c++
00236 // fill-column: 100
00237 // c-file-style: "senf"
00238 // indent-tabs-mode: nil
00239 // ispell-local-dictionary: "american"
00240 // compile-command: "scons -u test"
00241 // comment-column: 40
00242 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research