switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Socket / Protocols / BSDSocketAddress.cci
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief BSDSocketAddress inline non-template implementation */
30
31 //#include "BSDSocketAddress.ih"
32
33 // Custom includes
34 #include <memory.h>
35 #include <algorithm>
36 #include <typeinfo>
37
38 #define prefix_ inline
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42 // senf::BSDSocketAddress
43
44 prefix_ struct sockaddr const * senf::BSDSocketAddress::sockaddr_p()
45     const
46 {
47     return static_cast<GenericBSDSocketAddress const *>(this)->sockaddr_p();
48 }
49
50 prefix_ short senf::BSDSocketAddress::family()
51     const
52 {
53     return sockaddr_p()->sa_family;
54 }
55
56 prefix_ socklen_t senf::BSDSocketAddress::socklen()
57     const
58 {
59     return len_;
60 }
61
62 prefix_ socklen_t const * senf::BSDSocketAddress::socklen_p()
63     const
64 {
65     return & len_;
66 }
67
68 prefix_ void senf::BSDSocketAddress::socklen(socklen_t len)
69 {
70     len_ = len;
71 }
72
73 prefix_ bool senf::BSDSocketAddress::operator==(BSDSocketAddress const & other)
74     const
75 {
76     return socklen()==other.socklen() && memcmp(sockaddr_p(), other.sockaddr_p(), socklen())==0;
77 }
78
79 prefix_ bool senf::BSDSocketAddress::operator<(BSDSocketAddress const & other)
80     const
81 {
82     if (socklen() < other.socklen()) return true;
83     else if (socklen() > other.socklen()) return false;
84     else return memcmp(sockaddr_p(), other.sockaddr_p(), socklen()) < 0;
85 }
86
87 prefix_ bool senf::BSDSocketAddress::boolean_test()
88     const
89 {
90     return socklen() > sizeof(short) && family() != AF_UNSPEC &&
91         unsigned(std::count(reinterpret_cast<unsigned char const *>(sockaddr_p())+sizeof(short),
92                             reinterpret_cast<unsigned char const *>(sockaddr_p())+socklen(),
93                    0u)) < socklen()-2;
94 }
95
96 //-/////////////////////////////////////////////////////////////////////////////////////////////////
97 // protected members
98
99 prefix_ senf::BSDSocketAddress::BSDSocketAddress(socklen_t len, short family)
100     : len_ (len)
101 {
102     ::memset(sockaddr_p(), 0u, len_);
103     sockaddr_p()->sa_family = family;
104 }
105
106 // WARNING: THIS COPY CONSTRUCTOR IS NOT GENERALLY SAFE !!!!!!
107 // It is only safe if:
108 // a) source and target class are identical derived classes (e.g. Both INet4)
109 // b) target is GenericBSDSocketAddress (sockaddr_storage).
110 //
111 // In these cases, the storage space available for the target is at least as large as that
112 // available for the source ant the copy is ok.
113 //
114 // To ensure this behavior, the copy constructor is protected here and is made accessible only
115 // via the corresponding derived classes.
116 //
117 // The same holds for the copy-assignment operator
118 prefix_ senf::BSDSocketAddress::BSDSocketAddress(BSDSocketAddress const & other)
119     : len_ (other.socklen())
120 {
121     ::memcpy(sockaddr_p(), other.sockaddr_p(), len_);
122 }
123
124 prefix_ senf::BSDSocketAddress &
125 senf::BSDSocketAddress::operator=(BSDSocketAddress const & other)
126 {
127     len_ = other.socklen();
128     ::memmove(sockaddr_p(), other.sockaddr_p(), len_);
129     return *this;
130 }
131
132
133 prefix_ struct sockaddr * senf::BSDSocketAddress::sockaddr_p()
134 {
135     return static_cast<GenericBSDSocketAddress *>(this)->sockaddr_p();
136 }
137
138 prefix_ socklen_t * senf::BSDSocketAddress::socklen_p()
139 {
140     return & len_;
141 }
142
143 //-/////////////////////////////////////////////////////////////////////////////////////////////////
144 // related
145
146 template <class Target>
147 prefix_ Target & senf::sockaddr_cast(BSDSocketAddress & source)
148 {
149     if (source.family() != Target::addressFamily)
150         throw std::bad_cast();
151     return static_cast<Target &>(source);
152 }
153
154 template <class Target>
155 prefix_ Target const & senf::sockaddr_cast(BSDSocketAddress const & source)
156 {
157     if (source.family() != Target::addressFamily)
158         throw std::bad_cast();
159     return static_cast<Target const &>(source);
160 }
161
162 //-/////////////////////////////////////////////////////////////////////////////////////////////////
163 // senf::GenericBSDSocketAddress
164
165 prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress()
166     : BSDSocketAddress(sizeof(sockaddr_storage), AF_UNSPEC)
167 {}
168
169 prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress(BSDSocketAddress const & other)
170     : BSDSocketAddress(other)
171 {}
172
173 prefix_ senf::GenericBSDSocketAddress&
174 senf::GenericBSDSocketAddress::operator=(const BSDSocketAddress & other)
175 {
176     BSDSocketAddress::operator=(other);
177     return *this;
178 }
179
180 prefix_
181 senf::GenericBSDSocketAddress::GenericBSDSocketAddress(const GenericBSDSocketAddress& other)
182     : BSDSocketAddress(other)
183 {}
184
185 prefix_ senf::GenericBSDSocketAddress&
186 senf::GenericBSDSocketAddress::operator=(const GenericBSDSocketAddress& other)
187 {
188     BSDSocketAddress::operator=(other);
189     return *this;
190 }
191
192 prefix_ struct sockaddr const * senf::GenericBSDSocketAddress::sockaddr_p()
193     const
194 {
195     return static_cast<struct sockaddr const *>(static_cast<void const *>(& addr_));
196 }
197
198 prefix_ struct sockaddr * senf::GenericBSDSocketAddress::sockaddr_p()
199 {
200     return static_cast<struct sockaddr *>(static_cast<void *>(& addr_));
201 }
202
203 //-/////////////////////////////////////////////////////////////////////////////////////////////////
204 #undef prefix_
205
206 \f
207 // Local Variables:
208 // mode: c++
209 // fill-column: 100
210 // comment-column: 40
211 // c-file-style: "senf"
212 // indent-tabs-mode: nil
213 // ispell-local-dictionary: "american"
214 // compile-command: "scons -u test"
215 // End: