blob: 4573ed136cbaa9724d2dc3fc4711fed2270b7e0e [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 &
Alexander Afanasyev66f4c492013-01-20 23:32:50 -0800158Name::appendComp(const Name &comp)
159{
160 m_comps.insert (m_comps.end (),
161 comp.m_comps.begin (), comp.m_comps.end ());
162 return *this;
163}
164
165Name &
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800166Name::appendComp(const Bytes &comp)
167{
168 m_comps.push_back(comp);
169 return *this;
170}
171
172Name &
173Name::appendComp(const string &compStr)
174{
175 Bytes comp(compStr.begin(), compStr.end());
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800176 return appendComp(comp);
177}
178
179Name &
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800180Name::appendComp (const void *buf, size_t size)
181{
182 Bytes comp (reinterpret_cast<const unsigned char*> (buf), reinterpret_cast<const unsigned char*> (buf) + size);
183 return appendComp(comp);
184}
185
186Name &
187Name::appendComp(uint64_t number)
188{
189 Bytes comp;
190 comp.push_back (0);
Alexander Afanasyev66f4c492013-01-20 23:32:50 -0800191
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800192 while (number > 0)
193 {
194 comp.push_back (static_cast<unsigned char> (number & 0xFF));
195 number >>= 8;
196 }
197 return appendComp (comp);
198}
199
200uint64_t
201Name::getCompAsInt (int index) const
202{
203 Bytes comp = getComp(index);
204 if (comp.size () < 1 ||
205 comp[0] != 0)
206 {
207 boost::throw_exception(NameException()
208 << error_info_str("Non integer component: " + getCompAsString(index)));
209 }
210 uint64_t ret = 0;
211 for (int i = comp.size () - 1; i >= 1; i--)
212 {
213 ret <<= 8;
214 ret |= comp [i];
215 }
216 return ret;
217}
218
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800219Bytes
220Name::getComp(int index) const
221{
222 if (index >= m_comps.size())
223 {
224 boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
225 }
226 return m_comps[index];
227}
228
229string
230Name::getCompAsString(int index) const
231{
232 Bytes comp = getComp(index);
233 stringstream ss(stringstream::out);
234 int size = comp.size();
235 for (int i = 0; i < size; i++)
236 {
237 unsigned char ch = comp[i];
238 if (isprint(ch))
239 {
240 ss << (char) ch;
241 }
242 else
243 {
Alexander Afanasyevc9eb68f2013-01-07 13:40:00 -0800244 ss << "%" << hex << setfill('0') << setw(2) << (unsigned int)ch;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800245 }
246 }
247
248 return ss.str();
249}
250
251Name
252Name::getPartialName(int start, int n) const
253{
254 int size = m_comps.size();
Alexander Afanasyevdcfa9632013-01-07 16:38:19 -0800255 if (start < 0 || start >= size || (n > 0 && start + n > size))
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800256 {
257 stringstream ss(stringstream::out);
258 ss << "getPartialName() parameter out of range! ";
259 ss << "start = " << start;
260 ss << "n = " << n;
261 ss << "size = " << size;
262 boost::throw_exception(NameException() << error_info_str(ss.str()));
263 }
264
265 vector<Bytes> comps;
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800266 int end;
267 if (n > 0)
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800268 {
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800269 end = start + n;
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800270 }
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800271 else
272 {
273 end = size;
274 }
275
276 for (int i = start; i < end; i++)
277 {
278 comps.push_back(m_comps[i]);
279 }
280
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800281 return Name(comps);
282}
283
284ostream &
285operator <<(ostream &os, const Name &name)
286{
287 int size = name.size();
288 vector<string> strComps;
289 for (int i = 0; i < size; i++)
290 {
291 strComps.push_back(name.getCompAsString(i));
292 }
293 string joined = boost::algorithm::join(strComps, "/");
294 os << "/" << joined;
295 return os;
296}
297
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800298bool
299operator ==(const Name &n1, const Name &n2)
300{
301 stringstream ss1(stringstream::out);
302 stringstream ss2(stringstream::out);
303 ss1 << n1;
304 ss2 << n2;
305 return ss1.str() == ss2.str();
306}
307
308bool
309operator !=(const Name &n1, const Name &n2)
310{
311 return !(n1 == n2);
312}
313
314bool
315operator <(const Name &n1, const Name &n2)
316{
317 stringstream ss1(stringstream::out);
318 stringstream ss2(stringstream::out);
319 ss1 << n1;
320 ss2 << n2;
321 return ss1.str() < ss2.str();
322}
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800323
Zhenkai Zhuf47109b2013-01-02 19:41:34 -0800324
325} // Ccnx