blob: 9bc26630688a05faac434e39162b2cccdd28df01 [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{
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -08007CcnxCharbufPtr CcnxCharbuf::Null;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -08008
Zhenkai Zhub0adefe2013-01-04 21:56:38 -08009void
10CcnxCharbuf::init(ccn_charbuf *buf)
11{
12 if (buf != NULL)
13 {
14 m_buf = ccn_charbuf_create();
15 ccn_charbuf_reserve(m_buf, buf->length);
16 memcpy(m_buf->buf, buf->buf, buf->length);
17 m_buf->length = buf->length;
18 }
19}
20
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080021CcnxCharbuf::CcnxCharbuf()
22 : m_buf(NULL)
23{
24 m_buf = ccn_charbuf_create();
25}
26
27CcnxCharbuf::CcnxCharbuf(ccn_charbuf *buf)
28 : m_buf(NULL)
29{
Zhenkai Zhub0adefe2013-01-04 21:56:38 -080030 init(buf);
31}
32
33CcnxCharbuf::CcnxCharbuf(const CcnxCharbuf &other)
34 : m_buf (NULL)
35{
36 init(other.m_buf);
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080037}
38
39CcnxCharbuf::~CcnxCharbuf()
40{
41 ccn_charbuf_destroy(&m_buf);
42}
43
44Name::Name()
45{
46}
47
48Name::Name(const string &name)
49{
50 stringstream ss(name);
51 string compStr;
Zhenkai Zhu3b82d432013-01-03 22:48:40 -080052 bool first = true;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080053 while(getline(ss, compStr, '/'))
54 {
Zhenkai Zhu3b82d432013-01-03 22:48:40 -080055 // discard the first empty comp before the first '/'
56 if (first)
57 {
58 first = false;
59 continue;
60 }
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080061 Bytes comp(compStr.begin(), compStr.end());
62 m_comps.push_back(comp);
63 }
64}
65
66Name::Name(const vector<Bytes> &comps)
67{
68 m_comps = comps;
69}
70
71Name::Name(const Name &other)
72{
73 m_comps = other.m_comps;
74}
75
76Name::Name(const unsigned char *data, const ccn_indexbuf *comps)
77{
78 for (int i = 0; i < comps->n - 1; i++)
79 {
80 const unsigned char *compPtr;
81 size_t size;
82 ccn_name_comp_get(data, comps, i, &compPtr, &size);
83 Bytes comp;
84 readRaw(comp, compPtr, size);
85 m_comps.push_back(comp);
86 }
87}
88
Alexander Afanasyevd09871f2013-01-04 22:36:37 -080089Name::Name (const unsigned char *buf, const size_t length)
90{
91 ccn_indexbuf *idx = ccn_indexbuf_create();
92 const ccn_charbuf namebuf = { length, length, const_cast<unsigned char *> (buf) };
93 ccn_name_split (&namebuf, idx);
94
95 const unsigned char *compPtr = NULL;
96 size_t size = 0;
97 int i = 0;
98 while (ccn_name_comp_get(namebuf.buf, idx, i, &compPtr, &size) == 0)
99 {
100 Bytes comp;
101 readRaw (comp, compPtr, size);
102 m_comps.push_back(comp);
103 i++;
104 }
105 ccn_indexbuf_destroy(&idx);
106}
107
108
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800109Name &
110Name::operator=(const Name &other)
111{
112 m_comps = other.m_comps;
113 return *this;
114}
115bool
Zhenkai Zhu3b82d432013-01-03 22:48:40 -0800116Name::operator==(const string &str) const
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800117{
118 return this->toString() == str;
119}
120
121bool
Zhenkai Zhu3b82d432013-01-03 22:48:40 -0800122Name::operator!=(const string &str) const
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800123{
124 return !(*this == str);
125}
126
127Name
128operator+(const Name &n1, const Name &n2)
129{
130 vector<Bytes> comps = n1.m_comps;
131 copy(n2.m_comps.begin(), n2.m_comps.end(), back_inserter(comps));
132 return Name(comps);
133}
134
135string
136Name::toString() const
137{
138 stringstream ss(stringstream::out);
139 ss << *this;
140 return ss.str();
141}
142
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800143CcnxCharbufPtr
144Name::toCcnxCharbuf() const
145{
146 CcnxCharbufPtr ptr(new CcnxCharbuf());
147 ccn_charbuf *cbuf = ptr->getBuf();
148 ccn_name_init(cbuf);
149 int size = m_comps.size();
150 for (int i = 0; i < size; i++)
151 {
152 ccn_name_append(cbuf, head(m_comps[i]), m_comps[i].size());
153 }
154 return ptr;
155}
156
157Name &
158Name::appendComp(const Bytes &comp)
159{
160 m_comps.push_back(comp);
161 return *this;
162}
163
164Name &
165Name::appendComp(const string &compStr)
166{
167 Bytes comp(compStr.begin(), compStr.end());
168 appendComp(comp);
169 return *this;
170}
171
172Bytes
173Name::getComp(int index) const
174{
175 if (index >= m_comps.size())
176 {
177 boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
178 }
179 return m_comps[index];
180}
181
182string
183Name::getCompAsString(int index) const
184{
185 Bytes comp = getComp(index);
186 stringstream ss(stringstream::out);
187 int size = comp.size();
188 for (int i = 0; i < size; i++)
189 {
190 unsigned char ch = comp[i];
191 if (isprint(ch))
192 {
193 ss << (char) ch;
194 }
195 else
196 {
197 ss << "%" << hex << setfill('0') << setw(2) << ch;
198 }
199 }
200
201 return ss.str();
202}
203
204Name
205Name::getPartialName(int start, int n) const
206{
207 int size = m_comps.size();
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800208 if (start < 0 || start >= size || n > 0 && start + n > size)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800209 {
210 stringstream ss(stringstream::out);
211 ss << "getPartialName() parameter out of range! ";
212 ss << "start = " << start;
213 ss << "n = " << n;
214 ss << "size = " << size;
215 boost::throw_exception(NameException() << error_info_str(ss.str()));
216 }
217
218 vector<Bytes> comps;
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800219 int end;
220 if (n > 0)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800221 {
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800222 end = start + n;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800223 }
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800224 else
225 {
226 end = size;
227 }
228
229 for (int i = start; i < end; i++)
230 {
231 comps.push_back(m_comps[i]);
232 }
233
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800234 return Name(comps);
235}
236
237ostream &
238operator <<(ostream &os, const Name &name)
239{
240 int size = name.size();
241 vector<string> strComps;
242 for (int i = 0; i < size; i++)
243 {
244 strComps.push_back(name.getCompAsString(i));
245 }
246 string joined = boost::algorithm::join(strComps, "/");
247 os << "/" << joined;
248 return os;
249}
250
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800251bool
252operator ==(const Name &n1, const Name &n2)
253{
254 stringstream ss1(stringstream::out);
255 stringstream ss2(stringstream::out);
256 ss1 << n1;
257 ss2 << n2;
258 return ss1.str() == ss2.str();
259}
260
261bool
262operator !=(const Name &n1, const Name &n2)
263{
264 return !(n1 == n2);
265}
266
267bool
268operator <(const Name &n1, const Name &n2)
269{
270 stringstream ss1(stringstream::out);
271 stringstream ss2(stringstream::out);
272 ss1 << n1;
273 ss2 << n2;
274 return ss1.str() < ss2.str();
275}
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800276
277Selectors::Selectors()
278 : m_maxSuffixComps(-1)
279 , m_minSuffixComps(-1)
280 , m_answerOriginKind(AOK_DEFAULT)
281 , m_interestLifetime(-1.0)
282 , m_scope(-1)
283 , m_childSelector(DEFAULT)
284{
285}
286
287Selectors::Selectors(const Selectors &other)
288{
289 m_maxSuffixComps = other.m_maxSuffixComps;
290 m_minSuffixComps = other.m_minSuffixComps;
291 m_answerOriginKind = other.m_answerOriginKind;
292 m_interestLifetime = other.m_interestLifetime;
293 m_scope = other.m_scope;
294 m_childSelector = other.m_childSelector;
295 m_publisherPublicKeyDigest = other.m_publisherPublicKeyDigest;
296}
297
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800298bool
299Selectors::operator == (const Selectors &other)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800300{
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800301 return m_maxSuffixComps == other.m_maxSuffixComps
302 && m_minSuffixComps == other.m_minSuffixComps
303 && m_answerOriginKind == other.m_answerOriginKind
304 && (m_interestLifetime - other.m_interestLifetime) < 10e-4
305 && m_scope == other.m_scope
306 && m_childSelector == other.m_childSelector;
307}
308
309bool
310Selectors::isEmpty() const
311{
312 return m_maxSuffixComps == -1
313 && m_minSuffixComps == -1
314 && m_answerOriginKind == AOK_DEFAULT
315 && (m_interestLifetime - (-1.0)) < 10e-4
316 && m_scope == -1
317 && m_childSelector == DEFAULT;
318}
319
320
321CcnxCharbufPtr
322Selectors::toCcnxCharbuf() const
323{
324 if (isEmpty())
325 {
326 return CcnxCharbuf::Null;
327 }
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800328 CcnxCharbufPtr ptr(new CcnxCharbuf());
329 ccn_charbuf *cbuf = ptr->getBuf();
330 ccn_charbuf_append_tt(cbuf, CCN_DTAG_Interest, CCN_DTAG);
331 ccn_charbuf_append_tt(cbuf, CCN_DTAG_Name, CCN_DTAG);
332 ccn_charbuf_append_closer(cbuf); // </Name>
333
334 if (m_maxSuffixComps < m_minSuffixComps)
335 {
336 boost::throw_exception(InterestSelectorException() << error_info_str("MaxSuffixComps = " + boost::lexical_cast<string>(m_maxSuffixComps) + " is smaller than MinSuffixComps = " + boost::lexical_cast<string>(m_minSuffixComps)));
337 }
338
339 if (m_maxSuffixComps > 0)
340 {
341 ccnb_tagged_putf(cbuf, CCN_DTAG_MaxSuffixComponents, "%d", m_maxSuffixComps);
342 }
343
344 if (m_minSuffixComps > 0)
345 {
346 ccnb_tagged_putf(cbuf, CCN_DTAG_MinSuffixComponents, "%d", m_minSuffixComps);
347 }
348
349 if (m_answerOriginKind != AOK_DEFAULT)
350 {
351 // it was not using "ccnb_tagged_putf" in ccnx c code, no idea why
352 ccn_charbuf_append_tt(cbuf, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
353 ccnb_append_number(cbuf, m_answerOriginKind);
354 ccn_charbuf_append_closer(cbuf); // <AnswerOriginKind>
355 }
356
357 if (m_scope != -1)
358 {
359 ccnb_tagged_putf(cbuf, CCN_DTAG_Scope, "%d", m_scope);
360 }
361
362 if (m_interestLifetime > 0.0)
363 {
364 // Ccnx timestamp unit is weird 1/4096 second
365 // this is from their code
366 unsigned lifetime = 4096 * (m_interestLifetime + 1.0/8192.0);
367 if (lifetime == 0 || lifetime > (30 << 12))
368 {
369 boost::throw_exception(InterestSelectorException() << error_info_str("Ccnx requires 0 < lifetime < 30.0. lifetime= " + boost::lexical_cast<string>(m_interestLifetime)));
370 }
371 unsigned char buf[3] = {0};
372 for (int i = sizeof(buf) - 1; i >= 0; i--, lifetime >>= 8)
373 {
374 buf[i] = lifetime & 0xff;
375 }
376 ccnb_append_tagged_blob(cbuf, CCN_DTAG_InterestLifetime, buf, sizeof(buf));
377 }
378
379 if (m_childSelector != DEFAULT)
380 {
381 ccnb_tagged_putf(cbuf, CCN_DTAG_ChildSelector, "%d", m_childSelector);
382 }
383
384
385 ccn_charbuf_append_closer(cbuf); // </Interest>
386
387 return ptr;
388}
389
390} // Ccnx