libutil++  1.9.3
 All Classes Functions Variables
IPAddressPort.cpp
1 /*
2 ** libutil++
3 ** $Id: IPAddressPort.cpp 1664 2016-04-04 03:57:40Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: IPAddressPort.cpp 1664 2016-04-04 03:57:40Z sella $";
10 
11 #include "IPAddressPort.h"
12 #include "../util/String.h"
13 
14 #include <string.h>
15 
16 #define HASH_ALGO_INT1
17 
18 using namespace sella::net;
19 using namespace sella::util;
20 
21 IPAddressPort::IPAddressPort(const IPAddress &address, const Port &port) throw () :
22  hcache(0)
23 {
24  init(address, port);
25 }
26 
27 IPAddressPort::IPAddressPort(const IPAddress &address, const TCPPort &port) throw () :
28  hcache(0)
29 {
30  init(address, (Port) port);
31 }
32 
33 IPAddressPort::IPAddressPort(const IPAddress &address, const UDPPort &port) throw () :
34  hcache(0)
35 {
36  init(address, (Port) port);
37 }
38 
39 IPAddressPort::IPAddressPort(const IPAddress &address, uint16_t port) throw (PortException) :
40  hcache(0)
41 {
42  const Port p(port);
43 
44  init(address, p);
45 }
46 
47 IPAddressPort::IPAddressPort(const std::string &address, uint16_t port) throw (AddressException, PortException) :
48  hcache(0)
49 {
50  std::vector<std::string> matches;
51 
52  std::string aaa = address;
53  std::string pat = "^\\s*(\\[?([0-9\\.]+)\\]?|\\[([0-9A-Z:]+)\\]):([0-9]+)\\s*$";
54 
55  if (String::regex_imatch(aaa, pat, matches)) {
56  const IPAddress a((matches.at(3).empty()) ? matches.at(2) : matches.at(3));
57 
58  if (port > 0) {
59  const Port p(port);
60 
61  init(a, p);
62  } else {
63  const Port p(matches.at(4));
64 
65  init(a, p);
66  }
67  } else if (String::regex_imatch(address, "^\\s*\\[?([0-9\\.]+|[0-9A-Z:]+)\\]?\\s*$", matches)) {
68  const IPAddress a(matches.at(1));
69  const Port p(port);
70 
71  init(a, p);
72  } else {
73  const IPAddress a(address);
74  const Port p(port);
75 
76  init(a, p);
77  }
78 }
79 
80 IPAddressPort::IPAddressPort(const struct sockaddr_storage *ss) throw (AddressException, PortException) :
81  hcache(0)
82 {
83  const IPAddress a(ss);
84  const Port p(ss);
85 
86  init(a, p);
87 }
88 
89 IPAddressPort::IPAddressPort(const struct sockaddr *sa) throw (AddressException, PortException) :
90  hcache(0)
91 {
92  const IPAddress a(sa);
93  const Port p(sa);
94 
95  init(a, p);
96 }
97 
98 IPAddressPort::IPAddressPort(const IPAddressPort &other) throw () :
99  address(other.address),
100  port(other.port),
101  u(other.u),
102  scache(other.scache),
103  hcache(other.hcache)
104 { }
105 
106 IPAddressPort::IPAddressPort(const IPAddressPort &&other) throw () :
107  address(std::move(other.address)),
108  port(std::move(other.port)),
109  u(other.u),
110  scache(std::move(other.scache)),
111  hcache(other.hcache)
112 { }
113 
114 IPAddressPort::~IPAddressPort() throw () { }
115 
116 IPAddressPort& IPAddressPort::operator = (const IPAddressPort &other) throw () {
117  if (this != &other) {
118  this->address = other.address;
119  this->port = other.port;
120  this->u = other.u;
121  this->scache = other.scache;
122  this->hcache = other.hcache;
123  }
124 
125  return *this;
126 }
127 
128 IPAddressPort& IPAddressPort::operator = (const IPAddressPort &&other) throw () {
129  if (this != &other) {
130  this->address = std::move(other.address);
131  this->port = std::move(other.port);
132  this->u = other.u;
133  this->scache = std::move(other.scache);
134  this->hcache = other.hcache;
135  }
136 
137  return *this;
138 }
139 
140 bool IPAddressPort::operator == (const IPAddressPort &other) const throw () {
141  return (this->port == other.port) ? ((this->address == other.address) ? true : false) : false;
142 }
143 
144 bool IPAddressPort::operator != (const IPAddressPort &other) const throw () {
145  return !(*this == other);
146 }
147 
148 bool IPAddressPort::operator >= (const IPAddressPort &other) const throw () {
149  return (this->address < other.address) ? false : ((this->address > other.address) ? true : (this->port >= other.port) ? true : false);
150 }
151 
152 bool IPAddressPort::operator <= (const IPAddressPort &other) const throw () {
153  return (this->address > other.address) ? false : ((this->address < other.address) ? true : (this->port <= other.port) ? true : false);
154 }
155 
156 bool IPAddressPort::operator > (const IPAddressPort &other) const throw () {
157  return (this->address > other.address) ? true : ((this->address < other.address) ? false : (this->port > other.port) ? true : false);
158 }
159 
160 bool IPAddressPort::operator < (const IPAddressPort &other) const throw () {
161  return (this->address < other.address) ? true : ((this->address > other.address) ? false : (this->port < other.port) ? true : false);
162 }
163 
164 int IPAddressPort::getFamily(void) const throw () {
165  return address.getFamily();
166 }
167 
168 const IPAddress& IPAddressPort::getIPAddress(void) const throw () {
169  return this->address;
170 }
171 
172 const Port& IPAddressPort::getPort(void) const throw () {
173  return this->port;
174 }
175 
176 const struct sockaddr_storage& IPAddressPort::getSockaddrStorage(void) const throw () {
177  return u.ss;
178 }
179 
180 const struct sockaddr& IPAddressPort::getSockaddr(void) const throw () {
181  return u.sa;
182 }
183 
184 const struct sockaddr_in& IPAddressPort::getSockaddrIn(void) const throw () {
185  return u.sa_in;
186 }
187 
188 const struct sockaddr_in6& IPAddressPort::getSockaddrIn6(void) const throw () {
189  return u.sa_in6;
190 }
191 
192 bool IPAddressPort::hasIPAddress(void) const throw () {
193  return (!address.empty());
194 }
195 
196 bool IPAddressPort::hasPort(void) const throw () {
197  return (!port.empty());
198 }
199 
200 const std::string& IPAddressPort::str(void) const throw (AddressException) {
201  if (scache.empty()) {
202  if (this->address.getFamily() == AF_INET) {
203  scache.append(this->address.str()).append(":").append(this->port.str());
204  } else {
205  scache.append("[").append(this->address.str()).append("]:").append(this->port.str());
206  }
207  }
208 
209  return scache;
210 }
211 
212 const char* IPAddressPort::c_str(void) const throw (AddressException) {
213  return str().c_str();
214 }
215 
216 uint32_t IPAddressPort::getU32(void) const throw () {
217  return (address.getU32() ^ port.getU32());
218 }
219 
220 uint32_t IPAddressPort::getHash(void) const throw () {
221  if (hcache != 0) {
222  return hcache;
223  }
224 
225 #if defined HASH_ALGO_INT1 /* Fast. Nibble swap. */
226  uint32_t k = getU32();
227 
228  hcache = ((k & 0xF0F0F0F0) >> 4) | ((k & 0x0F0F0F0F) << 4);
229 #elif defined HASH_ALGO_INT2
230  uint32_t k = getU32();
231 
232  hcache = (k<<16)^(k>>16)^k; /* Fast. Mix by XOR shifting.. */
233 #elif defined HASH_ALGO_INT3 /* Very fast, but not good. */
234  hcache = getU32();
235 #else
236  #error No hash algo selected.
237 #endif
238 
239  return hcache;
240 }
241 
242 bool IPAddressPort::empty(void) const throw () {
243  return (port.empty() && address.empty());
244 }
245 
246 const IPAddressPort::shared IPAddressPort::shared_ptr(const IPAddress &address, const Port &port) throw () {
247  return std::make_shared<IPAddressPort>(address, port);
248 }
249 
250 const IPAddressPort::shared IPAddressPort::shared_ptr(const IPAddress &address, const TCPPort &port) throw () {
251  return std::make_shared<IPAddressPort>(address, port);
252 }
253 
254 const IPAddressPort::shared IPAddressPort::shared_ptr(const IPAddress &address, const UDPPort &port) throw () {
255  return std::make_shared<IPAddressPort>(address, port);
256 }
257 
258 const IPAddressPort::shared IPAddressPort::shared_ptr(const IPAddress &address, uint16_t port) throw (PortException) {
259  return std::make_shared<IPAddressPort>(address, port);
260 }
261 
262 const IPAddressPort::shared IPAddressPort::shared_ptr(const std::string &address, uint16_t port) throw (AddressException, PortException) {
263  return std::make_shared<IPAddressPort>(address, port);
264 }
265 
266 const IPAddressPort::shared IPAddressPort::shared_ptr(const struct sockaddr_storage *ss) throw (AddressException, PortException) {
267  return std::make_shared<IPAddressPort>(ss);
268 }
269 
270 const IPAddressPort::shared IPAddressPort::shared_ptr(const struct sockaddr *sa) throw (AddressException, PortException) {
271  return std::make_shared<IPAddressPort>(sa);
272 }
273 
274 void IPAddressPort::init(const IPAddress &address, const Port &port) throw () {
275  this->address = address;
276  this->port = port;
277 
278  memset(&u, 0, sizeof(union __sockaddr_union));
279 
280  u.sa.sa_family = address.getFamily();
281  if (u.sa.sa_family == AF_INET) {
282  memcpy(&(u.sa_in.sin_addr), &(address.getIPv4AddressStructure()), sizeof(struct in_addr));
283  } else {
284  memcpy(&(u.sa_in6.sin6_addr), &(address.getIPv6AddressStructure()), sizeof(struct in6_addr));
285  }
286  u.sa_in.sin_port = htons(port.get());
287 }
288 
289 /*
290 ** vim: noet ts=3 sw=3
291 */