blob: 18e24120e055796d268d625d41593d894a325ebc [file] [log] [blame]
Jeff Thompsonfa306642013-06-17 15:06:57 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Alexander Afanasyev
5 * Zhenkai Zhu
6 *
7 * BSD license, See the LICENSE file for more information
8 *
9 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
10 * Zhenkai Zhu <zhenkai@cs.ucla.edu>
11 */
12
13#ifndef NDN_NAME_H
14#define NDN_NAME_H
15
16#include "ndn-cpp/fields/name-component.h"
17#include "ndn-cpp/common.h"
18
19namespace ndn {
20
21/**
22 * @brief Class for NDN Name
23 */
24class Name
25{
26public:
27 typedef std::vector<name::Component>::iterator iterator;
28 typedef std::vector<name::Component>::const_iterator const_iterator;
29 typedef std::vector<name::Component>::reverse_iterator reverse_iterator;
30 typedef std::vector<name::Component>::const_reverse_iterator const_reverse_iterator;
31 typedef std::vector<name::Component>::reference reference;
32 typedef std::vector<name::Component>::const_reference const_reference;
33
34 typedef name::Component partial_type;
35
36 ///////////////////////////////////////////////////////////////////////////////
37 // CONSTRUCTORS //
38 ///////////////////////////////////////////////////////////////////////////////
39
40 /**
41 * @brief Default constructor to create an empty name (zero components, or "/")
42 */
43 Name ();
44
45 /**
46 * @brief Copy constructor
47 *
48 * @param other reference to a NDN name object
49 */
50 Name (const Name &other);
51
52 /**
53 * @brief Create a name from URL string
54 *
55 * @param url URI-represented name
56 */
57 Name (const std::string &url);
58
59 /**
60 * @brief Create a name from a container of elements [begin, end)
61 *
62 * @param begin begin iterator of the container
63 * @param end end iterator of the container
64 */
65 template<class Iterator>
66 Name (Iterator begin, Iterator end);
67
68 /**
69 * @brief Assignment operator
70 */
71 Name &
72 operator= (const Name &other);
73
74
75 ///////////////////////////////////////////////////////////////////////////////
76 // SETTERS //
77 ///////////////////////////////////////////////////////////////////////////////
78
79 /**
80 * @brief Append a binary blob as a name component
81 *
82 * @param comp a binary blob
83 * @returns reference to self (to allow chaining of append methods)
84 */
85 inline Name &
86 append (const name::Component &comp);
87
88 /**
89 * @brief Append a binary blob as a name component
90 * @param comp a binary blob
91 *
92 * This version is a little bit more efficient, since it swaps contents of comp and newly added component
93 *
94 * Attention!!! This method has an intended side effect: content of comp becomes empty
95 */
96 inline Name &
97 appendBySwap (name::Component &comp);
98
99 /**
100 * @brief Append components a container of elements [begin, end)
101 *
102 * @param begin begin iterator of the container
103 * @param end end iterator of the container
104 * @returns reference to self (to allow chaining of append methods)
105 */
106 template<class Iterator>
107 inline Name &
108 append (Iterator begin, Iterator end);
109
110 /**
111 * @brief Append components from another ndn::Name object
112 *
113 * @param comp reference to Name object
114 * @returns reference to self (to allow chaining of append methods)
115 */
116 inline Name &
117 append (const Name &comp);
118
119 /**
120 * @brief Append a string as a name component
121 *
122 * @param compStr a string
123 * @returns reference to self (to allow chaining of append methods)
124 *
125 * No conversions will be done to the string. The string is included in raw form,
126 * without any leading '\0' symbols.
127 */
128 inline Name &
129 append (const std::string &compStr);
130
131 /**
132 * @brief Append a binary blob as a name component
133 *
134 * @param buf pointer to the first byte of the binary blob
135 * @param size length of the binary blob
136 * @returns reference to self (to allow chaining of append methods)
137 */
138 inline Name &
139 append (const void *buf, size_t size);
140
141 /**
142 * @brief Append network-ordered numeric component to the name
143 *
144 * @param number number to be encoded and added as a component
145 *
146 * Number is encoded and added in network order. Tail zero-bytes are not included.
147 * For example, if the number is 1, then 1-byte binary blob will be added 0x01.
148 * If the number is 256, then 2 binary blob will be added: 0x01 0x01
149 *
150 * If the number is zero, an empty component will be added
151 */
152 inline Name &
153 appendNumber (uint64_t number);
154
155 /**
156 * @brief Append network-ordered numeric component to the name with marker
157 *
158 * @param number number to be encoded and added as a component
159 * @param marker byte marker, specified by the desired naming convention
160 *
161 * Currently defined naming conventions of the marker:
162 * - 0x00 sequence number
163 * - 0xC1 control number
164 * - 0xFB block id
165 * - 0xFD version number
166 *
167 * This version is almost exactly as appendNumber, with exception that it adds initial marker.
168 * The number is formatted in the exactly the same way.
169 *
170 * @see appendNumber
171 */
172 inline Name &
173 appendNumberWithMarker (uint64_t number, unsigned char marker);
174
175 /**
176 * @brief Helper method to add sequence number to the name (marker = 0x00)
177 * @param seqno sequence number
178 * @see appendNumberWithMarker
179 */
180 inline Name &
181 appendSeqNum (uint64_t seqno);
182
183 /**
184 * @brief Helper method to add control number to the name (marker = 0xC1)
185 * @param control control number
186 * @see appendNumberWithMarker
187 */
188 inline Name &
189 appendControlNum (uint64_t control);
190
191 /**
192 * @brief Helper method to add block ID to the name (marker = 0xFB)
193 * @param blkid block ID
194 * @see appendNumberWithMarker
195 */
196 inline Name &
197 appendBlkId (uint64_t blkid);
198
199 /**
200 * @brief Helper method to add version to the name (marker = 0xFD)
201 * @param version fully formatted version in a desired format (e.g., timestamp).
202 * If version is Name::nversion, then the version number is automatically
203 * assigned based on UTC timestamp
204 * @see appendNumberWithMarker
205 */
206 Name &
207 appendVersion (uint64_t version = Name::nversion);
208
209 ///////////////////////////////////////////////////////////////////////////////
210 // GETTERS //
211 ///////////////////////////////////////////////////////////////////////////////
212
213 /**
214 * @brief Get number of the name components
215 * @return number of name components
216 */
217 inline size_t
218 size () const;
219
220 /**
221 * @brief Get binary blob of name component
222 * @param index index of the name component. If less than 0, then getting component from the back:
223 * get(-1) getting the last component, get(-2) is getting second component from back, etc.
224 * @returns const reference to binary blob of the requested name component
225 *
226 * If index is out of range, an exception will be thrown
227 */
228 const name::Component &
229 get (int index) const;
230
231 /**
232 * @brief Get binary blob of name component
233 * @param index index of the name component. If less than 0, then getting component from the back
234 * @returns reference to binary blob of the requested name component
235 *
236 * If index is out of range, an exception will be thrown
237 */
238 name::Component &
239 get (int index);
240
241 /////
242 ///// Iterator interface to name components
243 /////
244 inline Name::const_iterator
245 begin () const; ///< @brief Begin iterator (const)
246
247 inline Name::iterator
248 begin (); ///< @brief Begin iterator
249
250 inline Name::const_iterator
251 end () const; ///< @brief End iterator (const)
252
253 inline Name::iterator
254 end (); ///< @brief End iterator
255
256 inline Name::const_reverse_iterator
257 rbegin () const; ///< @brief Reverse begin iterator (const)
258
259 inline Name::reverse_iterator
260 rbegin (); ///< @brief Reverse begin iterator
261
262 inline Name::const_reverse_iterator
263 rend () const; ///< @brief Reverse end iterator (const)
264
265 inline Name::reverse_iterator
266 rend (); ///< @brief Reverse end iterator
267
268
269 /////
270 ///// Static helpers to convert name component to appropriate value
271 /////
272
273 /**
274 * @brief Get a new name, constructed as a subset of components
275 * @param pos Position of the first component to be copied to the subname
276 * @param len Number of components to be copied. Value Name::npos indicates that all components till the end of the name.
277 */
278 Name
279 getSubName (size_t pos = 0, size_t len = npos) const;
280
281 /**
282 * @brief Get prefix of the name
283 * @param len length of the prefix
284 * @param skip number of components to skip from beginning of the name
285 */
286 inline Name
287 getPrefix (size_t len, size_t skip = 0) const;
288
289 /**
290 * @brief Get postfix of the name
291 * @param len length of the postfix
292 * @param skip number of components to skip from end of the name
293 */
294 inline Name
295 getPostfix (size_t len, size_t skip = 0) const;
296
297 /**
298 * @brief Get text representation of the name (URI)
299 */
300 std::string
301 toUri () const;
302
303 /**
304 * @brief Write name as URI to the specified output stream
305 * @param os output stream
306 */
307 void
308 toUri (std::ostream &os) const;
309
310 /////////////////////////////////////////////////
311 // Helpers and compatibility wrappers
312 /////////////////////////////////////////////////
313
314 /**
315 * @brief Compare two names, using canonical ordering for each component
316 * @return 0 They compare equal
317 * <0 If *this comes before other in the canonical ordering
318 * >0 If *this comes after in the canonical ordering
319 */
320 int
321 compare (const Name &name) const;
322
323 /**
324 * @brief Check if to Name objects are equal (have the same number of components with the same binary data)
325 */
326 inline bool
327 operator == (const Name &name) const;
328
329 /**
330 * @brief Check if two Name objects are not equal
331 */
332 inline bool
333 operator != (const Name &name) const;
334
335 /**
336 * @brief Less or equal comparison of two name objects
337 */
338 inline bool
339 operator <= (const Name &name) const;
340
341 /**
342 * @brief Less comparison of two name objects
343 */
344 inline bool
345 operator < (const Name &name) const;
346
347 /**
348 * @brief Great or equal comparison of two name objects
349 */
350 inline bool
351 operator >= (const Name &name) const;
352
353 /**
354 * @brief Great comparison of two name objects
355 */
356 inline bool
357 operator > (const Name &name) const;
358
359 /**
360 * @brief Operator [] to simplify access to name components
361 * @see get
362 */
363 inline name::Component &
364 operator [] (int index);
365
366 /**
367 * @brief Operator [] to simplify access to name components
368 * @see get
369 */
370 inline const name::Component &
371 operator [] (int index) const;
372
373 /**
374 * @brief Create a new Name object, by copying components from first and second name
375 */
376 Name
377 operator + (const Name &name) const;
378
379 /**
380 * @brief A wrapper for append method
381 */
382 template<class T>
383 inline void
384 push_back (const T &comp);
385
386public:
387 // Data Members (public):
388 /// Value returned by various member functions when they fail.
389 const static size_t npos = static_cast<size_t> (-1);
390 const static uint64_t nversion = static_cast<uint64_t> (-1);
391
392private:
393 std::vector<name::Component> m_comps;
394};
395
396typedef boost::shared_ptr<Name> NamePtr;
397
398inline std::ostream &
399operator << (std::ostream &os, const Name &name)
400{
401 name.toUri (os);
402 return os;
403}
404
405
406/////////////////////////////////////////////////////////////////////////////////////
407// Definition of inline methods
408/////////////////////////////////////////////////////////////////////////////////////
409
410template<class Iterator>
411Name::Name (Iterator begin, Iterator end)
412{
413 append (begin, end);
414}
415
416inline Name &
417Name::append (const name::Component &comp)
418{
419 if (comp.size () != 0)
420 m_comps.push_back (comp);
421 return *this;
422}
423
424inline Name &
425Name::appendBySwap (name::Component &comp)
426{
427 if (comp.size () != 0)
428 {
429 Name::iterator newComp = m_comps.insert (end (), name::Component ());
430 newComp->swap (comp);
431 }
432 return *this;
433}
434
435template<class Iterator>
436inline Name &
437Name::append (Iterator begin, Iterator end)
438{
439 for (Iterator i = begin; i != end; i++)
440 {
441 append (*i);
442 }
443 return *this;
444}
445
446Name &
447Name::append (const Name &comp)
448{
449 if (this == &comp)
450 {
451 // have to double-copy if the object is self, otherwise results very frustrating (because we use vector...)
452 return append (Name (comp.begin (), comp.end ()));
453 }
454 return append (comp.begin (), comp.end ());
455}
456
457Name &
458Name::append (const std::string &compStr)
459{
460 name::Component comp (compStr);
461 return appendBySwap (comp);
462}
463
464Name &
465Name::append (const void *buf, size_t size)
466{
467 name::Component comp (buf, size);
468 return appendBySwap (comp);
469}
470
471Name &
472Name::appendNumber (uint64_t number)
473{
474 name::Component comp;
475 name::Component::fromNumber (number).swap (comp);
476 return appendBySwap (comp);
477}
478
479Name &
480Name::appendNumberWithMarker (uint64_t number, unsigned char marker)
481{
482 name::Component comp;
483 name::Component::fromNumberWithMarker (number, marker).swap (comp);
484 return appendBySwap (comp);
485}
486
487inline Name &
488Name::appendSeqNum (uint64_t seqno)
489{
490 return appendNumberWithMarker (seqno, 0x00);
491}
492
493inline Name &
494Name::appendControlNum (uint64_t control)
495{
496 return appendNumberWithMarker (control, 0xC1);
497}
498
499inline Name &
500Name::appendBlkId (uint64_t blkid)
501{
502 return appendNumberWithMarker (blkid, 0xFB);
503}
504
505inline size_t
506Name::size () const
507{
508 return m_comps.size ();
509}
510
511/////
512///// Iterator interface to name components
513/////
514inline Name::const_iterator
515Name::begin () const
516{
517 return m_comps.begin ();
518}
519
520inline Name::iterator
521Name::begin ()
522{
523 return m_comps.begin ();
524}
525
526inline Name::const_iterator
527Name::end () const
528{
529 return m_comps.end ();
530}
531
532inline Name::iterator
533Name::end ()
534{
535 return m_comps.end ();
536}
537
538inline Name::const_reverse_iterator
539Name::rbegin () const
540{
541 return m_comps.rbegin ();
542}
543
544inline Name::reverse_iterator
545Name::rbegin ()
546{
547 return m_comps.rbegin ();
548}
549
550inline Name::const_reverse_iterator
551Name::rend () const
552{
553 return m_comps.rend ();
554}
555
556
557inline Name::reverse_iterator
558Name::rend ()
559{
560 return m_comps.rend ();
561}
562
563
564//// helpers
565
566
567inline Name
568Name::getPrefix (size_t len, size_t skip/* = 0*/) const
569{
570 return getSubName (skip, len);
571}
572
573inline Name
574Name::getPostfix (size_t len, size_t skip/* = 0*/) const
575{
576 return getSubName (size () - len - skip, len);
577}
578
579
580template<class T>
581inline void
582Name::push_back (const T &comp)
583{
584 append (comp);
585}
586
587inline bool
588Name::operator ==(const Name &name) const
589{
590 return (compare (name) == 0);
591}
592
593inline bool
594Name::operator !=(const Name &name) const
595{
596 return (compare (name) != 0);
597}
598
599inline bool
600Name::operator <= (const Name &name) const
601{
602 return (compare (name) <= 0);
603}
604
605inline bool
606Name::operator < (const Name &name) const
607{
608 return (compare (name) < 0);
609}
610
611inline bool
612Name::operator >= (const Name &name) const
613{
614 return (compare (name) >= 0);
615}
616
617inline bool
618Name::operator > (const Name &name) const
619{
620 return (compare (name) > 0);
621}
622
623inline name::Component &
624Name::operator [] (int index)
625{
626 return get (index);
627}
628
629inline const name::Component &
630Name::operator [] (int index) const
631{
632 return get (index);
633}
634
635} // ndn
636
637#endif