| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */ |
| /** |
| * Copyright (c) 2013-2014, Regents of the University of California. |
| * All rights reserved. |
| * |
| * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions). |
| * See AUTHORS.md for complete list of ndn-cxx authors and contributors. |
| * |
| * This file licensed under New BSD License. See COPYING for detailed information about |
| * ndn-cxx library copyright, permissions, and redistribution restrictions. |
| * |
| */ |
| |
| #include "common.hpp" |
| |
| #include "oid.hpp" |
| |
| #include "../security/cryptopp.hpp" |
| |
| #include <sstream> |
| |
| using namespace std; |
| using namespace CryptoPP; |
| |
| namespace ndn { |
| |
| OID::OID(const char* oid) |
| { |
| construct(oid); |
| } |
| |
| OID::OID(const string& oid) |
| { |
| construct(oid); |
| } |
| |
| void |
| OID::construct(const std::string& oid) |
| { |
| string str = oid + "."; |
| |
| size_t pos = 0; |
| size_t ppos = 0; |
| |
| while (string::npos != pos) { |
| ppos = pos; |
| |
| pos = str.find_first_of('.', pos); |
| if (pos == string::npos) |
| break; |
| |
| m_oid.push_back(atoi(str.substr(ppos, pos - ppos).c_str())); |
| |
| pos++; |
| } |
| } |
| |
| string OID::toString() const |
| { |
| ostringstream convert; |
| |
| for (vector<int>::const_iterator it = m_oid.begin(); it != m_oid.end(); ++it) { |
| if (it != m_oid.begin()) |
| convert << "."; |
| convert << *it; |
| } |
| |
| return convert.str(); |
| } |
| |
| bool |
| OID::equal(const OID& oid) const |
| { |
| vector<int>::const_iterator i = m_oid.begin(); |
| vector<int>::const_iterator j = oid.m_oid.begin(); |
| |
| for (; i != m_oid.end () && j != oid.m_oid.end (); i++, j++) { |
| if (*i != *j) |
| return false; |
| } |
| |
| if (i == m_oid.end () && j == oid.m_oid.end ()) |
| return true; |
| else |
| return false; |
| } |
| |
| inline void |
| EncodeValue(BufferedTransformation& bt, word32 v) |
| { |
| for (unsigned int i = RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U) - 7; i != 0; i -= 7) |
| bt.Put((byte)(0x80 | ((v >> i) & 0x7f))); |
| bt.Put((byte)(v & 0x7f)); |
| } |
| |
| inline size_t |
| DecodeValue(BufferedTransformation& bt, word32& v) |
| { |
| v = 0; |
| size_t i = 0; |
| while (true) |
| { |
| byte b; |
| if (!bt.Get(b)) |
| BERDecodeError(); |
| i++; |
| if (v >> (8*sizeof(v) - 7)) // v about to overflow |
| BERDecodeError(); |
| v <<= 7; |
| v += b & 0x7f; |
| if (!(b & 0x80)) |
| return i; |
| } |
| } |
| |
| void |
| OID::encode(CryptoPP::BufferedTransformation& out) const |
| { |
| BOOST_ASSERT(m_oid.size() >= 2); |
| |
| ByteQueue temp; |
| temp.Put(byte(m_oid[0] * 40 + m_oid[1])); |
| for (size_t i = 2; i < m_oid.size(); i++) |
| EncodeValue(temp, m_oid[i]); |
| |
| out.Put(OBJECT_IDENTIFIER); |
| DERLengthEncode(out, temp.CurrentSize()); |
| temp.TransferTo(out); |
| } |
| |
| void |
| OID::decode(CryptoPP::BufferedTransformation& in) |
| { |
| byte b; |
| if (!in.Get(b) || b != OBJECT_IDENTIFIER) |
| BERDecodeError(); |
| |
| size_t length; |
| if (!BERLengthDecode(in, length) || length < 1) |
| BERDecodeError(); |
| |
| if (!in.Get(b)) |
| BERDecodeError(); |
| |
| length--; |
| m_oid.resize(2); |
| m_oid[0] = b / 40; |
| m_oid[1] = b % 40; |
| |
| while (length > 0) |
| { |
| word32 v; |
| size_t valueLen = DecodeValue(in, v); |
| if (valueLen > length) |
| BERDecodeError(); |
| m_oid.push_back(v); |
| length -= valueLen; |
| } |
| } |
| |
| } // namespace ndn |