DER encoding: Implement DerNode and subclasses.
diff --git a/Makefile.am b/Makefile.am
index 54ee508..e781f48 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -116,7 +116,8 @@
ndn-cpp/encoding/element-listener.cpp \
ndn-cpp/encoding/oid.cpp \
ndn-cpp/encoding/wire-format.cpp \
- ndn-cpp/encoding/der/der.hpp \
+ ndn-cpp/encoding/der/der-exception.cpp ndn-cpp/encoding/der/der-exception.hpp \
+ ndn-cpp/encoding/der/der.cpp ndn-cpp/encoding/der/der.hpp \
ndn-cpp/encoding/der/visitor/no-arguments-visitor.cpp ndn-cpp/encoding/der/visitor/no-arguments-visitor.hpp \
ndn-cpp/encoding/der/visitor/simple-visitor.cpp ndn-cpp/encoding/der/visitor/simple-visitor.hpp \
ndn-cpp/encoding/der/visitor/visitor.hpp \
diff --git a/Makefile.in b/Makefile.in
index 2d5d108..eca3905 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -182,6 +182,8 @@
ndn-cpp/encoding/binary-xml-wire-format.lo \
ndn-cpp/encoding/element-listener.lo ndn-cpp/encoding/oid.lo \
ndn-cpp/encoding/wire-format.lo \
+ ndn-cpp/encoding/der/der-exception.lo \
+ ndn-cpp/encoding/der/der.lo \
ndn-cpp/encoding/der/visitor/no-arguments-visitor.lo \
ndn-cpp/encoding/der/visitor/simple-visitor.lo \
ndn-cpp/encoding/der/visitor/void-visitor.lo \
@@ -660,7 +662,8 @@
ndn-cpp/encoding/element-listener.cpp \
ndn-cpp/encoding/oid.cpp \
ndn-cpp/encoding/wire-format.cpp \
- ndn-cpp/encoding/der/der.hpp \
+ ndn-cpp/encoding/der/der-exception.cpp ndn-cpp/encoding/der/der-exception.hpp \
+ ndn-cpp/encoding/der/der.cpp ndn-cpp/encoding/der/der.hpp \
ndn-cpp/encoding/der/visitor/no-arguments-visitor.cpp ndn-cpp/encoding/der/visitor/no-arguments-visitor.hpp \
ndn-cpp/encoding/der/visitor/simple-visitor.cpp ndn-cpp/encoding/der/visitor/simple-visitor.hpp \
ndn-cpp/encoding/der/visitor/visitor.hpp \
@@ -889,6 +892,17 @@
ndn-cpp/encoding/$(DEPDIR)/$(am__dirstamp)
ndn-cpp/encoding/wire-format.lo: ndn-cpp/encoding/$(am__dirstamp) \
ndn-cpp/encoding/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/encoding/der/$(am__dirstamp):
+ @$(MKDIR_P) ndn-cpp/encoding/der
+ @: > ndn-cpp/encoding/der/$(am__dirstamp)
+ndn-cpp/encoding/der/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) ndn-cpp/encoding/der/$(DEPDIR)
+ @: > ndn-cpp/encoding/der/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/encoding/der/der-exception.lo: \
+ ndn-cpp/encoding/der/$(am__dirstamp) \
+ ndn-cpp/encoding/der/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/encoding/der/der.lo: ndn-cpp/encoding/der/$(am__dirstamp) \
+ ndn-cpp/encoding/der/$(DEPDIR)/$(am__dirstamp)
ndn-cpp/encoding/der/visitor/$(am__dirstamp):
@$(MKDIR_P) ndn-cpp/encoding/der/visitor
@: > ndn-cpp/encoding/der/visitor/$(am__dirstamp)
@@ -1055,6 +1069,8 @@
-rm -f ndn-cpp/c/util/*.lo
-rm -f ndn-cpp/encoding/*.$(OBJEXT)
-rm -f ndn-cpp/encoding/*.lo
+ -rm -f ndn-cpp/encoding/der/*.$(OBJEXT)
+ -rm -f ndn-cpp/encoding/der/*.lo
-rm -f ndn-cpp/encoding/der/visitor/*.$(OBJEXT)
-rm -f ndn-cpp/encoding/der/visitor/*.lo
-rm -f ndn-cpp/security/*.$(OBJEXT)
@@ -1107,6 +1123,8 @@
@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/$(DEPDIR)/element-listener.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/$(DEPDIR)/oid.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/$(DEPDIR)/wire-format.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/der/$(DEPDIR)/der-exception.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/der/$(DEPDIR)/der.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/der/visitor/$(DEPDIR)/no-arguments-visitor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/der/visitor/$(DEPDIR)/simple-visitor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/der/visitor/$(DEPDIR)/void-visitor.Plo@am__quote@
@@ -1195,6 +1213,7 @@
-rm -rf ndn-cpp/c/transport/.libs ndn-cpp/c/transport/_libs
-rm -rf ndn-cpp/c/util/.libs ndn-cpp/c/util/_libs
-rm -rf ndn-cpp/encoding/.libs ndn-cpp/encoding/_libs
+ -rm -rf ndn-cpp/encoding/der/.libs ndn-cpp/encoding/der/_libs
-rm -rf ndn-cpp/encoding/der/visitor/.libs ndn-cpp/encoding/der/visitor/_libs
-rm -rf ndn-cpp/security/.libs ndn-cpp/security/_libs
-rm -rf ndn-cpp/security/certificate/.libs ndn-cpp/security/certificate/_libs
@@ -1546,6 +1565,8 @@
-rm -f ndn-cpp/c/util/$(am__dirstamp)
-rm -f ndn-cpp/encoding/$(DEPDIR)/$(am__dirstamp)
-rm -f ndn-cpp/encoding/$(am__dirstamp)
+ -rm -f ndn-cpp/encoding/der/$(DEPDIR)/$(am__dirstamp)
+ -rm -f ndn-cpp/encoding/der/$(am__dirstamp)
-rm -f ndn-cpp/encoding/der/visitor/$(DEPDIR)/$(am__dirstamp)
-rm -f ndn-cpp/encoding/der/visitor/$(am__dirstamp)
-rm -f ndn-cpp/security/$(DEPDIR)/$(am__dirstamp)
@@ -1573,7 +1594,7 @@
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf ndn-cpp/$(DEPDIR) ndn-cpp/c/$(DEPDIR) ndn-cpp/c/encoding/$(DEPDIR) ndn-cpp/c/transport/$(DEPDIR) ndn-cpp/c/util/$(DEPDIR) ndn-cpp/encoding/$(DEPDIR) ndn-cpp/encoding/der/visitor/$(DEPDIR) ndn-cpp/security/$(DEPDIR) ndn-cpp/security/certificate/$(DEPDIR) ndn-cpp/security/identity/$(DEPDIR) ndn-cpp/security/policy/$(DEPDIR) ndn-cpp/transport/$(DEPDIR) ndn-cpp/util/$(DEPDIR) tests/$(DEPDIR)
+ -rm -rf ndn-cpp/$(DEPDIR) ndn-cpp/c/$(DEPDIR) ndn-cpp/c/encoding/$(DEPDIR) ndn-cpp/c/transport/$(DEPDIR) ndn-cpp/c/util/$(DEPDIR) ndn-cpp/encoding/$(DEPDIR) ndn-cpp/encoding/der/$(DEPDIR) ndn-cpp/encoding/der/visitor/$(DEPDIR) ndn-cpp/security/$(DEPDIR) ndn-cpp/security/certificate/$(DEPDIR) ndn-cpp/security/identity/$(DEPDIR) ndn-cpp/security/policy/$(DEPDIR) ndn-cpp/transport/$(DEPDIR) ndn-cpp/util/$(DEPDIR) tests/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
@@ -1621,7 +1642,7 @@
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
- -rm -rf ndn-cpp/$(DEPDIR) ndn-cpp/c/$(DEPDIR) ndn-cpp/c/encoding/$(DEPDIR) ndn-cpp/c/transport/$(DEPDIR) ndn-cpp/c/util/$(DEPDIR) ndn-cpp/encoding/$(DEPDIR) ndn-cpp/encoding/der/visitor/$(DEPDIR) ndn-cpp/security/$(DEPDIR) ndn-cpp/security/certificate/$(DEPDIR) ndn-cpp/security/identity/$(DEPDIR) ndn-cpp/security/policy/$(DEPDIR) ndn-cpp/transport/$(DEPDIR) ndn-cpp/util/$(DEPDIR) tests/$(DEPDIR)
+ -rm -rf ndn-cpp/$(DEPDIR) ndn-cpp/c/$(DEPDIR) ndn-cpp/c/encoding/$(DEPDIR) ndn-cpp/c/transport/$(DEPDIR) ndn-cpp/c/util/$(DEPDIR) ndn-cpp/encoding/$(DEPDIR) ndn-cpp/encoding/der/$(DEPDIR) ndn-cpp/encoding/der/visitor/$(DEPDIR) ndn-cpp/security/$(DEPDIR) ndn-cpp/security/certificate/$(DEPDIR) ndn-cpp/security/identity/$(DEPDIR) ndn-cpp/security/policy/$(DEPDIR) ndn-cpp/transport/$(DEPDIR) ndn-cpp/util/$(DEPDIR) tests/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/ndn-cpp/encoding/der/der-exception.cpp b/ndn-cpp/encoding/der/der-exception.cpp
new file mode 100644
index 0000000..84ab5c1
--- /dev/null
+++ b/ndn-cpp/encoding/der/der-exception.cpp
@@ -0,0 +1,29 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "der-exception.hpp"
+
+using namespace std;
+
+namespace ndn {
+
+namespace der
+{
+
+DerException::DerException(const string& errorMessage) throw()
+ : errorMessage_(errorMessage)
+{
+}
+
+DerException::~DerException() throw()
+{
+}
+
+} // der
+
+}
diff --git a/ndn-cpp/encoding/der/der-exception.hpp b/ndn-cpp/encoding/der/der-exception.hpp
new file mode 100644
index 0000000..1d0db2a
--- /dev/null
+++ b/ndn-cpp/encoding/der/der-exception.hpp
@@ -0,0 +1,61 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_DER_EXCEPTION_HPP
+#define NDN_DER_EXCEPTION_HPP
+
+#include <exception>
+#include <string>
+
+namespace ndn {
+
+namespace der {
+
+class DerException : public std::exception {
+public:
+ DerException(const std::string& errorMessage) throw();
+
+ ~DerException() throw();
+
+ std::string Msg() { return errorMessage_; }
+
+ virtual const char* what() const throw() { return errorMessage_.c_str(); }
+
+private:
+ const std::string errorMessage_;
+};
+
+class NegativeLengthException : public DerException
+{
+public:
+ NegativeLengthException(const std::string& errorMessage)
+ : DerException(errorMessage)
+ {}
+};
+
+class DerEncodingException : public DerException
+{
+public:
+ DerEncodingException(const std::string& errorMessage)
+ : DerException(errorMessage)
+ {}
+};
+
+class DerDecodingException : public DerException
+{
+public:
+ DerDecodingException(const std::string& errorMessage)
+ : DerException(errorMessage)
+ {}
+};
+
+} // der
+
+}
+
+#endif
diff --git a/ndn-cpp/encoding/der/der.cpp b/ndn-cpp/encoding/der/der.cpp
new file mode 100644
index 0000000..9620be2
--- /dev/null
+++ b/ndn-cpp/encoding/der/der.cpp
@@ -0,0 +1,629 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#if 1 // TODO: Remove this when we don't throw "not implemented".
+#include <stdexcept>
+#endif
+#include "der-exception.hpp"
+#include "../../util/logging.hpp"
+#include "der.hpp"
+
+INIT_LOGGER("ndn.der.DER");
+
+using namespace std;
+using namespace ndn::ptr_lib;
+
+namespace ndn {
+
+namespace der {
+
+/*
+ * DerNode
+ */
+DerNode::DerNode()
+ :m_parent(0)
+{}
+
+DerNode::DerNode(DerType type)
+ :m_type(type),
+ m_parent(0)
+{}
+
+DerNode::DerNode(std::istream& start)
+ :m_parent(0)
+{
+ decode(start);
+}
+
+DerNode::~DerNode()
+{}
+
+void
+DerNode::encodeHeader(int size)
+{
+ m_header.push_back((char)m_type);
+
+ if(size >= 127)
+ {
+ int val = size;
+ char buf[sizeof(val) + 1];
+ char *p = &(buf[sizeof(buf)-1]);
+ int n = 0;
+ int mask = (1 << 8) - 1;
+
+ while(val != 0)
+ {
+ p[0] = (char)(val & mask);
+ p--;
+ n++;
+ val >>= 8;
+ }
+
+ p[0] = (char)((1<<7) | n);
+ n++;
+
+ m_header.insert(m_header.end(), p, p+n);
+ }
+ else if(size >= 0)
+ {
+ m_header.push_back((char)size);
+ }
+ else
+ throw NegativeLengthException("Negative length");
+}
+
+int
+DerNode::decodeHeader(istream& start)
+{
+ uint8_t type = start.get();
+ // char type = start.get();
+ m_header.push_back(type);
+ m_type = static_cast<DerType>((int)type);
+
+ uint8_t sizeLen = start.get();
+ // char sizeLen = start.get();
+ m_header.push_back(sizeLen);
+
+ bool longFormat = sizeLen & (1 << 7);
+
+ if(!longFormat)
+ {
+ // _LOG_DEBUG("Short Format");
+ // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
+ return (int)sizeLen;
+ }
+ else
+ {
+ // _LOG_DEBUG("Long Format");
+ uint8_t byte;
+ // char byte;
+ int lenCount = sizeLen & ((1<<7) - 1);
+ // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
+ // _LOG_DEBUG("mask: " << (int)((1<<7) - 1));
+ // _LOG_DEBUG("lenCount: " << (int)lenCount);
+ int size = 0;
+ do
+ {
+ byte = start.get();
+ m_header.push_back(byte);
+ size = size * 256 + (int)byte;
+ // _LOG_DEBUG("byte: " << (int)byte);
+ // _LOG_DEBUG("size: " << size);
+ lenCount--;
+ }
+ while(lenCount > 0);
+
+ return size;
+ }
+}
+
+void
+DerNode::encode(ostream& start)
+{
+ start.write((const char*)&m_header[0], m_header.size());
+ start.write((const char*)&m_payload[0], m_payload.size());
+}
+
+void
+DerNode::decode(istream& start)
+{
+ int payloadSize = decodeHeader(start);
+ // _LOG_DEBUG("payloadSize: " << payloadSize);
+ if(payloadSize > 0 )
+ {
+ char buf[payloadSize];
+ start.read(buf, payloadSize);
+ m_payload.insert(m_payload.end(), buf, buf + payloadSize);
+ }
+}
+
+shared_ptr<DerNode>
+DerNode::parse(istream& start)
+{
+ int type = ((uint8_t)start.peek());
+
+ // _LOG_DEBUG("Type: " << hex << setw(2) << setfill('0') << type);
+ switch(type) {
+ case DER_BOOLEAN:
+ return shared_ptr<DerBool>(new DerBool(start));
+ case DER_INTEGER:
+ return shared_ptr<DerInteger>(new DerInteger(start));
+ case DER_BIT_STRING:
+ return shared_ptr<DerBitString>(new DerBitString(start));
+ case DER_OCTET_STRING:
+ return shared_ptr<DerOctetString>(new DerOctetString(start));
+ case DER_NULL:
+ return shared_ptr<DerNull>(new DerNull(start));
+ case DER_OBJECT_IDENTIFIER:
+ return shared_ptr<DerOid>(new DerOid(start));
+ case DER_SEQUENCE:
+ return shared_ptr<DerSequence>(new DerSequence(start));
+ case DER_PRINTABLE_STRING:
+ return shared_ptr<DerPrintableString>(new DerPrintableString(start));
+ case DER_GENERALIZED_TIME:
+ return shared_ptr<DerGtime>(new DerGtime(start));
+ default:
+ throw DerDecodingException("Unimplemented DER types");
+ }
+}
+
+
+/*
+ * DerComplex
+ */
+DerComplex::DerComplex()
+ :DerNode(),
+ m_childChanged(false),
+ m_size(0)
+{}
+
+DerComplex::DerComplex(DerType type)
+ :DerNode(type),
+ m_childChanged(false),
+ m_size(0)
+{}
+
+DerComplex::DerComplex(istream& start)
+ :DerNode(),
+ m_childChanged(false),
+ m_size(0)
+{
+ m_size = DerNode::decodeHeader(start);
+ // _LOG_DEBUG("Size: " << m_size);
+
+ int accSize = 0;
+
+ while(accSize < m_size)
+ {
+ // _LOG_DEBUG("accSize: " << accSize);
+ shared_ptr<DerNode> nodePtr = DerNode::parse(start);
+ accSize += nodePtr->getSize();
+ addChild(nodePtr, false);
+ }
+}
+
+DerComplex::~DerComplex()
+{}
+
+int
+DerComplex::getSize()
+{
+ if(m_childChanged)
+ {
+ updateSize();
+ m_childChanged = false;
+ }
+
+ m_header.clear();
+ DerNode::encodeHeader(m_size);
+ return m_size + m_header.size();
+}
+
+shared_ptr<vector<uint8_t> >
+DerComplex::getRaw()
+{
+ shared_ptr<vector<uint8_t> > blob(new vector<uint8_t>());
+ blob->insert(blob->end(), m_header.begin(), m_header.end());
+
+ DerNodePtrList::iterator it = m_nodeList.begin();
+ for(; it != m_nodeList.end(); it++)
+ {
+ shared_ptr<vector<uint8_t> > childBlob = (*it)->getRaw();
+ blob->insert(blob->end(), childBlob->begin(), childBlob->end());
+ }
+ return blob;
+}
+
+void
+DerComplex::updateSize()
+{
+ int newSize = 0;
+
+ DerNodePtrList::iterator it = m_nodeList.begin();
+ for(; it != m_nodeList.end(); it++)
+ {
+ newSize += (*it)->getSize();
+ }
+
+ m_size = newSize;
+ m_childChanged = false;
+}
+
+void
+DerComplex::addChild(shared_ptr<DerNode> nodePtr, bool notifyParent)
+{
+ nodePtr->setParent(this);
+
+ m_nodeList.push_back(nodePtr);
+
+ if(!notifyParent)
+ return;
+
+ if(m_childChanged)
+ return;
+ else
+ m_childChanged = true;
+
+ if(0 != m_parent)
+ m_parent->setChildChanged();
+}
+
+void
+DerComplex::setChildChanged()
+{
+ if(0 != m_parent && !m_childChanged)
+ {
+ m_parent->setChildChanged();
+ m_childChanged = true;
+ }
+ else
+ m_childChanged = true;
+}
+
+void
+DerComplex::encode(ostream& start)
+{
+ updateSize();
+ m_header.clear();
+
+ DerNode::encodeHeader(m_size);
+
+ start.write((const char*)&m_header[0], m_header.size());
+
+ DerNodePtrList::iterator it = m_nodeList.begin();
+ for(; it != m_nodeList.end(); it++)
+ (*it)->encode(start);
+}
+
+
+/*
+ * DerByteString
+ */
+DerByteString::DerByteString(const string& str, DerType type)
+ :DerNode(type)
+{
+ m_payload.insert(m_payload.end(), str.begin(), str.end());
+
+ DerNode::encodeHeader(m_payload.size());
+}
+
+DerByteString::DerByteString(const std::vector<uint8_t>& blob, DerType type)
+ :DerNode(type)
+{
+ m_payload.insert(m_payload.end(), blob.begin(), blob.end());
+
+ DerNode::encodeHeader(m_payload.size());
+}
+
+DerByteString::DerByteString(istream& start)
+ :DerNode(start)
+{}
+
+DerByteString::~DerByteString()
+{}
+
+
+/*
+ * DerBool
+ */
+DerBool::DerBool(bool value)
+ :DerNode(DER_BOOLEAN)
+
+{
+ char payload = (value ? 0xFF : 0x00);
+ m_payload.push_back(payload);
+
+ DerNode::encodeHeader(m_payload.size());
+}
+
+DerBool::DerBool(istream& start)
+ :DerNode(start)
+{}
+
+DerBool::~DerBool()
+{}
+
+
+/*
+ * DerInteger
+ */
+DerInteger::DerInteger(const vector<uint8_t>& blob)
+ :DerNode(DER_INTEGER)
+{
+ m_payload.insert(m_payload.end(), blob.begin(), blob.end());
+
+ DerNode::encodeHeader(m_payload.size());
+}
+
+DerInteger::DerInteger(istream& start)
+ :DerNode(start)
+{}
+
+DerInteger::~DerInteger()
+{}
+
+
+/*
+ * DerBitString
+ */
+DerBitString::DerBitString(const vector<uint8_t>& blob, uint8_t paddingLen)
+ :DerNode(DER_BIT_STRING)
+{
+ m_payload.push_back((char)paddingLen);
+ m_payload.insert(m_payload.end(), blob.begin(), blob.end());
+
+ DerNode::encodeHeader(m_payload.size());
+}
+
+DerBitString::DerBitString(istream& start)
+ :DerNode(start)
+{}
+
+DerBitString::~DerBitString()
+{}
+
+
+/*
+ * DerOctetString
+ */
+DerOctetString::DerOctetString(const string& str)
+ :DerByteString(str, DER_OCTET_STRING)
+{}
+
+DerOctetString::DerOctetString(const vector<uint8_t>& blob)
+ :DerByteString(blob, DER_OCTET_STRING)
+{}
+
+DerOctetString::DerOctetString(istream& start)
+ :DerByteString(start)
+{}
+
+DerOctetString::~DerOctetString()
+{}
+
+
+/*
+ * DerNull
+ */
+DerNull::DerNull()
+ :DerNode(DER_NULL)
+{
+ DerNode::encodeHeader(0);
+}
+
+DerNull::DerNull(istream& start)
+ :DerNode(start)
+{}
+
+DerNull::~DerNull()
+{}
+
+
+/*
+ * DerOid
+ */
+DerOid::DerOid(const OID& oid)
+ :DerNode(DER_OBJECT_IDENTIFIER)
+{
+ prepareEncoding(oid.getIntegerList());
+}
+
+
+DerOid::DerOid(const string& oidStr)
+ :DerNode(DER_OBJECT_IDENTIFIER)
+{
+ vector<int> value;
+
+ string str = oidStr + ".";
+
+ size_t pos = 0;
+ size_t ppos = 0;
+
+ while(string::npos != pos){
+ ppos = pos;
+
+ pos = str.find_first_of('.', pos);
+ if(string::npos == pos)
+ break;
+
+ value.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
+
+ pos++;
+ }
+
+ prepareEncoding(value);
+}
+
+DerOid::DerOid(const vector<int>& value)
+ :DerNode(DER_OBJECT_IDENTIFIER)
+{
+ prepareEncoding(value);
+}
+
+DerOid::DerOid(istream& start)
+ :DerNode(start)
+{}
+
+DerOid::~DerOid()
+{}
+
+void
+DerOid::prepareEncoding(const vector<int>& value)
+{
+ ostringstream os;
+
+ int firstNumber = 0;
+
+ if(value.size() >= 1){
+ if(0 <= value[0] && 2 >= value[0])
+ firstNumber = value[0] * 40;
+ else
+ throw DerEncodingException("first integer of oid is out of range");
+ }
+ else
+ throw DerEncodingException("no integer in oid");
+
+ if(value.size() >= 2){
+ if(0 <= value[1] && 39 >= value[1])
+ firstNumber += value[1];
+ else
+ throw DerEncodingException("second integer of oid is out of range");
+ }
+
+ encode128(firstNumber, os);
+
+ if(value.size() > 2){
+ int i = 2;
+ for(; i < value.size(); i++)
+ encode128(value[i], os);
+ }
+
+ string output = os.str();
+ DerNode::encodeHeader(output.size());
+
+ m_payload.insert(m_payload.end(), output.begin(), output.end());
+}
+
+void
+DerOid::encode128(int value, ostringstream& os)
+{
+ int mask = (1 << 7) - 1;
+
+ if(128 > value)
+ {
+ uint8_t singleByte = (uint8_t) mask & value;
+ os.write((char *)&singleByte, 1);
+ }
+ else{
+ uint8_t buf[(sizeof(value)*8 + 6)/7 + 1];
+ uint8_t *p = &(buf[sizeof(buf)-1]);
+ int n = 1;
+
+ p[0] = (uint8_t)(value & mask);
+ value >>= 7;
+
+ while(value != 0)
+ {
+ (--p)[0] = (uint8_t)((value & mask) | (1 << 7));
+ n++;
+ value >>= 7;
+ }
+
+ os.write((char *)p, n);
+ }
+}
+
+int
+DerOid::decode128(int & offset)
+{
+ uint8_t flagMask = 0x80;
+ int result = 0;
+ while(m_payload[offset] & flagMask){
+ result = 128 * result + (uint8_t) m_payload[offset] - 128;
+ offset++;
+ }
+
+ result = result * 128 + m_payload[offset];
+ offset++;
+
+ return result;
+}
+
+
+/*
+ * DerSequence
+ */
+DerSequence::DerSequence()
+ :DerComplex(DER_SEQUENCE)
+{}
+
+DerSequence::DerSequence(istream& start)
+ :DerComplex(start)
+{}
+
+DerSequence::~DerSequence()
+{}
+
+
+/*
+ * DerPrintableString
+ */
+DerPrintableString::DerPrintableString(const string& str)
+ :DerByteString(str, DER_PRINTABLE_STRING)
+{}
+
+DerPrintableString::DerPrintableString(const vector<uint8_t>& blob)
+ :DerByteString(blob, DER_PRINTABLE_STRING)
+{}
+
+DerPrintableString::DerPrintableString(istream& start)
+ :DerByteString(start)
+{}
+
+DerPrintableString::~DerPrintableString()
+{}
+
+
+/*
+ * DerGtime
+ */
+DerGtime::DerGtime(const Time& time)
+ :DerNode(DER_GENERALIZED_TIME)
+{
+ string pTimeStr = toIsoString(time);
+ int index = pTimeStr.find_first_of('T');
+ string derTime = pTimeStr.substr(0, index) + pTimeStr.substr(index+1, pTimeStr.size() - index -1) + "Z";
+ m_payload.insert(m_payload.end(), derTime.begin(), derTime.end());
+
+ DerNode::encodeHeader(m_payload.size());
+}
+
+DerGtime::DerGtime(istream& start)
+ :DerNode(start)
+{}
+
+DerGtime::~DerGtime()
+{}
+
+string DerGtime::toIsoString(const Time& time)
+{
+#if 1
+ throw std::runtime_error("not implemented");
+#endif
+}
+
+Time DerGtime::fromIsoString(const string& isoString)
+{
+#if 1
+ throw std::runtime_error("not implemented");
+#endif
+}
+
+} // der
+
+}
diff --git a/ndn-cpp/encoding/der/der.hpp b/ndn-cpp/encoding/der/der.hpp
index 065cfd6..52dde00 100644
--- a/ndn-cpp/encoding/der/der.hpp
+++ b/ndn-cpp/encoding/der/der.hpp
@@ -205,11 +205,10 @@
virtual
~DerBool();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
-
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
};
//0x02
@@ -223,11 +222,10 @@
virtual
~DerInteger();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
-
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
};
//0x03
@@ -241,11 +239,10 @@
virtual
~DerBitString();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
-
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
};
//0x04
@@ -261,11 +258,10 @@
virtual
~DerOctetString();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
-
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
};
@@ -280,11 +276,10 @@
virtual
~DerNull();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
-
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
};
@@ -303,10 +298,10 @@
virtual
~DerOid();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
int
decode128(int& offset);
@@ -331,11 +326,10 @@
virtual
~DerSequence();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
-
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
};
//0x13
@@ -351,10 +345,10 @@
virtual
~DerPrintableString();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
};
//0x1b
@@ -368,11 +362,24 @@
virtual
~DerGtime();
- virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
- virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
- virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
- virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
+ virtual void accept(VoidNoArgumentsVisitor& visitor) { visitor.visit(*this); }
+ virtual void accept(VoidVisitor& visitor, ndnboost::any param) { visitor.visit(*this, param); }
+ virtual ndnboost::any accept(NoArgumentsVisitor& visitor) { return visitor.visit(*this); }
+ virtual ndnboost::any accept(Visitor& visitor, ndnboost::any param) { return visitor.visit(*this, param); }
+ /**
+ * Convert to the ISO string representation of the time.
+ * @param time Milliseconds since 1/1/1970.
+ * @return The ISO string.
+ */
+ static std::string toIsoString(const Time& time);
+
+ /**
+ * Convert from the ISO string representation to the internal time format.
+ * @param isoString The ISO time formatted string.
+ * @return The time in milliseconds since 1/1/1970.
+ */
+ static Time fromIsoString(const std::string& isoString);
};
} // der
diff --git a/ndn-cpp/encoding/der/visitor/simple-visitor.cpp b/ndn-cpp/encoding/der/visitor/simple-visitor.cpp
index 8539950..c56f999 100644
--- a/ndn-cpp/encoding/der/visitor/simple-visitor.cpp
+++ b/ndn-cpp/encoding/der/visitor/simple-visitor.cpp
@@ -6,9 +6,6 @@
* See COPYING for copyright and distribution information.
*/
-#if 1 // TODO: Remove this when we don't throw "not implemented".
-#include <stdexcept>
-#endif
#include "simple-visitor.hpp"
#include "../der.hpp"
#include <ndn-cpp/encoding/oid.hpp>
@@ -65,7 +62,6 @@
ndnboost::any
SimpleVisitor::visit(DerOid& derOid)
{
-#if 0 // Include again when der is defined.
vector<int> intList;
int offset = 0;
@@ -83,9 +79,6 @@
}
return ndnboost::any(OID(intList));
-#else
- throw std::runtime_error("not implemented");
-#endif
}
ndnboost::any
@@ -94,14 +87,12 @@
return ndnboost::any();
}
-#if 0 // TODO: Implmenent alternative to boost::posix_time::from_iso_string.
ndnboost::any
SimpleVisitor::visit(DerGtime& derGtime)
{
string str((const char*)&derGtime.getPayload()[0], derGtime.getPayload().size());
- return ndnboost::any(boost::posix_time::from_iso_string(str.substr(0, 8) + "T" + str.substr(8, 6)));
+ return ndnboost::any(DerGtime::fromIsoString(str.substr(0, 8) + "T" + str.substr(8, 6)));
}
-#endif
} // der
diff --git a/ndn-cpp/security/certificate/certificate-extension.cpp b/ndn-cpp/security/certificate/certificate-extension.cpp
index d3719a7..aba88dd 100644
--- a/ndn-cpp/security/certificate/certificate-extension.cpp
+++ b/ndn-cpp/security/certificate/certificate-extension.cpp
@@ -20,7 +20,6 @@
shared_ptr<der::DerNode>
CertificateExtension::toDer()
{
-#if 0 // Include again when der is defined.
shared_ptr<der::DerSequence> root(new der::DerSequence);
shared_ptr<der::DerOid> extensionId(new der::DerOid(extensionId_));
@@ -34,9 +33,6 @@
root->getSize();
return root;
-#else
- throw std::runtime_error("not implemented");
-#endif
}
Blob
diff --git a/ndn-cpp/security/certificate/certificate-subject-description.cpp b/ndn-cpp/security/certificate/certificate-subject-description.cpp
index e66b672..ee2310c 100644
--- a/ndn-cpp/security/certificate/certificate-subject-description.cpp
+++ b/ndn-cpp/security/certificate/certificate-subject-description.cpp
@@ -6,9 +6,6 @@
* See COPYING for copyright and distribution information.
*/
-#if 1 // TODO: Remove this when we don't throw "not implemented".
-#include <stdexcept>
-#endif
#include "../../encoding/der/der.hpp"
#include <ndn-cpp/security/certificate/certificate-subject-description.hpp>
@@ -20,7 +17,6 @@
shared_ptr<der::DerNode>
CertificateSubjectDescription::toDer()
{
-#if 0 // Include again when der is defined.
shared_ptr<der::DerSequence> root(new der::DerSequence());
shared_ptr<der::DerOid> oid(new der::DerOid(oid_));
@@ -30,9 +26,6 @@
root->addChild(value);
return root;
-#else
- throw std::runtime_error("not implemented");
-#endif
}
}