blob: 00fbe1162c07d025cf6be34d827c6a9c3a1b7a47 [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>
Alexander Afanasyev452645b2013-02-24 15:41:29 -080026#include <boost/make_shared.hpp>
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080027
Alexander Afanasyev053e5ac2013-01-22 20:59:13 -080028using namespace std;
29
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080030namespace Ccnx{
31
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080032Name::Name()
33{
34}
35
36Name::Name(const string &name)
37{
38 stringstream ss(name);
39 string compStr;
Zhenkai Zhu3b82d432013-01-03 22:48:40 -080040 bool first = true;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080041 while(getline(ss, compStr, '/'))
42 {
Zhenkai Zhu3b82d432013-01-03 22:48:40 -080043 // discard the first empty comp before the first '/'
44 if (first)
45 {
46 first = false;
47 continue;
48 }
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080049 Bytes comp(compStr.begin(), compStr.end());
50 m_comps.push_back(comp);
51 }
52}
53
54Name::Name(const vector<Bytes> &comps)
55{
56 m_comps = comps;
57}
58
59Name::Name(const Name &other)
60{
61 m_comps = other.m_comps;
62}
63
64Name::Name(const unsigned char *data, const ccn_indexbuf *comps)
65{
Alexander Afanasyevd7245812013-02-13 21:06:57 -080066 for (unsigned int i = 0; i < comps->n - 1; i++)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080067 {
68 const unsigned char *compPtr;
69 size_t size;
70 ccn_name_comp_get(data, comps, i, &compPtr, &size);
71 Bytes comp;
72 readRaw(comp, compPtr, size);
73 m_comps.push_back(comp);
74 }
75}
76
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080077Name::Name (const void *buf, const size_t length)
Alexander Afanasyevd09871f2013-01-04 22:36:37 -080078{
79 ccn_indexbuf *idx = ccn_indexbuf_create();
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080080 const ccn_charbuf namebuf = { length, length, const_cast<unsigned char *> (reinterpret_cast<const unsigned char *> (buf)) };
Alexander Afanasyevd09871f2013-01-04 22:36:37 -080081 ccn_name_split (&namebuf, idx);
82
83 const unsigned char *compPtr = NULL;
84 size_t size = 0;
85 int i = 0;
86 while (ccn_name_comp_get(namebuf.buf, idx, i, &compPtr, &size) == 0)
87 {
88 Bytes comp;
89 readRaw (comp, compPtr, size);
90 m_comps.push_back(comp);
91 i++;
92 }
93 ccn_indexbuf_destroy(&idx);
94}
95
Alexander Afanasyev0995f322013-01-22 13:16:46 -080096Name::Name (const CcnxCharbuf &buf)
97{
98 ccn_indexbuf *idx = ccn_indexbuf_create();
99 ccn_name_split (buf.getBuf (), idx);
100
101 const unsigned char *compPtr = NULL;
102 size_t size = 0;
103 int i = 0;
104 while (ccn_name_comp_get(buf.getBuf ()->buf, idx, i, &compPtr, &size) == 0)
105 {
106 Bytes comp;
107 readRaw (comp, compPtr, size);
108 m_comps.push_back(comp);
109 i++;
110 }
111 ccn_indexbuf_destroy(&idx);
112}
113
114Name::Name (const ccn_charbuf *buf)
115{
116 ccn_indexbuf *idx = ccn_indexbuf_create();
117 ccn_name_split (buf, idx);
118
119 const unsigned char *compPtr = NULL;
120 size_t size = 0;
121 int i = 0;
122 while (ccn_name_comp_get(buf->buf, idx, i, &compPtr, &size) == 0)
123 {
124 Bytes comp;
125 readRaw (comp, compPtr, size);
126 m_comps.push_back(comp);
127 i++;
128 }
129 ccn_indexbuf_destroy(&idx);
130}
Alexander Afanasyevd09871f2013-01-04 22:36:37 -0800131
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800132Name &
133Name::operator=(const Name &other)
134{
135 m_comps = other.m_comps;
136 return *this;
137}
138bool
Zhenkai Zhu3b82d432013-01-03 22:48:40 -0800139Name::operator==(const string &str) const
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800140{
141 return this->toString() == str;
142}
143
144bool
Zhenkai Zhu3b82d432013-01-03 22:48:40 -0800145Name::operator!=(const string &str) const
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800146{
147 return !(*this == str);
148}
149
150Name
151operator+(const Name &n1, const Name &n2)
152{
153 vector<Bytes> comps = n1.m_comps;
154 copy(n2.m_comps.begin(), n2.m_comps.end(), back_inserter(comps));
155 return Name(comps);
156}
157
158string
159Name::toString() const
160{
161 stringstream ss(stringstream::out);
162 ss << *this;
163 return ss.str();
164}
165
Alexander Afanasyev452645b2013-02-24 15:41:29 -0800166CcnxCharbuf*
167Name::toCcnxCharbufRaw () const
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800168{
Alexander Afanasyev452645b2013-02-24 15:41:29 -0800169 CcnxCharbuf *ptr = new CcnxCharbuf ();
170
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800171 ccn_charbuf *cbuf = ptr->getBuf();
172 ccn_name_init(cbuf);
173 int size = m_comps.size();
174 for (int i = 0; i < size; i++)
175 {
176 ccn_name_append(cbuf, head(m_comps[i]), m_comps[i].size());
177 }
178 return ptr;
179}
180
Alexander Afanasyev452645b2013-02-24 15:41:29 -0800181
182CcnxCharbufPtr
183Name::toCcnxCharbuf () const
184{
185 return CcnxCharbufPtr (toCcnxCharbufRaw ());
186}
187
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800188Name &
Alexander Afanasyev66f4c492013-01-20 23:32:50 -0800189Name::appendComp(const Name &comp)
190{
191 m_comps.insert (m_comps.end (),
192 comp.m_comps.begin (), comp.m_comps.end ());
193 return *this;
194}
195
196Name &
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800197Name::appendComp(const Bytes &comp)
198{
199 m_comps.push_back(comp);
200 return *this;
201}
202
203Name &
204Name::appendComp(const string &compStr)
205{
206 Bytes comp(compStr.begin(), compStr.end());
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800207 return appendComp(comp);
208}
209
210Name &
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800211Name::appendComp (const void *buf, size_t size)
212{
213 Bytes comp (reinterpret_cast<const unsigned char*> (buf), reinterpret_cast<const unsigned char*> (buf) + size);
214 return appendComp(comp);
215}
216
217Name &
218Name::appendComp(uint64_t number)
219{
220 Bytes comp;
221 comp.push_back (0);
Alexander Afanasyev66f4c492013-01-20 23:32:50 -0800222
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800223 while (number > 0)
224 {
225 comp.push_back (static_cast<unsigned char> (number & 0xFF));
226 number >>= 8;
227 }
228 return appendComp (comp);
229}
230
231uint64_t
232Name::getCompAsInt (int index) const
233{
234 Bytes comp = getComp(index);
235 if (comp.size () < 1 ||
236 comp[0] != 0)
237 {
238 boost::throw_exception(NameException()
239 << error_info_str("Non integer component: " + getCompAsString(index)));
240 }
241 uint64_t ret = 0;
242 for (int i = comp.size () - 1; i >= 1; i--)
243 {
244 ret <<= 8;
245 ret |= comp [i];
246 }
247 return ret;
248}
249
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800250const Bytes &
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800251Name::getComp(int index) const
252{
Alexander Afanasyevd7245812013-02-13 21:06:57 -0800253 if (index < 0)
254 {
255 boost::throw_exception(NameException() << error_info_str("Negative index: " + boost::lexical_cast<string>(index)));
256 }
257
258 if (static_cast<unsigned int> (index) >= m_comps.size())
259 {
260 boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
261 }
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800262 return m_comps[index];
263}
264
265string
266Name::getCompAsString(int index) const
267{
268 Bytes comp = getComp(index);
269 stringstream ss(stringstream::out);
270 int size = comp.size();
271 for (int i = 0; i < size; i++)
272 {
273 unsigned char ch = comp[i];
274 if (isprint(ch))
275 {
276 ss << (char) ch;
277 }
278 else
279 {
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800280 ss << "%" << hex << setfill('0') << setw(2) << (unsigned int)ch;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800281 }
282 }
283
284 return ss.str();
285}
286
287Name
288Name::getPartialName(int start, int n) const
289{
290 int size = m_comps.size();
Alexander Afanasyevdcfa9632013-01-07 16:38:19 -0800291 if (start < 0 || start >= size || (n > 0 && start + n > size))
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800292 {
293 stringstream ss(stringstream::out);
294 ss << "getPartialName() parameter out of range! ";
295 ss << "start = " << start;
296 ss << "n = " << n;
297 ss << "size = " << size;
298 boost::throw_exception(NameException() << error_info_str(ss.str()));
299 }
300
301 vector<Bytes> comps;
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800302 int end;
303 if (n > 0)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800304 {
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800305 end = start + n;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800306 }
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800307 else
308 {
309 end = size;
310 }
311
312 for (int i = start; i < end; i++)
313 {
314 comps.push_back(m_comps[i]);
315 }
316
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800317 return Name(comps);
318}
319
320ostream &
321operator <<(ostream &os, const Name &name)
322{
323 int size = name.size();
324 vector<string> strComps;
325 for (int i = 0; i < size; i++)
326 {
327 strComps.push_back(name.getCompAsString(i));
328 }
329 string joined = boost::algorithm::join(strComps, "/");
330 os << "/" << joined;
331 return os;
332}
333
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800334bool
335operator ==(const Name &n1, const Name &n2)
336{
337 stringstream ss1(stringstream::out);
338 stringstream ss2(stringstream::out);
339 ss1 << n1;
340 ss2 << n2;
341 return ss1.str() == ss2.str();
342}
343
344bool
345operator !=(const Name &n1, const Name &n2)
346{
347 return !(n1 == n2);
348}
349
350bool
351operator <(const Name &n1, const Name &n2)
352{
353 stringstream ss1(stringstream::out);
354 stringstream ss2(stringstream::out);
355 ss1 << n1;
356 ss2 << n2;
357 return ss1.str() < ss2.str();
358}
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800359
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800360
361} // Ccnx