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