Skip to content
Snippets Groups Projects
SocketHandle.cc 4.41 KiB
Newer Older
sbund's avatar
sbund committed
// $Id$
//
// Copyright (C) 2006 
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
//     Stefan Bund <stefan.bund@fokus.fraunhofer.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
// 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.

g0dil's avatar
g0dil committed
/** \file
    \brief senf::SocketHandle non-inline non-template implementation
 */

#include "SocketHandle.hh"
#include "SocketHandle.ih"
sbund's avatar
sbund committed

// Custom includes
#include "Utils/TypeInfo.hh"
//#include "SocketHandle.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ void senf::SocketBody::v_close()
    if (::shutdown(fd(),SHUT_RDWR) < 0)
        throw SystemException(errno);
    if (::close(fd()) < 0)
sbund's avatar
sbund committed
        throw SystemException(errno);
}

prefix_ void senf::SocketBody::v_terminate()
    struct linger ling;
    ling.l_onoff = 0;
    ling.l_linger = 0;

    // We purposely IGNORE any errors: this method is used to try and
    // terminate the connection ignoring any possible problems

    ::setsockopt(fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling));
    ::shutdown(fd(),SHUT_RDWR);
    ::close(fd());
}

prefix_ bool senf::SocketBody::v_eof()
prefix_ void senf::SocketBody::state(SocketStateMap & map, unsigned lod)
    map["file.handle"] = fd();
    map["file.refcount"] = refcount();
    map["socket.server"] = isServer();
    map["socket.protocol"] = prettyName(typeid(protocol()));
    map["socket.policy"] = prettyName(typeid(protocol().policy()));
    protocol().state(map,lod);
}

///////////////////////////////////////////////////////////////////////////
// senf::detail::StateMapOrdering
    bool contains(std::string::const_iterator b, std::string::const_iterator e, char c)
    {
        for (; b != e; ++b)
            if (*b == c)
                return true;
        return false;
    }
}

g0dil's avatar
g0dil committed
prefix_ bool senf::detail::StateMapOrdering::operator()(std::string const & a1,
                                                        std::string const & a2)
    std::string::const_iterator i1 (a1.begin());
    std::string::const_iterator const i1_end (a1.end());
    std::string::const_iterator i2 (a2.begin());
    std::string::const_iterator const i2_end (a2.end());
    for(; i1 != i1_end && i2 != i2_end && *i1 == *i2; ++i1, ++i2) ;
    if (i1 == i1_end) {
        if (i2 == i2_end)
            // the strings are equal
            return false;
        if (contains(i2,i2_end,'.'))
            // the longer string is a sub-'directory' of the shorter
	    /** \fixme shouldn't this be *i2 == '.' ? */
            return true;
        return *i1 < *i2;
    }
    else if (i2 == i2_end) { // && i1 != i1_end
        if (contains(i1,i1_end,'.'))
            // the longer string is a sub-'directory' of the shorter
	    /** \fixme shouldn't this be *i1 == '.' ? */
            return false;
        return *i1 < *i2;
    }
    if (contains(i1,i1_end,'.')) {
        if (contains(i2,i2_end,'.'))
            return *i1 < *i2;
        return false;
    }
    else if (contains(i2,i2_end,'.'))
        return true;
    return *i1 < *i2;
}

prefix_ std::string senf::detail::dumpState(SocketStateMap const & map)
{
    std::stringstream s;
    SocketStateMap::const_iterator i (map.begin());
    SocketStateMap::const_iterator i_end (map.end());
    for (; i != i_end; ++i)
        s << i->first << ": " << i->second << "\n";
    return s.str();
}

template <class Policy>
prefix_ std::ostream & senf::operator<<(std::ostream & os, SocketHandle<Policy> handle)
///////////////////////////////cc.e////////////////////////////////////////
sbund's avatar
sbund committed
#undef prefix_
//#include "SocketHandle.mpp"
sbund's avatar
sbund committed


// Local Variables:
// mode: c++
// c-file-style: "senf"
sbund's avatar
sbund committed
// End: