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