add Name and Selector classes
diff --git a/src/ccnx-name.cpp b/src/ccnx-name.cpp
new file mode 100644
index 0000000..bc7b9bd
--- /dev/null
+++ b/src/ccnx-name.cpp
@@ -0,0 +1,253 @@
+#include "ccnx-name.h"
+#include <boost/lexical_cast.hpp>
+#include <ctype.h>
+#include <boost/algorithm/string/join.hpp>
+
+namespace Ccnx{
+
+CcnxCharbuf::CcnxCharbuf()
+ : m_buf(NULL)
+{
+ m_buf = ccn_charbuf_create();
+}
+
+CcnxCharbuf::CcnxCharbuf(ccn_charbuf *buf)
+ : m_buf(NULL)
+{
+ if (buf != NULL)
+ {
+ m_buf = ccn_charbuf_create();
+ ccn_charbuf_reserve(m_buf, buf->length);
+ memcpy(m_buf->buf, buf->buf, buf->length);
+ m_buf->length = buf->length;
+ }
+}
+
+CcnxCharbuf::~CcnxCharbuf()
+{
+ ccn_charbuf_destroy(&m_buf);
+}
+
+Name::Name()
+{
+}
+
+Name::Name(const string &name)
+{
+ stringstream ss(name);
+ string compStr;
+ while(getline(ss, compStr, '/'))
+ {
+ Bytes comp(compStr.begin(), compStr.end());
+ m_comps.push_back(comp);
+ }
+}
+
+Name::Name(const vector<Bytes> &comps)
+{
+ m_comps = comps;
+}
+
+Name::Name(const Name &other)
+{
+ m_comps = other.m_comps;
+}
+
+Name::Name(const unsigned char *data, const ccn_indexbuf *comps)
+{
+ for (int i = 0; i < comps->n - 1; i++)
+ {
+ const unsigned char *compPtr;
+ size_t size;
+ ccn_name_comp_get(data, comps, i, &compPtr, &size);
+ Bytes comp;
+ readRaw(comp, compPtr, size);
+ m_comps.push_back(comp);
+ }
+}
+
+CcnxCharbufPtr
+Name::toCcnxCharbuf() const
+{
+ CcnxCharbufPtr ptr(new CcnxCharbuf());
+ ccn_charbuf *cbuf = ptr->getBuf();
+ ccn_name_init(cbuf);
+ int size = m_comps.size();
+ for (int i = 0; i < size; i++)
+ {
+ ccn_name_append(cbuf, head(m_comps[i]), m_comps[i].size());
+ }
+ return ptr;
+}
+
+Name &
+Name::appendComp(const Bytes &comp)
+{
+ m_comps.push_back(comp);
+ return *this;
+}
+
+Name &
+Name::appendComp(const string &compStr)
+{
+ Bytes comp(compStr.begin(), compStr.end());
+ appendComp(comp);
+ return *this;
+}
+
+Bytes
+Name::getComp(int index) const
+{
+ if (index >= m_comps.size())
+ {
+ boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
+ }
+ return m_comps[index];
+}
+
+string
+Name::getCompAsString(int index) const
+{
+ Bytes comp = getComp(index);
+ stringstream ss(stringstream::out);
+ int size = comp.size();
+ for (int i = 0; i < size; i++)
+ {
+ unsigned char ch = comp[i];
+ if (isprint(ch))
+ {
+ ss << (char) ch;
+ }
+ else
+ {
+ ss << "%" << hex << setfill('0') << setw(2) << ch;
+ }
+ }
+
+ return ss.str();
+}
+
+Name
+Name::getPartialName(int start, int n) const
+{
+ int size = m_comps.size();
+ if (start < 0 || start >= size || start + n > size)
+ {
+ stringstream ss(stringstream::out);
+ ss << "getPartialName() parameter out of range! ";
+ ss << "start = " << start;
+ ss << "n = " << n;
+ ss << "size = " << size;
+ boost::throw_exception(NameException() << error_info_str(ss.str()));
+ }
+
+ vector<Bytes> comps;
+ for (int i = 0; i < n; i++)
+ {
+ comps.push_back(m_comps[start + i]);
+ }
+ return Name(comps);
+}
+
+ostream &
+operator <<(ostream &os, const Name &name)
+{
+ int size = name.size();
+ vector<string> strComps;
+ for (int i = 0; i < size; i++)
+ {
+ strComps.push_back(name.getCompAsString(i));
+ }
+ string joined = boost::algorithm::join(strComps, "/");
+ os << "/" << joined;
+ return os;
+}
+
+
+Selectors::Selectors()
+ : m_maxSuffixComps(-1)
+ , m_minSuffixComps(-1)
+ , m_answerOriginKind(AOK_DEFAULT)
+ , m_interestLifetime(-1.0)
+ , m_scope(-1)
+ , m_childSelector(DEFAULT)
+{
+}
+
+Selectors::Selectors(const Selectors &other)
+{
+ m_maxSuffixComps = other.m_maxSuffixComps;
+ m_minSuffixComps = other.m_minSuffixComps;
+ m_answerOriginKind = other.m_answerOriginKind;
+ m_interestLifetime = other.m_interestLifetime;
+ m_scope = other.m_scope;
+ m_childSelector = other.m_childSelector;
+ m_publisherPublicKeyDigest = other.m_publisherPublicKeyDigest;
+}
+
+CcnxCharbufPtr
+Selectors::toCcnxCharbuf()
+{
+ CcnxCharbufPtr ptr(new CcnxCharbuf());
+ ccn_charbuf *cbuf = ptr->getBuf();
+ ccn_charbuf_append_tt(cbuf, CCN_DTAG_Interest, CCN_DTAG);
+ ccn_charbuf_append_tt(cbuf, CCN_DTAG_Name, CCN_DTAG);
+ ccn_charbuf_append_closer(cbuf); // </Name>
+
+ if (m_maxSuffixComps < m_minSuffixComps)
+ {
+ boost::throw_exception(InterestSelectorException() << error_info_str("MaxSuffixComps = " + boost::lexical_cast<string>(m_maxSuffixComps) + " is smaller than MinSuffixComps = " + boost::lexical_cast<string>(m_minSuffixComps)));
+ }
+
+ if (m_maxSuffixComps > 0)
+ {
+ ccnb_tagged_putf(cbuf, CCN_DTAG_MaxSuffixComponents, "%d", m_maxSuffixComps);
+ }
+
+ if (m_minSuffixComps > 0)
+ {
+ ccnb_tagged_putf(cbuf, CCN_DTAG_MinSuffixComponents, "%d", m_minSuffixComps);
+ }
+
+ if (m_answerOriginKind != AOK_DEFAULT)
+ {
+ // it was not using "ccnb_tagged_putf" in ccnx c code, no idea why
+ ccn_charbuf_append_tt(cbuf, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
+ ccnb_append_number(cbuf, m_answerOriginKind);
+ ccn_charbuf_append_closer(cbuf); // <AnswerOriginKind>
+ }
+
+ if (m_scope != -1)
+ {
+ ccnb_tagged_putf(cbuf, CCN_DTAG_Scope, "%d", m_scope);
+ }
+
+ if (m_interestLifetime > 0.0)
+ {
+ // Ccnx timestamp unit is weird 1/4096 second
+ // this is from their code
+ unsigned lifetime = 4096 * (m_interestLifetime + 1.0/8192.0);
+ if (lifetime == 0 || lifetime > (30 << 12))
+ {
+ boost::throw_exception(InterestSelectorException() << error_info_str("Ccnx requires 0 < lifetime < 30.0. lifetime= " + boost::lexical_cast<string>(m_interestLifetime)));
+ }
+ unsigned char buf[3] = {0};
+ for (int i = sizeof(buf) - 1; i >= 0; i--, lifetime >>= 8)
+ {
+ buf[i] = lifetime & 0xff;
+ }
+ ccnb_append_tagged_blob(cbuf, CCN_DTAG_InterestLifetime, buf, sizeof(buf));
+ }
+
+ if (m_childSelector != DEFAULT)
+ {
+ ccnb_tagged_putf(cbuf, CCN_DTAG_ChildSelector, "%d", m_childSelector);
+ }
+
+
+ ccn_charbuf_append_closer(cbuf); // </Interest>
+
+ return ptr;
+}
+
+} // Ccnx
diff --git a/src/ccnx-tunnel.cpp b/src/ccnx-tunnel.cpp
index 06adae0..037bd8a 100644
--- a/src/ccnx-tunnel.cpp
+++ b/src/ccnx-tunnel.cpp
@@ -28,9 +28,9 @@
}
int
-CcnxTunnel::sendInterest (const Interest &interest, Closure *closure)
+CcnxTunnel::sendInterest (const string &interest, Closure *closure)
{
- string strInterest = interest.name();
+ string strInterest = interest;
string tunneledInterest = queryRoutableName(strInterest);
Closure *cp = new TunnelClosure(closure, this, strInterest);
sendInterest(tunneledInterest, cp);
diff --git a/src/ccnx-wrapper.cpp b/src/ccnx-wrapper.cpp
index d84dc0d..1980e6e 100644
--- a/src/ccnx-wrapper.cpp
+++ b/src/ccnx-wrapper.cpp
@@ -32,17 +32,6 @@
return &bytes[0];
}
-void
-split(const string &name, Comps &comps)
-{
- stringstream ss(name);
- string comp;
- while(getline(ss, comp, '/'))
- {
- comps.push_back(comp);
- }
-}
-
CcnxWrapper::CcnxWrapper()
: m_handle (0)
, m_keyStore (0)
@@ -386,7 +375,7 @@
return CCN_UPCALL_RESULT_OK;
}
-int CcnxWrapper::sendInterest (const Interest &interest, Closure *closure)
+int CcnxWrapper::sendInterest (const string &interest, Closure *closure)
{
UniqueRecLock(m_mutex);
if (!m_running || !m_connected)
@@ -395,7 +384,7 @@
ccn_charbuf *pname = ccn_charbuf_create();
ccn_closure *dataClosure = new ccn_closure;
- ccn_name_from_uri (pname, interest.name().c_str());
+ ccn_name_from_uri (pname, interest.c_str());
dataClosure->data = (void *)closure;
dataClosure->p = &incomingData;