]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/smux/types.cpp
Suffix construction and prefix compare methods added to the OID
[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, size_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 {
57 if (!StringToArcs(str.c_str(), str.length(), arcs))
58     throw std::runtime_error("Invalid oid");
59 }
60
61 OID::OID(const char * str, size_t length)
62 {
63 if (!StringToArcs(str, length, arcs))
64     throw std::runtime_error("Invalid oid");
65 }
66
67 OID::OID(const std::vector<unsigned> & a)
68     : arcs(a)
69 {
70 }
71
72 OID::OID(const unsigned * a, size_t length)
73 {
74 std::vector<unsigned> newArcs(a, a + length);
75 arcs.swap(newArcs);
76 }
77
78 OID::OID(OBJECT_IDENTIFIER_t * oid)
79 {
80 unsigned a[1024];
81 int count = OBJECT_IDENTIFIER_get_arcs(oid, a, sizeof(a[0]), 1024);
82
83 if (count > 1024)
84     throw std::runtime_error("OID is too long");
85
86 std::vector<unsigned> newArcs(a, a + count);
87 arcs.swap(newArcs);
88 }
89
90 OID::OID(const OID & rvalue)
91     : arcs(rvalue.arcs)
92 {
93 }
94
95 OID::~OID()
96 {
97 }
98
99 bool OID::addSuffix(const char * suffix, size_t length)
100 {
101 if (!AppendToArcs(suffix, length, arcs))
102     return false;
103 return true;
104 }
105
106 bool OID::addSuffix(const std::string & suffix)
107 {
108 if (!AppendToArcs(suffix.c_str(), suffix.length(), arcs))
109     return false;
110 return true;
111 }
112
113 bool OID::addSuffix(const unsigned * suffix, size_t length)
114 {
115 std::copy(suffix, suffix + length, std::back_inserter(arcs));
116 return true;
117 }
118
119 bool OID::addSuffix(const std::vector<unsigned> & suffix)
120 {
121 std::copy(suffix.begin(), suffix.end(), std::back_inserter(arcs));
122 return true;
123 }
124
125 bool OID::addSuffix(unsigned a, unsigned b)
126 {
127 arcs.push_back(a);
128 arcs.push_back(b);
129 return true;
130 }
131
132 OID OID::copyWithSuffix(const char * suffix, size_t length) const
133 {
134 OID oid(*this);
135 if (!oid.addSuffix(suffix, length))
136     throw std::runtime_error("Invalid suffix");
137 return oid;
138 }
139
140 OID OID::copyWithSuffix(const std::string & suffix) const
141 {
142 OID oid(*this);
143 if (!oid.addSuffix(suffix))
144     throw std::runtime_error("Invalid suffix");
145 return oid;
146 }
147
148 OID OID::copyWithSuffix(const unsigned * suffix, size_t length) const
149 {
150 OID oid(*this);
151 if (!oid.addSuffix(suffix, length))
152     throw std::runtime_error("Invalid suffix");
153 return oid;
154 }
155
156 OID OID::copyWithSuffix(const std::vector<unsigned> & suffix) const
157 {
158 OID oid(*this);
159 if (!oid.addSuffix(suffix))
160     throw std::runtime_error("Invalid suffix");
161 return oid;
162 }
163
164 OID OID::copyWithSuffix(unsigned a, unsigned b) const
165 {
166 OID oid(*this);
167 oid.addSuffix(a, b);
168 return oid;
169 }
170
171 std::string OID::ToString() const
172 {
173 std::stringstream stream;
174 for (size_t i = 0; i < arcs.size(); ++i)
175     stream << "." << arcs[i];
176 return stream.str();
177 }
178
179 void OID::ToOID(OBJECT_IDENTIFIER_t * oid) const
180 {
181 OBJECT_IDENTIFIER_set_arcs(oid, &arcs.front(), sizeof(unsigned), arcs.size());
182 }
183
184 OID & OID::operator=(const OID & rvalue)
185 {
186 arcs = rvalue.arcs;
187 return *this;
188 }
189
190 bool OID::operator==(const OID & rvalue) const
191 {
192 if (arcs.size() != rvalue.arcs.size())
193     return false;
194 for (size_t i = 0; i < arcs.size(); ++i)
195     if (arcs[i] != rvalue.arcs[i])
196         return false;
197 return true;
198 }
199
200 bool OID::operator<(const OID & rvalue) const
201 {
202 size_t i = 0;
203 size_t min = std::min(arcs.size(), rvalue.arcs.size());
204 while (i < min &&
205        arcs[i] == rvalue.arcs[i])
206     ++i;
207 if (i == min)
208     {
209     if (rvalue.arcs.size() > arcs.size())
210         return true;
211     return false;
212     }
213
214 if (arcs[i] < rvalue.arcs[i])
215     return true;
216
217 return false;
218 }
219
220 bool OID::PrefixLess(const OID & rvalue) const
221 {
222 size_t i = 0;
223 size_t min = std::min(arcs.size(), rvalue.arcs.size());
224 while (i < min &&
225        arcs[i] == rvalue.arcs[i])
226     ++i;
227 if (i == min)
228     return false;
229 if (arcs[i] < rvalue.arcs[i])
230     return true;
231 return false;
232 }
233
234 std::ostream & operator<<(std::ostream & stream, const OID & oid)
235 {
236 for (size_t i = 0; i < oid.arcs.size(); ++i)
237     stream << "." << oid.arcs[i];
238 return stream;
239 }