blob: 848019a9468fa7a1ab87547978c6c58b17cdce94 [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
27namespace Ccnx{
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080028CcnxCharbufPtr CcnxCharbuf::Null;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080029
Zhenkai Zhub0adefe2013-01-04 21:56:38 -080030void
31CcnxCharbuf::init(ccn_charbuf *buf)
32{
33 if (buf != NULL)
34 {
35 m_buf = ccn_charbuf_create();
36 ccn_charbuf_reserve(m_buf, buf->length);
37 memcpy(m_buf->buf, buf->buf, buf->length);
38 m_buf->length = buf->length;
39 }
40}
41
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080042CcnxCharbuf::CcnxCharbuf()
43 : m_buf(NULL)
44{
45 m_buf = ccn_charbuf_create();
46}
47
48CcnxCharbuf::CcnxCharbuf(ccn_charbuf *buf)
49 : m_buf(NULL)
50{
Zhenkai Zhub0adefe2013-01-04 21:56:38 -080051 init(buf);
52}
53
54CcnxCharbuf::CcnxCharbuf(const CcnxCharbuf &other)
55 : m_buf (NULL)
56{
57 init(other.m_buf);
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080058}
59
60CcnxCharbuf::~CcnxCharbuf()
61{
62 ccn_charbuf_destroy(&m_buf);
63}
64
65Name::Name()
66{
67}
68
69Name::Name(const string &name)
70{
71 stringstream ss(name);
72 string compStr;
Zhenkai Zhu3b82d432013-01-03 22:48:40 -080073 bool first = true;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080074 while(getline(ss, compStr, '/'))
75 {
Zhenkai Zhu3b82d432013-01-03 22:48:40 -080076 // discard the first empty comp before the first '/'
77 if (first)
78 {
79 first = false;
80 continue;
81 }
Zhenkai Zhuf47109b2013-01-02 19:41:34 -080082 Bytes comp(compStr.begin(), compStr.end());
83 m_comps.push_back(comp);
84 }
85}
86
87Name::Name(const vector<Bytes> &comps)
88{
89 m_comps = comps;
90}
91
92Name::Name(const Name &other)
93{
94 m_comps = other.m_comps;
95}
96
97Name::Name(const unsigned char *data, const ccn_indexbuf *comps)
98{
99 for (int i = 0; i < comps->n - 1; i++)
100 {
101 const unsigned char *compPtr;
102 size_t size;
103 ccn_name_comp_get(data, comps, i, &compPtr, &size);
104 Bytes comp;
105 readRaw(comp, compPtr, size);
106 m_comps.push_back(comp);
107 }
108}
109
Alexander Afanasyevd09871f2013-01-04 22:36:37 -0800110Name::Name (const unsigned char *buf, const size_t length)
111{
112 ccn_indexbuf *idx = ccn_indexbuf_create();
113 const ccn_charbuf namebuf = { length, length, const_cast<unsigned char *> (buf) };
114 ccn_name_split (&namebuf, idx);
115
116 const unsigned char *compPtr = NULL;
117 size_t size = 0;
118 int i = 0;
119 while (ccn_name_comp_get(namebuf.buf, idx, i, &compPtr, &size) == 0)
120 {
121 Bytes comp;
122 readRaw (comp, compPtr, size);
123 m_comps.push_back(comp);
124 i++;
125 }
126 ccn_indexbuf_destroy(&idx);
127}
128
129
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800130Name &
131Name::operator=(const Name &other)
132{
133 m_comps = other.m_comps;
134 return *this;
135}
136bool
Zhenkai Zhu3b82d432013-01-03 22:48:40 -0800137Name::operator==(const string &str) const
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800138{
139 return this->toString() == str;
140}
141
142bool
Zhenkai Zhu3b82d432013-01-03 22:48:40 -0800143Name::operator!=(const string &str) const
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800144{
145 return !(*this == str);
146}
147
148Name
149operator+(const Name &n1, const Name &n2)
150{
151 vector<Bytes> comps = n1.m_comps;
152 copy(n2.m_comps.begin(), n2.m_comps.end(), back_inserter(comps));
153 return Name(comps);
154}
155
156string
157Name::toString() const
158{
159 stringstream ss(stringstream::out);
160 ss << *this;
161 return ss.str();
162}
163
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800164CcnxCharbufPtr
165Name::toCcnxCharbuf() const
166{
167 CcnxCharbufPtr ptr(new CcnxCharbuf());
168 ccn_charbuf *cbuf = ptr->getBuf();
169 ccn_name_init(cbuf);
170 int size = m_comps.size();
171 for (int i = 0; i < size; i++)
172 {
173 ccn_name_append(cbuf, head(m_comps[i]), m_comps[i].size());
174 }
175 return ptr;
176}
177
178Name &
Alexander Afanasyev66f4c492013-01-20 23:32:50 -0800179Name::appendComp(const Name &comp)
180{
181 m_comps.insert (m_comps.end (),
182 comp.m_comps.begin (), comp.m_comps.end ());
183 return *this;
184}
185
186Name &
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800187Name::appendComp(const Bytes &comp)
188{
189 m_comps.push_back(comp);
190 return *this;
191}
192
193Name &
194Name::appendComp(const string &compStr)
195{
196 Bytes comp(compStr.begin(), compStr.end());
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800197 return appendComp(comp);
198}
199
200Name &
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800201Name::appendComp (const void *buf, size_t size)
202{
203 Bytes comp (reinterpret_cast<const unsigned char*> (buf), reinterpret_cast<const unsigned char*> (buf) + size);
204 return appendComp(comp);
205}
206
207Name &
208Name::appendComp(uint64_t number)
209{
210 Bytes comp;
211 comp.push_back (0);
Alexander Afanasyev66f4c492013-01-20 23:32:50 -0800212
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800213 while (number > 0)
214 {
215 comp.push_back (static_cast<unsigned char> (number & 0xFF));
216 number >>= 8;
217 }
218 return appendComp (comp);
219}
220
221uint64_t
222Name::getCompAsInt (int index) const
223{
224 Bytes comp = getComp(index);
225 if (comp.size () < 1 ||
226 comp[0] != 0)
227 {
228 boost::throw_exception(NameException()
229 << error_info_str("Non integer component: " + getCompAsString(index)));
230 }
231 uint64_t ret = 0;
232 for (int i = comp.size () - 1; i >= 1; i--)
233 {
234 ret <<= 8;
235 ret |= comp [i];
236 }
237 return ret;
238}
239
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800240Bytes
241Name::getComp(int index) const
242{
243 if (index >= m_comps.size())
244 {
245 boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
246 }
247 return m_comps[index];
248}
249
250string
251Name::getCompAsString(int index) const
252{
253 Bytes comp = getComp(index);
254 stringstream ss(stringstream::out);
255 int size = comp.size();
256 for (int i = 0; i < size; i++)
257 {
258 unsigned char ch = comp[i];
259 if (isprint(ch))
260 {
261 ss << (char) ch;
262 }
263 else
264 {
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800265 ss << "%" << hex << setfill('0') << setw(2) << (unsigned int)ch;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800266 }
267 }
268
269 return ss.str();
270}
271
272Name
273Name::getPartialName(int start, int n) const
274{
275 int size = m_comps.size();
Alexander Afanasyevdcfa9632013-01-07 16:38:19 -0800276 if (start < 0 || start >= size || (n > 0 && start + n > size))
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800277 {
278 stringstream ss(stringstream::out);
279 ss << "getPartialName() parameter out of range! ";
280 ss << "start = " << start;
281 ss << "n = " << n;
282 ss << "size = " << size;
283 boost::throw_exception(NameException() << error_info_str(ss.str()));
284 }
285
286 vector<Bytes> comps;
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800287 int end;
288 if (n > 0)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800289 {
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800290 end = start + n;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800291 }
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800292 else
293 {
294 end = size;
295 }
296
297 for (int i = start; i < end; i++)
298 {
299 comps.push_back(m_comps[i]);
300 }
301
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800302 return Name(comps);
303}
304
305ostream &
306operator <<(ostream &os, const Name &name)
307{
308 int size = name.size();
309 vector<string> strComps;
310 for (int i = 0; i < size; i++)
311 {
312 strComps.push_back(name.getCompAsString(i));
313 }
314 string joined = boost::algorithm::join(strComps, "/");
315 os << "/" << joined;
316 return os;
317}
318
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800319bool
320operator ==(const Name &n1, const Name &n2)
321{
322 stringstream ss1(stringstream::out);
323 stringstream ss2(stringstream::out);
324 ss1 << n1;
325 ss2 << n2;
326 return ss1.str() == ss2.str();
327}
328
329bool
330operator !=(const Name &n1, const Name &n2)
331{
332 return !(n1 == n2);
333}
334
335bool
336operator <(const Name &n1, const Name &n2)
337{
338 stringstream ss1(stringstream::out);
339 stringstream ss2(stringstream::out);
340 ss1 << n1;
341 ss2 << n2;
342 return ss1.str() < ss2.str();
343}
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800344
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800345
346} // Ccnx