libutil++  1.9.3
 All Classes Functions Variables
IPAddress.cpp
1 /*
2 ** libutil++
3 ** $Id: IPAddress.cpp 1702 2016-08-13 23:26:06Z 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: IPAddress.cpp 1702 2016-08-13 23:26:06Z sella $";
10 
11 #include "IPAddress.h"
12 #include "../net/IPAddress.h"
13 #include "../util/CommonMacro.h"
14 
15 using namespace sella::variant;
16 namespace sn = sella::net;
17 
18 IPAddress::IPAddress() throw () : Nullable(std::make_shared<sn::IPAddress>()) { }
19 
20 IPAddress::IPAddress(const std::string &value) throw (TypeCastException) : Nullable() {
21  if (LIKELY(boost::regex_match(value, IPAddress::Pattern()))) {
22  this->value = std::make_shared<sn::IPAddress>(value);
23  } else {
24  THROW(TypeCastException, "unable to cast '%s' to a ipaddress value", value.c_str());
25  }
26 }
27 
28 IPAddress::IPAddress(const sn::IPAddress &value) throw () : Nullable(std::make_shared<sn::IPAddress>(value)) { }
29 
30 IPAddress::IPAddress(sn::IPAddress &&value) throw () : Nullable(std::make_shared<sn::IPAddress>(std::move(value))) { }
31 
32 IPAddress::IPAddress(const IPAddress &other) throw () : Nullable() {
33  if (LIKELY(this != &other)) {
34  if (LIKELY(!other.isNull())) {
35  if (UNLIKELY(isNull())) {
36  this->value = std::make_shared<sn::IPAddress>(other.get());
37  } else {
38  *std::static_pointer_cast<sn::IPAddress>(this->value) = *std::static_pointer_cast<sn::IPAddress>(other.value);
39  }
40  } else {
41  this->value.reset();
42  }
43  }
44 }
45 
46 IPAddress::IPAddress(IPAddress &&other) throw () : Nullable() {
47  if (UNLIKELY(!other.isNull())) {
48  this->value = std::move(other.value);
49  }
50 }
51 
52 bool IPAddress::operator==(const IPAddress &other) const throw () {
53  return (*std::static_pointer_cast<sn::IPAddress>(this->value) == *std::static_pointer_cast<sn::IPAddress>(other.value));
54 }
55 
56 bool IPAddress::operator!=(const IPAddress &other) const throw () {
57  return !(*this == other);
58 }
59 
60 bool IPAddress::operator>(const IPAddress &other) const throw () {
61  return (*std::static_pointer_cast<sn::IPAddress>(this->value) > *std::static_pointer_cast<sn::IPAddress>(other.value));
62 }
63 
64 bool IPAddress::operator<(const IPAddress &other) const throw () {
65  return (*std::static_pointer_cast<sn::IPAddress>(this->value) < *std::static_pointer_cast<sn::IPAddress>(other.value));
66 }
67 
68 IPAddress& IPAddress::operator=(const IPAddress &other) throw () {
69  if (LIKELY(this != &other)) {
70  if (LIKELY(!other.isNull())) {
71  if (UNLIKELY(isNull())) {
72  this->value = std::make_shared<sn::IPAddress>(other.get());
73  } else {
74  *std::static_pointer_cast<sn::IPAddress>(this->value) = *std::static_pointer_cast<sn::IPAddress>(other.value);
75  }
76  } else {
77  this->value.reset();
78  }
79  }
80 
81  return *this;
82 }
83 
84 IPAddress& IPAddress::operator=(IPAddress &&other) throw () {
85  if (LIKELY(this != &other)) {
86  if (LIKELY(!other.isNull())) {
87  this->value = std::move(other.value);
88  }
89  }
90 
91  return *this;
92 }
93 
94 IPAddress& IPAddress::operator=(const sella::net::IPAddress &other) throw () {
95  if (UNLIKELY(isNull())) {
96  this->value = std::make_shared<sn::IPAddress>(other);
97  } else {
98  *std::static_pointer_cast<sn::IPAddress>(this->value) = other;
99  }
100 
101  return *this;
102 }
103 
104 IPAddress::~IPAddress() throw () { }
105 
106 const sn::IPAddress& IPAddress::get() const throw (UnsupportedOperatorException) {
107  if (UNLIKELY(isNull())) {
108  THROW(UnsupportedOperatorException, "unable to take reference of null value");
109  }
110 
111  return *std::static_pointer_cast<sn::IPAddress>(this->value);
112 }
113 
114 sn::IPAddress& IPAddress::get() throw (UnsupportedOperatorException) {
115  if (UNLIKELY(isNull())) {
116  THROW(UnsupportedOperatorException, "unable to take reference of null value");
117  }
118 
119  return *std::static_pointer_cast<sn::IPAddress>(this->value);
120 }
121 
122 void IPAddress::clear() throw() {
123  if (UNLIKELY(isNull())) {
124  this->value = std::make_shared<sn::IPAddress>();
125  } else {
126  std::static_pointer_cast<sn::IPAddress>(this->value)->clear();
127  }
128 }
129 
130 void IPAddress::msgpack(sella::util::MessagePack &mpack, uint32_t &offset) const throw (TypeCastException) {
131  uint32_t c;
132 
133  if (UNLIKELY(isNull())) {
134  c = mpack.append(offset);
135  } else {
136  c = mpack.append(offset, std::static_pointer_cast<sella::net::IPAddress>(this->value)->str());
137  }
138 
139  offset += c;
140 
141  if (UNLIKELY(c == 0)) {
142  THROW(TypeCastException, "Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
143  }
144 }
145 
146 void IPAddress::msgpackBufferSize(size_t &size) const throw () {
147  if (UNLIKELY(isNull())) {
148  size += 1;
149 
150  return;
151  }
152 
153  size += 5 + (std::static_pointer_cast<sella::net::IPAddress>(this->value)->getFamily() == sn::IPAddress::IPv4Family) ? 15 : 39;
154 }
155 
156 std::string IPAddress::str(int type) const throw () {
157  if (UNLIKELY(isNull())) {
158  return "null";
159  }
160 
161  return this->get().str();
162 }
163 
164 bool IPAddress::isType(const char *value, size_t size) throw () {
165  unsigned char buf[sizeof(struct in6_addr)];
166 
167  for (int i = 0, len = (size > 5) ? 5 : size; i < len; i++) {
168  if (value[i] == '.') { /* Possibly an IPv4 address */
169  return (inet_pton(AF_INET, value, buf) == 1);
170  } else if (value[i] == ':') { /* Possibly an IPv6 address */
171  return (inet_pton(AF_INET6, value, buf) == 1);
172  }
173  }
174 
175  return false;
176 }
177 
178 /*
179 ** vim: noet ts=3 sw=3
180 */