Renamed namespaces satcom::lib and satcom::pkf to senf
[senf.git] / Socket / SocketHandle.cc
1 // $Id$
2 //
3 // Copyright (C) 2006 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 // Definition of non-inline non-template functions
24
25 #include "SocketHandle.hh"
26 #include "SocketHandle.ih"
27
28 // Custom includes
29 #include <sstream>
30 #include <sys/socket.h>
31 #include "Utils/TypeInfo.hh"
32
33 //#include "SocketHandle.mpp"
34 #define prefix_
35 ///////////////////////////////cc.p////////////////////////////////////////
36
37 prefix_ void senf::SocketBody::v_close()
38 {
39     if (::shutdown(fd(),SHUT_RDWR) < 0)
40         throw SystemException(errno);
41     if (::close(fd()) < 0)
42         throw SystemException(errno);
43 }
44
45 prefix_ void senf::SocketBody::v_terminate()
46 {
47     struct linger ling;
48     ling.l_onoff = 0;
49     ling.l_linger = 0;
50
51     // We purposely IGNORE any errors: this method is used to try and
52     // terminate the connection ignoring any possible problems
53
54     ::setsockopt(fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling));
55     ::shutdown(fd(),SHUT_RDWR);
56     ::close(fd());
57 }
58
59 prefix_ bool senf::SocketBody::v_eof()
60     const
61 {
62     return protocol().eof();
63 }
64
65 prefix_ void senf::SocketBody::state(SocketStateMap & map, unsigned lod)
66 {
67     map["file.handle"] = fd();
68     map["file.refcount"] = refcount();
69     map["socket.server"] = isServer();
70     map["socket.protocol"] = prettyName(typeid(protocol()));
71     map["socket.policy"] = prettyName(typeid(protocol().policy()));
72     protocol().state(map,lod);
73 }
74
75 ///////////////////////////////////////////////////////////////////////////
76 // senf::detail::StateMapOrdering
77
78 namespace {
79     bool contains(std::string::iterator b, std::string::iterator e, char c)
80     {
81         for (; b != e; ++b)
82             if (*b == c)
83                 return true;
84         return false;
85     }
86 }
87
88 prefix_ bool senf::detail::StateMapOrdering::operator()(std::string a1, std::string a2)
89     const
90 {
91     std::string::iterator i1 (a1.begin());
92     std::string::iterator const i1_end (a1.end());
93     std::string::iterator i2 (a2.begin());
94     std::string::iterator const i2_end (a2.end());
95     for(; i1 != i1_end && i2 != i2_end && *i1 == *i2; ++i1, ++i2) ;
96     if (i1 == i1_end) {
97         if (i2 == i2_end)
98             // the strings are equal
99             return false;
100         if (contains(i2,i2_end,'.'))
101             // the longer string is a sub-'directory' of the shorter
102             // FIXME: shouldn't this be *i2 == '.' ?
103             return true;
104         return *i1 < *i2;
105     }
106     else if (i2 == i2_end) { // && i1 != i1_end
107         if (contains(i1,i1_end,'.'))
108             // the longer string is a sub-'directory' of the shorter
109             // FIXME: shouldn't this be *i1 == '.' ?
110             return false;
111         return *i1 < *i2;
112     }
113     if (contains(i1,i1_end,'.')) {
114         if (contains(i2,i2_end,'.'))
115             return *i1 < *i2;
116         return false;
117     }
118     else if (contains(i2,i2_end,'.'))
119         return true;
120     return *i1 < *i2;
121 }
122
123 prefix_ std::string senf::detail::dumpState(SocketStateMap const & map)
124 {
125     std::stringstream s;
126     SocketStateMap::const_iterator i (map.begin());
127     SocketStateMap::const_iterator i_end (map.end());
128     for (; i != i_end; ++i)
129         s << i->first << ": " << i->second << "\n";
130     return s.str();
131 }
132
133 template <class Policy>
134 prefix_ std::ostream & senf::operator<<(std::ostream & os, SocketHandle<Policy> handle)
135 {
136     os << handle.dumpState();
137     return os;
138 }
139
140 ///////////////////////////////cc.e////////////////////////////////////////
141 #undef prefix_
142 //#include "SocketHandle.mpp"
143
144 \f
145 // Local Variables:
146 // mode: c++
147 // c-file-style: "senf"
148 // End: