blob: 55d434b28b82fa87568866bdb9e9cf8dca6df5f7 [file] [log] [blame]
Alexander Afanasyev49a30d02013-01-21 21:38:48 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
19 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
20 */
21
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080022#include "ccnx-name.h"
23#include <boost/lexical_cast.hpp>
24#include <ctype.h>
25#include <boost/algorithm/string/join.hpp>
26
Alexander Afanasyev053e5ac2013-01-22 20:59:13 -080027using namespace std;
28
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080029namespace Ccnx{
30
Zhenkai Zhub0adefe2013-01-04 21:56:38 -080031void
32CcnxCharbuf::init(ccn_charbuf *buf)
33{
34 if (buf != NULL)
35 {
36 m_buf = ccn_charbuf_create();
37 ccn_charbuf_reserve(m_buf, buf->length);
38 memcpy(m_buf->buf, buf->buf, buf->length);
39 m_buf->length = buf->length;
40 }
41}
42
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080043CcnxCharbuf::CcnxCharbuf()
44 : m_buf(NULL)
45{
46 m_buf = ccn_charbuf_create();
47}
48
49CcnxCharbuf::CcnxCharbuf(ccn_charbuf *buf)
50 : m_buf(NULL)
51{
Zhenkai Zhub0adefe2013-01-04 21:56:38 -080052 init(buf);
53}
54
55CcnxCharbuf::CcnxCharbuf(const CcnxCharbuf &other)
56 : m_buf (NULL)
57{
58 init(other.m_buf);
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080059}
60
Alexander Afanasyev0995f322013-01-22 13:16:46 -080061CcnxCharbuf::CcnxCharbuf(const void *buf, size_t length)
62{
63 m_buf = ccn_charbuf_create ();
64 ccn_charbuf_reserve (m_buf, length);
65 memcpy (m_buf->buf, buf, length);
66 m_buf->length = length;
67}
68
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080069CcnxCharbuf::~CcnxCharbuf()
70{
71 ccn_charbuf_destroy(&m_buf);
72}
73
74Name::Name()
75{
76}
77
78Name::Name(const string &name)
79{
80 stringstream ss(name);
81 string compStr;
Zhenkai Zhu3b82d432013-01-03 22:48:40 -080082 bool first = true;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080083 while(getline(ss, compStr, '/'))
84 {
Zhenkai Zhu3b82d432013-01-03 22:48:40 -080085 // discard the first empty comp before the first '/'
86 if (first)
87 {
88 first = false;
89 continue;
90 }
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080091 Bytes comp(compStr.begin(), compStr.end());
92 m_comps.push_back(comp);
93 }
94}
95
96Name::Name(const vector<Bytes> &comps)
97{
98 m_comps = comps;
99}
100
101Name::Name(const Name &other)
102{
103 m_comps = other.m_comps;
104}
105
106Name::Name(const unsigned char *data, const ccn_indexbuf *comps)
107{
Alexander Afanasyevd7245812013-02-13 21:06:57 -0800108 for (unsigned int i = 0; i < comps->n - 1; i++)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800109 {
110 const unsigned char *compPtr;
111 size_t size;
112 ccn_name_comp_get(data, comps, i, &compPtr, &size);
113 Bytes comp;
114 readRaw(comp, compPtr, size);
115 m_comps.push_back(comp);
116 }
117}
118
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800119Name::Name (const void *buf, const size_t length)
Alexander Afanasyevd09871f2013-01-04 22:36:37 -0800120{
121 ccn_indexbuf *idx = ccn_indexbuf_create();
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800122 const ccn_charbuf namebuf = { length, length, const_cast<unsigned char *> (reinterpret_cast<const unsigned char *> (buf)) };
Alexander Afanasyevd09871f2013-01-04 22:36:37 -0800123 ccn_name_split (&namebuf, idx);
124
125 const unsigned char *compPtr = NULL;
126 size_t size = 0;
127 int i = 0;
128 while (ccn_name_comp_get(namebuf.buf, idx, i, &compPtr, &size) == 0)
129 {
130 Bytes comp;
131 readRaw (comp, compPtr, size);
132 m_comps.push_back(comp);
133 i++;
134 }
135 ccn_indexbuf_destroy(&idx);
136}
137
Alexander Afanasyev0995f322013-01-22 13:16:46 -0800138Name::Name (const CcnxCharbuf &buf)
139{
140 ccn_indexbuf *idx = ccn_indexbuf_create();
141 ccn_name_split (buf.getBuf (), idx);
142
143 const unsigned char *compPtr = NULL;
144 size_t size = 0;
145 int i = 0;
146 while (ccn_name_comp_get(buf.getBuf ()->buf, idx, i, &compPtr, &size) == 0)
147 {
148 Bytes comp;
149 readRaw (comp, compPtr, size);
150 m_comps.push_back(comp);
151 i++;
152 }
153 ccn_indexbuf_destroy(&idx);
154}
155
156Name::Name (const ccn_charbuf *buf)
157{
158 ccn_indexbuf *idx = ccn_indexbuf_create();
159 ccn_name_split (buf, idx);
160
161 const unsigned char *compPtr = NULL;
162 size_t size = 0;
163 int i = 0;
164 while (ccn_name_comp_get(buf->buf, idx, i, &compPtr, &size) == 0)
165 {
166 Bytes comp;
167 readRaw (comp, compPtr, size);
168 m_comps.push_back(comp);
169 i++;
170 }
171 ccn_indexbuf_destroy(&idx);
172}
Alexander Afanasyevd09871f2013-01-04 22:36:37 -0800173
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800174Name &
175Name::operator=(const Name &other)
176{
177 m_comps = other.m_comps;
178 return *this;
179}
180bool
Zhenkai Zhu3b82d432013-01-03 22:48:40 -0800181Name::operator==(const string &str) const
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800182{
183 return this->toString() == str;
184}
185
186bool
Zhenkai Zhu3b82d432013-01-03 22:48:40 -0800187Name::operator!=(const string &str) const
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800188{
189 return !(*this == str);
190}
191
192Name
193operator+(const Name &n1, const Name &n2)
194{
195 vector<Bytes> comps = n1.m_comps;
196 copy(n2.m_comps.begin(), n2.m_comps.end(), back_inserter(comps));
197 return Name(comps);
198}
199
200string
201Name::toString() const
202{
203 stringstream ss(stringstream::out);
204 ss << *this;
205 return ss.str();
206}
207
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800208CcnxCharbufPtr
209Name::toCcnxCharbuf() const
210{
211 CcnxCharbufPtr ptr(new CcnxCharbuf());
212 ccn_charbuf *cbuf = ptr->getBuf();
213 ccn_name_init(cbuf);
214 int size = m_comps.size();
215 for (int i = 0; i < size; i++)
216 {
217 ccn_name_append(cbuf, head(m_comps[i]), m_comps[i].size());
218 }
219 return ptr;
220}
221
222Name &
Alexander Afanasyev66f4c492013-01-20 23:32:50 -0800223Name::appendComp(const Name &comp)
224{
225 m_comps.insert (m_comps.end (),
226 comp.m_comps.begin (), comp.m_comps.end ());
227 return *this;
228}
229
230Name &
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800231Name::appendComp(const Bytes &comp)
232{
233 m_comps.push_back(comp);
234 return *this;
235}
236
237Name &
238Name::appendComp(const string &compStr)
239{
240 Bytes comp(compStr.begin(), compStr.end());
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800241 return appendComp(comp);
242}
243
244Name &
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800245Name::appendComp (const void *buf, size_t size)
246{
247 Bytes comp (reinterpret_cast<const unsigned char*> (buf), reinterpret_cast<const unsigned char*> (buf) + size);
248 return appendComp(comp);
249}
250
251Name &
252Name::appendComp(uint64_t number)
253{
254 Bytes comp;
255 comp.push_back (0);
Alexander Afanasyev66f4c492013-01-20 23:32:50 -0800256
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800257 while (number > 0)
258 {
259 comp.push_back (static_cast<unsigned char> (number & 0xFF));
260 number >>= 8;
261 }
262 return appendComp (comp);
263}
264
265uint64_t
266Name::getCompAsInt (int index) const
267{
268 Bytes comp = getComp(index);
269 if (comp.size () < 1 ||
270 comp[0] != 0)
271 {
272 boost::throw_exception(NameException()
273 << error_info_str("Non integer component: " + getCompAsString(index)));
274 }
275 uint64_t ret = 0;
276 for (int i = comp.size () - 1; i >= 1; i--)
277 {
278 ret <<= 8;
279 ret |= comp [i];
280 }
281 return ret;
282}
283
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800284const Bytes &
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800285Name::getComp(int index) const
286{
Alexander Afanasyevd7245812013-02-13 21:06:57 -0800287 if (index < 0)
288 {
289 boost::throw_exception(NameException() << error_info_str("Negative index: " + boost::lexical_cast<string>(index)));
290 }
291
292 if (static_cast<unsigned int> (index) >= m_comps.size())
293 {
294 boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
295 }
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800296 return m_comps[index];
297}
298
299string
300Name::getCompAsString(int index) const
301{
302 Bytes comp = getComp(index);
303 stringstream ss(stringstream::out);
304 int size = comp.size();
305 for (int i = 0; i < size; i++)
306 {
307 unsigned char ch = comp[i];
308 if (isprint(ch))
309 {
310 ss << (char) ch;
311 }
312 else
313 {
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800314 ss << "%" << hex << setfill('0') << setw(2) << (unsigned int)ch;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800315 }
316 }
317
318 return ss.str();
319}
320
321Name
322Name::getPartialName(int start, int n) const
323{
324 int size = m_comps.size();
Alexander Afanasyevdcfa9632013-01-07 16:38:19 -0800325 if (start < 0 || start >= size || (n > 0 && start + n > size))
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800326 {
327 stringstream ss(stringstream::out);
328 ss << "getPartialName() parameter out of range! ";
329 ss << "start = " << start;
330 ss << "n = " << n;
331 ss << "size = " << size;
332 boost::throw_exception(NameException() << error_info_str(ss.str()));
333 }
334
335 vector<Bytes> comps;
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800336 int end;
337 if (n > 0)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800338 {
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800339 end = start + n;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800340 }
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800341 else
342 {
343 end = size;
344 }
345
346 for (int i = start; i < end; i++)
347 {
348 comps.push_back(m_comps[i]);
349 }
350
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800351 return Name(comps);
352}
353
354ostream &
355operator <<(ostream &os, const Name &name)
356{
357 int size = name.size();
358 vector<string> strComps;
359 for (int i = 0; i < size; i++)
360 {
361 strComps.push_back(name.getCompAsString(i));
362 }
363 string joined = boost::algorithm::join(strComps, "/");
364 os << "/" << joined;
365 return os;
366}
367
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800368bool
369operator ==(const Name &n1, const Name &n2)
370{
371 stringstream ss1(stringstream::out);
372 stringstream ss2(stringstream::out);
373 ss1 << n1;
374 ss2 << n2;
375 return ss1.str() == ss2.str();
376}
377
378bool
379operator !=(const Name &n1, const Name &n2)
380{
381 return !(n1 == n2);
382}
383
384bool
385operator <(const Name &n1, const Name &n2)
386{
387 stringstream ss1(stringstream::out);
388 stringstream ss2(stringstream::out);
389 ss1 << n1;
390 ss2 << n2;
391 return ss1.str() < ss2.str();
392}
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800393
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800394
395} // Ccnx