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