blob: bc7b9bd5c6db79e134b3e69156cb61a891c25248 [file] [log] [blame]
Zhenkai Zhuf47109b2013-01-02 19:41:34 -08001#include "ccnx-name.h"
2#include <boost/lexical_cast.hpp>
3#include <ctype.h>
4#include <boost/algorithm/string/join.hpp>
5
6namespace Ccnx{
7
8CcnxCharbuf::CcnxCharbuf()
9 : m_buf(NULL)
10{
11 m_buf = ccn_charbuf_create();
12}
13
14CcnxCharbuf::CcnxCharbuf(ccn_charbuf *buf)
15 : m_buf(NULL)
16{
17 if (buf != NULL)
18 {
19 m_buf = ccn_charbuf_create();
20 ccn_charbuf_reserve(m_buf, buf->length);
21 memcpy(m_buf->buf, buf->buf, buf->length);
22 m_buf->length = buf->length;
23 }
24}
25
26CcnxCharbuf::~CcnxCharbuf()
27{
28 ccn_charbuf_destroy(&m_buf);
29}
30
31Name::Name()
32{
33}
34
35Name::Name(const string &name)
36{
37 stringstream ss(name);
38 string compStr;
39 while(getline(ss, compStr, '/'))
40 {
41 Bytes comp(compStr.begin(), compStr.end());
42 m_comps.push_back(comp);
43 }
44}
45
46Name::Name(const vector<Bytes> &comps)
47{
48 m_comps = comps;
49}
50
51Name::Name(const Name &other)
52{
53 m_comps = other.m_comps;
54}
55
56Name::Name(const unsigned char *data, const ccn_indexbuf *comps)
57{
58 for (int i = 0; i < comps->n - 1; i++)
59 {
60 const unsigned char *compPtr;
61 size_t size;
62 ccn_name_comp_get(data, comps, i, &compPtr, &size);
63 Bytes comp;
64 readRaw(comp, compPtr, size);
65 m_comps.push_back(comp);
66 }
67}
68
69CcnxCharbufPtr
70Name::toCcnxCharbuf() const
71{
72 CcnxCharbufPtr ptr(new CcnxCharbuf());
73 ccn_charbuf *cbuf = ptr->getBuf();
74 ccn_name_init(cbuf);
75 int size = m_comps.size();
76 for (int i = 0; i < size; i++)
77 {
78 ccn_name_append(cbuf, head(m_comps[i]), m_comps[i].size());
79 }
80 return ptr;
81}
82
83Name &
84Name::appendComp(const Bytes &comp)
85{
86 m_comps.push_back(comp);
87 return *this;
88}
89
90Name &
91Name::appendComp(const string &compStr)
92{
93 Bytes comp(compStr.begin(), compStr.end());
94 appendComp(comp);
95 return *this;
96}
97
98Bytes
99Name::getComp(int index) const
100{
101 if (index >= m_comps.size())
102 {
103 boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
104 }
105 return m_comps[index];
106}
107
108string
109Name::getCompAsString(int index) const
110{
111 Bytes comp = getComp(index);
112 stringstream ss(stringstream::out);
113 int size = comp.size();
114 for (int i = 0; i < size; i++)
115 {
116 unsigned char ch = comp[i];
117 if (isprint(ch))
118 {
119 ss << (char) ch;
120 }
121 else
122 {
123 ss << "%" << hex << setfill('0') << setw(2) << ch;
124 }
125 }
126
127 return ss.str();
128}
129
130Name
131Name::getPartialName(int start, int n) const
132{
133 int size = m_comps.size();
134 if (start < 0 || start >= size || start + n > size)
135 {
136 stringstream ss(stringstream::out);
137 ss << "getPartialName() parameter out of range! ";
138 ss << "start = " << start;
139 ss << "n = " << n;
140 ss << "size = " << size;
141 boost::throw_exception(NameException() << error_info_str(ss.str()));
142 }
143
144 vector<Bytes> comps;
145 for (int i = 0; i < n; i++)
146 {
147 comps.push_back(m_comps[start + i]);
148 }
149 return Name(comps);
150}
151
152ostream &
153operator <<(ostream &os, const Name &name)
154{
155 int size = name.size();
156 vector<string> strComps;
157 for (int i = 0; i < size; i++)
158 {
159 strComps.push_back(name.getCompAsString(i));
160 }
161 string joined = boost::algorithm::join(strComps, "/");
162 os << "/" << joined;
163 return os;
164}
165
166
167Selectors::Selectors()
168 : m_maxSuffixComps(-1)
169 , m_minSuffixComps(-1)
170 , m_answerOriginKind(AOK_DEFAULT)
171 , m_interestLifetime(-1.0)
172 , m_scope(-1)
173 , m_childSelector(DEFAULT)
174{
175}
176
177Selectors::Selectors(const Selectors &other)
178{
179 m_maxSuffixComps = other.m_maxSuffixComps;
180 m_minSuffixComps = other.m_minSuffixComps;
181 m_answerOriginKind = other.m_answerOriginKind;
182 m_interestLifetime = other.m_interestLifetime;
183 m_scope = other.m_scope;
184 m_childSelector = other.m_childSelector;
185 m_publisherPublicKeyDigest = other.m_publisherPublicKeyDigest;
186}
187
188CcnxCharbufPtr
189Selectors::toCcnxCharbuf()
190{
191 CcnxCharbufPtr ptr(new CcnxCharbuf());
192 ccn_charbuf *cbuf = ptr->getBuf();
193 ccn_charbuf_append_tt(cbuf, CCN_DTAG_Interest, CCN_DTAG);
194 ccn_charbuf_append_tt(cbuf, CCN_DTAG_Name, CCN_DTAG);
195 ccn_charbuf_append_closer(cbuf); // </Name>
196
197 if (m_maxSuffixComps < m_minSuffixComps)
198 {
199 boost::throw_exception(InterestSelectorException() << error_info_str("MaxSuffixComps = " + boost::lexical_cast<string>(m_maxSuffixComps) + " is smaller than MinSuffixComps = " + boost::lexical_cast<string>(m_minSuffixComps)));
200 }
201
202 if (m_maxSuffixComps > 0)
203 {
204 ccnb_tagged_putf(cbuf, CCN_DTAG_MaxSuffixComponents, "%d", m_maxSuffixComps);
205 }
206
207 if (m_minSuffixComps > 0)
208 {
209 ccnb_tagged_putf(cbuf, CCN_DTAG_MinSuffixComponents, "%d", m_minSuffixComps);
210 }
211
212 if (m_answerOriginKind != AOK_DEFAULT)
213 {
214 // it was not using "ccnb_tagged_putf" in ccnx c code, no idea why
215 ccn_charbuf_append_tt(cbuf, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
216 ccnb_append_number(cbuf, m_answerOriginKind);
217 ccn_charbuf_append_closer(cbuf); // <AnswerOriginKind>
218 }
219
220 if (m_scope != -1)
221 {
222 ccnb_tagged_putf(cbuf, CCN_DTAG_Scope, "%d", m_scope);
223 }
224
225 if (m_interestLifetime > 0.0)
226 {
227 // Ccnx timestamp unit is weird 1/4096 second
228 // this is from their code
229 unsigned lifetime = 4096 * (m_interestLifetime + 1.0/8192.0);
230 if (lifetime == 0 || lifetime > (30 << 12))
231 {
232 boost::throw_exception(InterestSelectorException() << error_info_str("Ccnx requires 0 < lifetime < 30.0. lifetime= " + boost::lexical_cast<string>(m_interestLifetime)));
233 }
234 unsigned char buf[3] = {0};
235 for (int i = sizeof(buf) - 1; i >= 0; i--, lifetime >>= 8)
236 {
237 buf[i] = lifetime & 0xff;
238 }
239 ccnb_append_tagged_blob(cbuf, CCN_DTAG_InterestLifetime, buf, sizeof(buf));
240 }
241
242 if (m_childSelector != DEFAULT)
243 {
244 ccnb_tagged_putf(cbuf, CCN_DTAG_ChildSelector, "%d", m_childSelector);
245 }
246
247
248 ccn_charbuf_append_closer(cbuf); // </Interest>
249
250 return ptr;
251}
252
253} // Ccnx