blob: b456bc726a49d331860fa38a121b74e54a5778cd [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;
486 name::Component::fromNumber (number).swap (comp);
487 return appendBySwap (comp);
488}
489
490Name &
491Name::appendNumberWithMarker (uint64_t number, unsigned char marker)
492{
493 name::Component comp;
494 name::Component::fromNumberWithMarker (number, marker).swap (comp);
495 return appendBySwap (comp);
496}
497
498inline Name &
499Name::appendSeqNum (uint64_t seqno)
500{
501 return appendNumberWithMarker (seqno, 0x00);
502}
503
504inline Name &
505Name::appendControlNum (uint64_t control)
506{
507 return appendNumberWithMarker (control, 0xC1);
508}
509
510inline Name &
511Name::appendBlkId (uint64_t blkid)
512{
513 return appendNumberWithMarker (blkid, 0xFB);
514}
515
516inline size_t
517Name::size () const
518{
519 return m_comps.size ();
520}
521
522/////
523///// Iterator interface to name components
524/////
525inline Name::const_iterator
526Name::begin () const
527{
528 return m_comps.begin ();
529}
530
531inline Name::iterator
532Name::begin ()
533{
534 return m_comps.begin ();
535}
536
537inline Name::const_iterator
538Name::end () const
539{
540 return m_comps.end ();
541}
542
543inline Name::iterator
544Name::end ()
545{
546 return m_comps.end ();
547}
548
549inline Name::const_reverse_iterator
550Name::rbegin () const
551{
552 return m_comps.rbegin ();
553}
554
555inline Name::reverse_iterator
556Name::rbegin ()
557{
558 return m_comps.rbegin ();
559}
560
561inline Name::const_reverse_iterator
562Name::rend () const
563{
564 return m_comps.rend ();
565}
566
567
568inline Name::reverse_iterator
569Name::rend ()
570{
571 return m_comps.rend ();
572}
573
574
575//// helpers
576
577
578inline Name
579Name::getPrefix (size_t len, size_t skip/* = 0*/) const
580{
581 return getSubName (skip, len);
582}
583
584inline Name
585Name::getPostfix (size_t len, size_t skip/* = 0*/) const
586{
587 return getSubName (size () - len - skip, len);
588}
589
590
591template<class T>
592inline void
593Name::push_back (const T &comp)
594{
595 append (comp);
596}
597
598inline bool
599Name::operator ==(const Name &name) const
600{
601 return (compare (name) == 0);
602}
603
604inline bool
605Name::operator !=(const Name &name) const
606{
607 return (compare (name) != 0);
608}
609
610inline bool
611Name::operator <= (const Name &name) const
612{
613 return (compare (name) <= 0);
614}
615
616inline bool
617Name::operator < (const Name &name) const
618{
619 return (compare (name) < 0);
620}
621
622inline bool
623Name::operator >= (const Name &name) const
624{
625 return (compare (name) >= 0);
626}
627
628inline bool
629Name::operator > (const Name &name) const
630{
631 return (compare (name) > 0);
632}
633
634inline name::Component &
635Name::operator [] (int index)
636{
637 return get (index);
638}
639
640inline const name::Component &
641Name::operator [] (int index) const
642{
643 return get (index);
644}
645
646ATTRIBUTE_HELPER_HEADER (Name);
647
648NDN_NAMESPACE_END
649
650#endif