libutil++  1.9.3
 All Classes Functions Variables
IPPrefix.cpp
1 /*
2 ** libutil++
3 ** $Id: IPPrefix.cpp 1723 2016-11-03 19:34:33Z 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: IPPrefix.cpp 1723 2016-11-03 19:34:33Z sella $";
10 
11 #include "IPPrefix.h"
12 #include "../net/IPPrefix.h"
13 #include "../util/CommonMacro.h"
14 
15 using namespace sella::variant;
16 namespace sn = sella::net;
17 
18 IPPrefix::IPPrefix() throw () : Nullable(std::make_shared<sn::IPPrefix>()) { }
19 
20 IPPrefix::IPPrefix(const std::string &value) throw (TypeCastException) : Nullable() {
21  if (LIKELY(boost::regex_match(value, IPPrefix::Pattern()))) {
22  this->value = std::make_shared<sn::IPPrefix>(value);
23  } else {
24  THROW(TypeCastException, "unable to cast '%s' to a ipprefix value", value.c_str());
25  }
26 }
27 
28 IPPrefix::IPPrefix(const sn::IPPrefix &value) throw () : Nullable(std::make_shared<sn::IPPrefix>(value)) { }
29 
30 IPPrefix::IPPrefix(sn::IPPrefix &&value) throw () : Nullable(std::make_shared<sn::IPPrefix>(std::move(value))) { }
31 
32 IPPrefix::IPPrefix(const IPPrefix &other) throw () : Nullable() {
33  if (LIKELY(this != &other)) {
34  if (LIKELY(!other.isNull())) {
35  if (UNLIKELY(isNull())) {
36  this->value = std::make_shared<sn::IPPrefix>(other.get());
37  } else {
38  *std::static_pointer_cast<sn::IPPrefix>(this->value) = *std::static_pointer_cast<sn::IPPrefix>(other.value);
39  }
40  } else {
41  this->value.reset();
42  }
43  }
44 }
45 
46 IPPrefix::IPPrefix(IPPrefix &&other) throw () : Nullable() {
47  if (LIKELY(!other.isNull())) {
48  this->value = std::move(other.value);
49  }
50 }
51 
52 bool IPPrefix::operator==(const IPPrefix &other) const throw () {
53  return (*std::static_pointer_cast<sn::IPPrefix>(this->value) == *std::static_pointer_cast<sn::IPPrefix>(other.value));
54 }
55 
56 bool IPPrefix::operator!=(const IPPrefix &other) const throw () {
57  return !(*this == other);
58 }
59 
60 bool IPPrefix::operator>(const IPPrefix &other) const throw () {
61  return (*std::static_pointer_cast<sn::IPPrefix>(this->value) > *std::static_pointer_cast<sn::IPPrefix>(other.value));
62 }
63 
64 bool IPPrefix::operator<(const IPPrefix &other) const throw () {
65  return (*std::static_pointer_cast<sn::IPPrefix>(this->value) < *std::static_pointer_cast<sn::IPPrefix>(other.value));
66 }
67 
68 IPPrefix& IPPrefix::operator=(const IPPrefix &other) throw () {
69  if (LIKELY(this != &other)) {
70  if (LIKELY(!other.isNull())) {
71  if (UNLIKELY(isNull())) {
72  this->value = std::make_shared<sn::IPPrefix>(other.get());
73  } else {
74  *std::static_pointer_cast<sn::IPPrefix>(this->value) = *std::static_pointer_cast<sn::IPPrefix>(other.value);
75  }
76  } else {
77  this->value.reset();
78  }
79  }
80 
81  return *this;
82 }
83 
84 IPPrefix& IPPrefix::operator=(IPPrefix &&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 IPPrefix& IPPrefix::operator=(const sella::net::IPPrefix &other) throw () {
95  if (UNLIKELY(isNull())) {
96  this->value = std::make_shared<sn::IPPrefix>(other);
97  } else {
98  *std::static_pointer_cast<sn::IPPrefix>(this->value) = other;
99  }
100 
101  return *this;
102 }
103 
104 IPPrefix::~IPPrefix() throw () { }
105 
106 const sn::IPPrefix& IPPrefix::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::IPPrefix>(this->value);
112 }
113 
114 sn::IPPrefix& IPPrefix::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::IPPrefix>(this->value);
120 }
121 
122 void IPPrefix::clear() throw() {
123  if (UNLIKELY(isNull())) {
124  this->value = std::make_shared<sn::IPPrefix>();
125  } else {
126  this->get().clear();
127  }
128 }
129 
130 void IPPrefix::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::IPPrefix>(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 IPPrefix::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::IPPrefix>(this->value)->getFamily() == sn::IPAddress::IPv4Family) ? 18 : 43;
154 }
155 
156 std::string IPPrefix::str(int type) const throw () {
157  if (UNLIKELY(isNull())) {
158  return "null";
159  }
160 
161  return this->get().str();
162 }
163 
164 bool IPPrefix::isType(const char *value, size_t size) throw () {
165  size_t cidr = 0;
166 
167  /* Verify CIDR is present and valid. */
168  for (size_t i = size - 4; i < size; i++) {
169  if (value[i] == '/' && ::isdigit(value[i + 1]) != 0) {
170  if (::atoi(value + i + 1) > 128) {
171  return false;
172  }
173 
174  cidr = i;
175  }
176  }
177 
178  if (cidr != 0) {
179  unsigned char buf[sizeof(struct in6_addr)];
180  char tmp[cidr + 1];
181 
182  /* Verify as proper IPv4/IPv6 */
183  for (size_t i = 0, len = (size > 5) ? 5 : size; i < len; i++) {
184  if (value[i] == '.') { /* Possibly an IPv4 address */
185  strncpy(tmp, value, cidr);
186  tmp[cidr] = 0;
187 
188  return (inet_pton(AF_INET, tmp, buf) == 1);
189  } else if (value[i] == ':') { /* Possibly an IPv6 address */
190  strncpy(tmp, value, cidr);
191  tmp[cidr] = 0;
192 
193  return (inet_pton(AF_INET6, tmp, buf) == 1);
194  }
195  }
196  }
197 
198  return false;
199 }
200 
201 /*
202 ** vim: noet ts=3 sw=3
203 */