fb6d60287c6f34b621139858b90247d8186816c2
[senf.git] / senf / Socket / Protocols / BSDSocketAddress.cci
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.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 /** \file
24     \brief BSDSocketAddress inline non-template implementation */
25
26 //#include "BSDSocketAddress.ih"
27
28 // Custom includes
29 #include <memory.h>
30 #include <algorithm>
31 #include <typeinfo>
32
33 #define prefix_ inline
34 //-/////////////////////////////////////////////////////////////////////////////////////////////////
35
36 //-/////////////////////////////////////////////////////////////////////////////////////////////////
37 // senf::BSDSocketAddress
38
39 prefix_ struct sockaddr const * senf::BSDSocketAddress::sockaddr_p()
40     const
41 {
42     return static_cast<GenericBSDSocketAddress const *>(this)->sockaddr_p();
43 }
44
45 prefix_ short senf::BSDSocketAddress::family()
46     const
47 {
48     return sockaddr_p()->sa_family;
49 }
50
51 prefix_ socklen_t senf::BSDSocketAddress::socklen()
52     const
53 {
54     return len_;
55 }
56
57 prefix_ socklen_t const * senf::BSDSocketAddress::socklen_p()
58     const
59 {
60     return & len_;
61 }
62
63 prefix_ void senf::BSDSocketAddress::socklen(socklen_t len)
64 {
65     len_ = len;
66 }
67
68 prefix_ bool senf::BSDSocketAddress::operator==(BSDSocketAddress const & other)
69     const
70 {
71     return socklen()==other.socklen() && memcmp(sockaddr_p(), other.sockaddr_p(), socklen())==0;
72 }
73
74 prefix_ bool senf::BSDSocketAddress::operator<(BSDSocketAddress const & other)
75     const
76 {
77     if (socklen() < other.socklen()) return true;
78     else if (socklen() > other.socklen()) return false;
79     else return memcmp(sockaddr_p(), other.sockaddr_p(), socklen()) < 0;
80 }
81
82 prefix_ bool senf::BSDSocketAddress::boolean_test()
83     const
84 {
85     return socklen() > sizeof(short) && family() != AF_UNSPEC &&
86         unsigned(std::count(reinterpret_cast<unsigned char const *>(sockaddr_p())+sizeof(short),
87                             reinterpret_cast<unsigned char const *>(sockaddr_p())+socklen(),
88                    0u)) < socklen()-2;
89 }
90
91 //-/////////////////////////////////////////////////////////////////////////////////////////////////
92 // protected members
93
94 prefix_ senf::BSDSocketAddress::BSDSocketAddress(socklen_t len, short family)
95     : len_ (len)
96 {
97     ::memset(sockaddr_p(), 0u, len_);
98     sockaddr_p()->sa_family = family;
99 }
100
101 // WARNING: THIS COPY CONSTRUCTOR IS NOT GENERALLY SAFE !!!!!!
102 // It is only safe if:
103 // a) source and target class are identical derived classes (e.g. Both INet4)
104 // b) target is GenericBSDSocketAddress (sockaddr_storage).
105 //
106 // In these cases, the storage space available for the target is at least as large as that
107 // available for the source ant the copy is ok.
108 //
109 // To ensure this behavior, the copy constructor is protected here and is made accessible only
110 // via the corresponding derived classes.
111 //
112 // The same holds for the copy-assignment operator
113 prefix_ senf::BSDSocketAddress::BSDSocketAddress(BSDSocketAddress const & other)
114     : len_ (other.socklen())
115 {
116     ::memcpy(sockaddr_p(), other.sockaddr_p(), len_);
117 }
118
119 prefix_ senf::BSDSocketAddress &
120 senf::BSDSocketAddress::operator=(BSDSocketAddress const & other)
121 {
122     len_ = other.socklen();
123     ::memmove(sockaddr_p(), other.sockaddr_p(), len_);
124     return *this;
125 }
126
127
128 prefix_ struct sockaddr * senf::BSDSocketAddress::sockaddr_p()
129 {
130     return static_cast<GenericBSDSocketAddress *>(this)->sockaddr_p();
131 }
132
133 prefix_ socklen_t * senf::BSDSocketAddress::socklen_p()
134 {
135     return & len_;
136 }
137
138 //-/////////////////////////////////////////////////////////////////////////////////////////////////
139 // related
140
141 template <class Target>
142 prefix_ Target & senf::sockaddr_cast(BSDSocketAddress & source)
143 {
144     if (source.family() != Target::addressFamily)
145         throw std::bad_cast();
146     return static_cast<Target &>(source);
147 }
148
149 template <class Target>
150 prefix_ Target const & senf::sockaddr_cast(BSDSocketAddress const & source)
151 {
152     if (source.family() != Target::addressFamily)
153         throw std::bad_cast();
154     return static_cast<Target const &>(source);
155 }
156
157 //-/////////////////////////////////////////////////////////////////////////////////////////////////
158 // senf::GenericBSDSocketAddress
159
160 prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress()
161     : BSDSocketAddress(sizeof(sockaddr_storage), AF_UNSPEC)
162 {}
163
164 prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress(BSDSocketAddress const & other)
165     : BSDSocketAddress(other)
166 {}
167
168 prefix_ senf::GenericBSDSocketAddress&
169 senf::GenericBSDSocketAddress::operator=(const BSDSocketAddress & other)
170 {
171     BSDSocketAddress::operator=(other);
172     return *this;
173 }
174
175 prefix_
176 senf::GenericBSDSocketAddress::GenericBSDSocketAddress(const GenericBSDSocketAddress& other)
177     : BSDSocketAddress(other)
178 {}
179
180 prefix_ senf::GenericBSDSocketAddress&
181 senf::GenericBSDSocketAddress::operator=(const GenericBSDSocketAddress& other)
182 {
183     BSDSocketAddress::operator=(other);
184     return *this;
185 }
186
187 prefix_ struct sockaddr const * senf::GenericBSDSocketAddress::sockaddr_p()
188     const
189 {
190     return static_cast<struct sockaddr const *>(static_cast<void const *>(& addr_));
191 }
192
193 prefix_ struct sockaddr * senf::GenericBSDSocketAddress::sockaddr_p()
194 {
195     return static_cast<struct sockaddr *>(static_cast<void *>(& addr_));
196 }
197
198 //-/////////////////////////////////////////////////////////////////////////////////////////////////
199 #undef prefix_
200
201 \f
202 // Local Variables:
203 // mode: c++
204 // fill-column: 100
205 // comment-column: 40
206 // c-file-style: "senf"
207 // indent-tabs-mode: nil
208 // ispell-local-dictionary: "american"
209 // compile-command: "scons -u test"
210 // End: