]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/smux/types.cpp
4e54749287110f740fa264db4590a63fd23028b9
[stg.git] / projects / stargazer / plugins / other / smux / types.cpp
1 #include <stdexcept>
2 #include <algorithm>
3 #include <iterator>
4 #include <sstream>
5
6 #include "types.h"
7
8 namespace
9 {
10
11 bool ParseArcs(const char * str, ptrdiff_t length, unsigned * a, size_t * pos);
12 bool StringToArcs(const char * str, size_t length, std::vector<unsigned> & arcs);
13 bool AppendToArcs(const char * str, size_t length, std::vector<unsigned> & arcs);
14
15 bool ParseArcs(const char * str, ptrdiff_t length, unsigned * a, size_t * pos)
16 {
17 if (length == 0)
18     return false;
19 const char * left = str;
20 if (*left == '.')
21     ++left;
22 size_t arcPos = 0;
23 while ((left - str) < length)
24     {
25     char * pos = NULL;
26     unsigned arc = static_cast<unsigned int>(strtoul(left, &pos, 10));
27     if (pos == left)
28         return false;
29     a[arcPos++] = arc;
30     if (arcPos >= 1024)
31         return false;
32     left = pos + 1;
33     }
34 *pos = arcPos;
35 return true;
36 }
37
38 bool StringToArcs(const char * str, size_t length, std::vector<unsigned> & arcs)
39 {
40 unsigned a[1024];
41 size_t pos = 0;
42
43 if (!ParseArcs(str, length, a, &pos))
44     return false;
45
46 arcs.assign(a, a + pos);
47 return true;
48 }
49
50 bool AppendToArcs(const char * str, size_t length, std::vector<unsigned> & arcs)
51 {
52 unsigned a[1024];
53 size_t pos = 0;
54
55 if (!ParseArcs(str, length, a, &pos))
56     return false;
57
58 std::copy(&a[0], &a[pos], std::back_inserter(arcs));
59 return true;
60 }
61
62 }
63
64 OID::OID(const std::string & str)
65     : arcs()
66 {
67 if (!StringToArcs(str.c_str(), str.length(), arcs))
68     throw std::runtime_error("Invalid oid");
69 }
70
71 OID::OID(const char * str, size_t length)
72     : arcs()
73 {
74 if (!StringToArcs(str, length, arcs))
75     throw std::runtime_error("Invalid oid");
76 }
77
78 OID::OID(const std::vector<unsigned> & a)
79     : arcs(a)
80 {
81 }
82
83 OID::OID(const unsigned * a, size_t length)
84     : arcs()
85 {
86 std::vector<unsigned> newArcs(a, a + length);
87 arcs.swap(newArcs);
88 }
89
90 OID::OID(OBJECT_IDENTIFIER_t * oid)
91     : arcs()
92 {
93 unsigned a[1024];
94 int count = OBJECT_IDENTIFIER_get_arcs(oid, a, sizeof(a[0]), 1024);
95
96 if (count > 1024)
97     throw std::runtime_error("OID is too long");
98
99 std::vector<unsigned> newArcs(a, a + count);
100 arcs.swap(newArcs);
101 }
102
103 OID::OID(const OID & rvalue)
104     : arcs(rvalue.arcs)
105 {
106 }
107
108 OID::~OID()
109 {
110 }
111
112 bool OID::addSuffix(const char * suffix, size_t length)
113 {
114 if (!AppendToArcs(suffix, length, arcs))
115     return false;
116 return true;
117 }
118
119 bool OID::addSuffix(const std::string & suffix)
120 {
121 if (!AppendToArcs(suffix.c_str(), suffix.length(), arcs))
122     return false;
123 return true;
124 }
125
126 bool OID::addSuffix(const unsigned * suffix, size_t length)
127 {
128 std::copy(suffix, suffix + length, std::back_inserter(arcs));
129 return true;
130 }
131
132 bool OID::addSuffix(const std::vector<unsigned> & suffix)
133 {
134 std::copy(suffix.begin(), suffix.end(), std::back_inserter(arcs));
135 return true;
136 }
137
138 bool OID::addSuffix(unsigned a, unsigned b)
139 {
140 arcs.push_back(a);
141 arcs.push_back(b);
142 return true;
143 }
144
145 OID OID::copyWithSuffix(const char * suffix, size_t length) const
146 {
147 OID oid(*this);
148 if (!oid.addSuffix(suffix, length))
149     throw std::runtime_error("Invalid suffix");
150 return oid;
151 }
152
153 OID OID::copyWithSuffix(const std::string & suffix) const
154 {
155 OID oid(*this);
156 if (!oid.addSuffix(suffix))
157     throw std::runtime_error("Invalid suffix");
158 return oid;
159 }
160
161 OID OID::copyWithSuffix(const unsigned * suffix, size_t length) const
162 {
163 OID oid(*this);
164 if (!oid.addSuffix(suffix, length))
165     throw std::runtime_error("Invalid suffix");
166 return oid;
167 }
168
169 OID OID::copyWithSuffix(const std::vector<unsigned> & suffix) const
170 {
171 OID oid(*this);
172 if (!oid.addSuffix(suffix))
173     throw std::runtime_error("Invalid suffix");
174 return oid;
175 }
176
177 OID OID::copyWithSuffix(unsigned a, unsigned b) const
178 {
179 OID oid(*this);
180 oid.addSuffix(a, b);
181 return oid;
182 }
183
184 std::string OID::ToString() const
185 {
186 std::stringstream stream;
187 for (size_t i = 0; i < arcs.size(); ++i)
188     stream << "." << arcs[i];
189 return stream.str();
190 }
191
192 void OID::ToOID(OBJECT_IDENTIFIER_t * oid) const
193 {
194 OBJECT_IDENTIFIER_set_arcs(oid, &arcs.front(), sizeof(unsigned), static_cast<unsigned int>(arcs.size()));
195 }
196
197 OID & OID::operator=(const OID & rvalue)
198 {
199 arcs = rvalue.arcs;
200 return *this;
201 }
202
203 bool OID::operator==(const OID & rvalue) const
204 {
205 if (arcs.size() != rvalue.arcs.size())
206     return false;
207 for (size_t i = 0; i < arcs.size(); ++i)
208     if (arcs[i] != rvalue.arcs[i])
209         return false;
210 return true;
211 }
212
213 bool OID::operator<(const OID & rvalue) const
214 {
215 size_t i = 0;
216 size_t min = std::min(arcs.size(), rvalue.arcs.size());
217 while (i < min &&
218        arcs[i] == rvalue.arcs[i])
219     ++i;
220 if (i == min)
221     {
222     if (rvalue.arcs.size() > arcs.size())
223         return true;
224     return false;
225     }
226
227 if (arcs[i] < rvalue.arcs[i])
228     return true;
229
230 return false;
231 }
232
233 bool OID::PrefixLess(const OID & rvalue) const
234 {
235 size_t i = 0;
236 size_t min = std::min(arcs.size(), rvalue.arcs.size());
237 while (i < min &&
238        arcs[i] == rvalue.arcs[i])
239     ++i;
240 if (i == min)
241     return false;
242 if (arcs[i] < rvalue.arcs[i])
243     return true;
244 return false;
245 }
246
247 std::ostream & operator<<(std::ostream & stream, const OID & oid)
248 {
249 for (size_t i = 0; i < oid.arcs.size(); ++i)
250     stream << "." << oid.arcs[i];
251 return stream;
252 }