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