#include <stdexcept>
#include <algorithm>
+#include <iterator>
#include <sstream>
#include "types.h"
-bool StringToArcs(const char * str, size_t length, std::vector<unsigned> & arcs)
+namespace
+{
+
+bool ParseArcs(const char * str, ptrdiff_t length, unsigned * a, size_t * pos);
+bool StringToArcs(const char * str, size_t length, std::vector<unsigned> & arcs);
+bool AppendToArcs(const char * str, size_t length, std::vector<unsigned> & arcs);
+
+bool ParseArcs(const char * str, ptrdiff_t length, unsigned * a, size_t * pos)
{
-unsigned a[1024];
if (length == 0)
return false;
const char * left = str;
while ((left - str) < length)
{
char * pos = NULL;
- unsigned arc = strtoul(left, &pos, 10);
+ unsigned arc = static_cast<unsigned int>(strtoul(left, &pos, 10));
if (pos == left)
return false;
a[arcPos++] = arc;
return false;
left = pos + 1;
}
+*pos = arcPos;
+return true;
+}
-std::vector<unsigned> newArcs(a, a + arcPos);
-arcs.swap(newArcs);
+bool StringToArcs(const char * str, size_t length, std::vector<unsigned> & arcs)
+{
+unsigned a[1024];
+size_t pos = 0;
+
+if (!ParseArcs(str, length, a, &pos))
+ return false;
+
+arcs.assign(a, a + pos);
return true;
}
+bool AppendToArcs(const char * str, size_t length, std::vector<unsigned> & arcs)
+{
+unsigned a[1024];
+size_t pos = 0;
+
+if (!ParseArcs(str, length, a, &pos))
+ return false;
+
+std::copy(&a[0], &a[pos], std::back_inserter(arcs));
+return true;
+}
+
+}
+
OID::OID(const std::string & str)
+ : arcs()
{
if (!StringToArcs(str.c_str(), str.length(), arcs))
throw std::runtime_error("Invalid oid");
}
OID::OID(const char * str, size_t length)
+ : arcs()
{
if (!StringToArcs(str, length, arcs))
throw std::runtime_error("Invalid oid");
}
OID::OID(const unsigned * a, size_t length)
+ : arcs()
{
std::vector<unsigned> newArcs(a, a + length);
arcs.swap(newArcs);
}
OID::OID(OBJECT_IDENTIFIER_t * oid)
+ : arcs()
{
unsigned a[1024];
int count = OBJECT_IDENTIFIER_get_arcs(oid, a, sizeof(a[0]), 1024);
{
}
+bool OID::addSuffix(const char * suffix, size_t length)
+{
+if (!AppendToArcs(suffix, length, arcs))
+ return false;
+return true;
+}
+
+bool OID::addSuffix(const std::string & suffix)
+{
+if (!AppendToArcs(suffix.c_str(), suffix.length(), arcs))
+ return false;
+return true;
+}
+
+bool OID::addSuffix(const unsigned * suffix, size_t length)
+{
+std::copy(suffix, suffix + length, std::back_inserter(arcs));
+return true;
+}
+
+bool OID::addSuffix(const std::vector<unsigned> & suffix)
+{
+std::copy(suffix.begin(), suffix.end(), std::back_inserter(arcs));
+return true;
+}
+
+bool OID::addSuffix(unsigned a, unsigned b)
+{
+arcs.push_back(a);
+arcs.push_back(b);
+return true;
+}
+
+OID OID::copyWithSuffix(const char * suffix, size_t length) const
+{
+OID oid(*this);
+if (!oid.addSuffix(suffix, length))
+ throw std::runtime_error("Invalid suffix");
+return oid;
+}
+
+OID OID::copyWithSuffix(const std::string & suffix) const
+{
+OID oid(*this);
+if (!oid.addSuffix(suffix))
+ throw std::runtime_error("Invalid suffix");
+return oid;
+}
+
+OID OID::copyWithSuffix(const unsigned * suffix, size_t length) const
+{
+OID oid(*this);
+if (!oid.addSuffix(suffix, length))
+ throw std::runtime_error("Invalid suffix");
+return oid;
+}
+
+OID OID::copyWithSuffix(const std::vector<unsigned> & suffix) const
+{
+OID oid(*this);
+if (!oid.addSuffix(suffix))
+ throw std::runtime_error("Invalid suffix");
+return oid;
+}
+
+OID OID::copyWithSuffix(unsigned a, unsigned b) const
+{
+OID oid(*this);
+oid.addSuffix(a, b);
+return oid;
+}
+
std::string OID::ToString() const
{
std::stringstream stream;
void OID::ToOID(OBJECT_IDENTIFIER_t * oid) const
{
-OBJECT_IDENTIFIER_set_arcs(oid, &arcs.front(), sizeof(unsigned), arcs.size());
+OBJECT_IDENTIFIER_set_arcs(oid, &arcs.front(), sizeof(unsigned), static_cast<unsigned int>(arcs.size()));
}
OID & OID::operator=(const OID & rvalue)
bool OID::operator<(const OID & rvalue) const
{
-for (size_t i = 0; i < std::min(arcs.size(), rvalue.arcs.size()); ++i)
- if (arcs[i] > rvalue.arcs[i])
- return false;
-if (rvalue.arcs.size() < arcs.size())
+size_t i = 0;
+size_t min = std::min(arcs.size(), rvalue.arcs.size());
+while (i < min &&
+ arcs[i] == rvalue.arcs[i])
+ ++i;
+if (i == min)
+ {
+ if (rvalue.arcs.size() > arcs.size())
+ return true;
return false;
-return true;
+ }
+
+if (arcs[i] < rvalue.arcs[i])
+ return true;
+
+return false;
}
-std::ostream & OID::operator<<(std::ostream & stream) const
+bool OID::PrefixLess(const OID & rvalue) const
{
-for (size_t i = 0; i < arcs.size(); ++i)
- stream << "." << arcs[i];
+size_t i = 0;
+size_t min = std::min(arcs.size(), rvalue.arcs.size());
+while (i < min &&
+ arcs[i] == rvalue.arcs[i])
+ ++i;
+if (i == min)
+ return false;
+if (arcs[i] < rvalue.arcs[i])
+ return true;
+return false;
+}
+
+std::ostream & operator<<(std::ostream & stream, const OID & oid)
+{
+for (size_t i = 0; i < oid.arcs.size(); ++i)
+ stream << "." << oid.arcs[i];
return stream;
}