blob: 0eeed2a5e3d264279628fb2a2b5eb08c8e2ad967 [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
Jeff Thompsonfa306642013-06-17 15:06:57 -0700396inline std::ostream &
397operator << (std::ostream &os, const Name &name)
398{
399 name.toUri (os);
400 return os;
401}
402
403
404/////////////////////////////////////////////////////////////////////////////////////
405// Definition of inline methods
406/////////////////////////////////////////////////////////////////////////////////////
407
408template<class Iterator>
409Name::Name (Iterator begin, Iterator end)
410{
411 append (begin, end);
412}
413
414inline Name &
415Name::append (const name::Component &comp)
416{
417 if (comp.size () != 0)
418 m_comps.push_back (comp);
419 return *this;
420}
421
422inline Name &
423Name::appendBySwap (name::Component &comp)
424{
425 if (comp.size () != 0)
426 {
427 Name::iterator newComp = m_comps.insert (end (), name::Component ());
428 newComp->swap (comp);
429 }
430 return *this;
431}
432
433template<class Iterator>
434inline Name &
435Name::append (Iterator begin, Iterator end)
436{
437 for (Iterator i = begin; i != end; i++)
438 {
439 append (*i);
440 }
441 return *this;
442}
443
444Name &
445Name::append (const Name &comp)
446{
447 if (this == &comp)
448 {
449 // have to double-copy if the object is self, otherwise results very frustrating (because we use vector...)
450 return append (Name (comp.begin (), comp.end ()));
451 }
452 return append (comp.begin (), comp.end ());
453}
454
455Name &
456Name::append (const std::string &compStr)
457{
458 name::Component comp (compStr);
459 return appendBySwap (comp);
460}
461
462Name &
463Name::append (const void *buf, size_t size)
464{
465 name::Component comp (buf, size);
466 return appendBySwap (comp);
467}
468
469Name &
470Name::appendNumber (uint64_t number)
471{
472 name::Component comp;
473 name::Component::fromNumber (number).swap (comp);
474 return appendBySwap (comp);
475}
476
477Name &
478Name::appendNumberWithMarker (uint64_t number, unsigned char marker)
479{
480 name::Component comp;
481 name::Component::fromNumberWithMarker (number, marker).swap (comp);
482 return appendBySwap (comp);
483}
484
485inline Name &
486Name::appendSeqNum (uint64_t seqno)
487{
488 return appendNumberWithMarker (seqno, 0x00);
489}
490
491inline Name &
492Name::appendControlNum (uint64_t control)
493{
494 return appendNumberWithMarker (control, 0xC1);
495}
496
497inline Name &
498Name::appendBlkId (uint64_t blkid)
499{
500 return appendNumberWithMarker (blkid, 0xFB);
501}
502
503inline size_t
504Name::size () const
505{
506 return m_comps.size ();
507}
508
509/////
510///// Iterator interface to name components
511/////
512inline Name::const_iterator
513Name::begin () const
514{
515 return m_comps.begin ();
516}
517
518inline Name::iterator
519Name::begin ()
520{
521 return m_comps.begin ();
522}
523
524inline Name::const_iterator
525Name::end () const
526{
527 return m_comps.end ();
528}
529
530inline Name::iterator
531Name::end ()
532{
533 return m_comps.end ();
534}
535
536inline Name::const_reverse_iterator
537Name::rbegin () const
538{
539 return m_comps.rbegin ();
540}
541
542inline Name::reverse_iterator
543Name::rbegin ()
544{
545 return m_comps.rbegin ();
546}
547
548inline Name::const_reverse_iterator
549Name::rend () const
550{
551 return m_comps.rend ();
552}
553
554
555inline Name::reverse_iterator
556Name::rend ()
557{
558 return m_comps.rend ();
559}
560
561
562//// helpers
563
564
565inline Name
566Name::getPrefix (size_t len, size_t skip/* = 0*/) const
567{
568 return getSubName (skip, len);
569}
570
571inline Name
572Name::getPostfix (size_t len, size_t skip/* = 0*/) const
573{
574 return getSubName (size () - len - skip, len);
575}
576
577
578template<class T>
579inline void
580Name::push_back (const T &comp)
581{
582 append (comp);
583}
584
585inline bool
586Name::operator ==(const Name &name) const
587{
588 return (compare (name) == 0);
589}
590
591inline bool
592Name::operator !=(const Name &name) const
593{
594 return (compare (name) != 0);
595}
596
597inline bool
598Name::operator <= (const Name &name) const
599{
600 return (compare (name) <= 0);
601}
602
603inline bool
604Name::operator < (const Name &name) const
605{
606 return (compare (name) < 0);
607}
608
609inline bool
610Name::operator >= (const Name &name) const
611{
612 return (compare (name) >= 0);
613}
614
615inline bool
616Name::operator > (const Name &name) const
617{
618 return (compare (name) > 0);
619}
620
621inline name::Component &
622Name::operator [] (int index)
623{
624 return get (index);
625}
626
627inline const name::Component &
628Name::operator [] (int index) const
629{
630 return get (index);
631}
632
633} // ndn
634
635#endif