NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
name.cc
1 /* -*- 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 #include "name.h"
14 
15 #include "detail/error.h"
16 #include <boost/algorithm/string.hpp>
17 
18 #include <ctype.h>
19 
20 using namespace std;
21 
22 NDN_NAMESPACE_BEGIN
23 
24 ATTRIBUTE_HELPER_CPP (Name);
25 
27 // CONSTRUCTORS //
29 
30 Name::Name ()
31 {
32 }
33 
34 Name::Name (const string &uri)
35 {
36  string::const_iterator i = uri.begin ();
37  string::const_iterator end = uri.end ();
38 
39  string::const_iterator firstSlash = std::find (i, end, '/');
40  if (firstSlash == end)
41  {
42  BOOST_THROW_EXCEPTION (error::Name ()
43  << error::msg ("Name should include at least one slash (did you forget to specify initial /?)"));
44  }
45 
46  if (firstSlash != i)
47  {
48  string schema (i, firstSlash);
49  if (*schema.rbegin () != ':')
50  {
51  BOOST_THROW_EXCEPTION (error::Name ()
52  << error::msg ("First component of the name does not start with a slash (did you forget to specify initial /?)"));
53  }
54 
55  i = firstSlash;
56 
57  if (!boost::iequals (schema, "ccnx:") &&
58  !boost::iequals (schema, "ndn:"))
59  {
60  BOOST_THROW_EXCEPTION (error::Name ()
61  << error::msg ("URI schema is not supported (only ccnx: or ndn: is allowed)")
62  << error::msg (schema));
63  }
64  }
65 
66  string::const_iterator secondSlash = i;
67  secondSlash ++;
68  if (secondSlash != end && *secondSlash == '/')
69  {
70  // The authority component (the part after the initial "//" in the familiar http and ftp URI schemes) is present,
71  // but it is not relevant to NDN name.
72  // skipping it
73  secondSlash ++;
74  i = std::find (secondSlash, end, '/');
75  }
76 
77  if (i == end)
78  {
79  BOOST_THROW_EXCEPTION (error::Name ()
80  << error::msg ("Invalid URI")
81  << error::msg (uri));
82  }
83 
84  while (i != end)
85  {
86  // skip any extra slashes
87  while (i != end && *i == '/')
88  {
89  i ++;
90  }
91  if (i == end)
92  break;
93 
94  string::const_iterator endOfComponent = std::find (i, end, '/');
95  name::Component comp;
96  appendBySwap (comp.fromUri (i, endOfComponent));
97 
98  i = endOfComponent;
99  }
100 }
101 
102 Name::Name (const Name &other)
103 {
104  m_comps = other.m_comps;
105 }
106 
107 Name &
108 Name::operator= (const Name &other)
109 {
110  m_comps = other.m_comps;
111  return *this;
112 }
113 
115 // SETTERS //
117 
118 Name &
119 Name::appendVersion (uint64_t version/* = Name::nversion*/)
120 {
121  if (version != Name::nversion)
122  return appendNumberWithMarker (version, 0xFD);
123  else
124  {
125  TimeInterval now = time::NowUnixTimestamp ();
126 #ifdef NDNSIM_MODE
127  int64_t seconds = now.GetSeconds ();
128  int64_t microseconds = now.GetMicroSeconds () - seconds * 1000000;
129 
130  version = (seconds << 12) | (0xFFF & (microseconds / 244 /*( 1000,000 microseconds / 4096.0 resolution = last 12 bits)*/));
131 #else
132  version = (now.total_seconds () << 12) | (0xFFF & (now.fractional_seconds () / 244 /*( 1000,000 microseconds / 4096.0 resolution = last 12 bits)*/));
133 #endif
134  return appendNumberWithMarker (version, 0xFD);
135  }
136 }
137 
138 
140 // GETTERS //
142 
143 const name::Component &
144 Name::get (int index) const
145 {
146  if (index < 0)
147  {
148  index = size () - (-index);
149  }
150 
151  if (static_cast<unsigned int> (index) >= size ())
152  {
153  BOOST_THROW_EXCEPTION (error::Name ()
154  << error::msg ("Index out of range")
155  << error::pos (index));
156  }
157  return m_comps [index];
158 }
159 
161 Name::get (int index)
162 {
163  if (index < 0)
164  {
165  index = size () - (-index);
166  }
167 
168  if (static_cast<unsigned int> (index) >= size())
169  {
170  BOOST_THROW_EXCEPTION (error::Name ()
171  << error::msg ("Index out of range")
172  << error::pos (index));
173  }
174  return m_comps [index];
175 }
176 
177 
181 
182 
183 Name
184 Name::getSubName (size_t pos/* = 0*/, size_t len/* = Name::npos*/) const
185 {
186  Name retval;
187 
188  if (len == npos)
189  {
190  len = size () - pos;
191  }
192 
193  if (pos + len > size ())
194  {
195  BOOST_THROW_EXCEPTION (error::Name ()
196  << error::msg ("getSubName parameter out of range")
197  << error::pos (pos)
198  << error::pos (len));
199  }
200 
201  for (size_t i = pos; i < pos + len; i++)
202  {
203  retval.append (get (i));
204  }
205 
206  return retval;
207 }
208 
209 Name
210 Name::operator+ (const Name &name) const
211 {
212  Name newName;
213  newName
214  .append (*this)
215  .append (name);
216 
217  return newName;
218 }
219 
220 std::string
221 Name::toUri () const
222 {
223  ostringstream os;
224  toUri (os);
225  return os.str ();
226 }
227 
228 void
229 Name::toUri (std::ostream &os) const
230 {
231  for (Name::const_iterator comp = begin (); comp != end (); comp++)
232  {
233  os << "/";
234  comp->toUri (os);
235  }
236  if (size () == 0)
237  os << "/";
238 }
239 
240 // ostream &
241 // operator << (ostream &os, const Name &name)
242 // {
243 // for (Name::const_iterator comp = name.begin (); comp != name.end (); comp++)
244 // {
245 // os << "/" << *comp;
246 // }
247 // if (name.size () == 0)
248 // os << "/";
249 // return os;
250 // }
251 
252 int
253 Name::compare (const Name &name) const
254 {
255  Name::const_iterator i = this->begin ();
256  Name::const_iterator j = name.begin ();
257 
258  for (; i != this->end () && j != name.end (); i++, j++)
259  {
260  int res = i->compare (*j);
261  if (res == 0)
262  continue;
263  else
264  return res;
265  }
266 
267  if (i == this->end () && j == name.end ())
268  return 0; // prefixes are equal
269 
270  return (i == this->end ()) ? -1 : +1;
271 }
272 
273 NDN_NAMESPACE_END
Class for NDN Name.
Definition: name.h:29
Name::const_iterator end() const
End iterator (const)
Definition: name.h:537
Name::const_iterator begin() const
Begin iterator (const)
Definition: name.h:525
boost::error_info< struct tag_msg, std::string > msg
Free-formatted text message explaining the error.
Definition: error.h:75
This file defines basic elements for the library reporting.
Name & append(const name::Component &comp)
Append a binary blob as a name component.
Definition: name.h:429
An error with Name.
Definition: error.h:48
boost::error_info< struct tag_pos, int > pos
Report of the position of the error (error-specific meaning)
Definition: error.h:105
Class to representing binary blob of NDN name component.