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-component.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  *
6  * BSD license, See the LICENSE file for more information
7  *
8  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9  */
10 
11 #if __clang__
12 #pragma clang diagnostic push
13 #pragma clang diagnostic ignored "-Wreorder"
14 #elif __GNUC__
15 #pragma GCC diagnostic ignored "-Wreorder"
16 #endif
17 
18 #include "name-component.h"
19 
20 #include "detail/error.h"
21 #include "detail/uri.h"
22 
23 NDN_NAMESPACE_BEGIN
24 
25 namespace name {
26 
27 Component::Component ()
28 {
29 }
30 
31 Component::Component (const std::string &uri)
32 {
33  copy (uri.begin (), uri.end (), std::back_inserter (*this));
34 }
35 
36 Component::Component (std::string::const_iterator begin, std::string::const_iterator end)
37 {
38  copy (begin, end, std::back_inserter (*this));
39 }
40 
41 Component::Component (const void *buf, size_t length)
42 {
43  copy (static_cast<const char*> (buf),
44  static_cast<const char*> (buf)+length,
45  std::back_inserter (*this));
46 }
47 
48 Component &
49 Component::fromUri (const std::string &uri)
50 {
51  try
52  {
53  Uri::fromEscaped (uri.begin (), uri.end (), std::back_inserter (*this));
54  }
55  catch (error::Uri &err)
56  {
57  // re-throwing different exception
58  BOOST_THROW_EXCEPTION (error::name::Component ()
59  << error::msg (uri)
60  << error::pos (error::get_pos (err)));
61  }
62 
63  return *this;
64 }
65 
66 Component &
67 Component::fromUri (std::string::const_iterator begin, std::string::const_iterator end)
68 {
69  try
70  {
71  Uri::fromEscaped (begin, end, std::back_inserter (*this));
72  }
73  catch (error::Uri &err)
74  {
75  // re-throwing different exception
76  BOOST_THROW_EXCEPTION (error::name::Component ()
77  << error::msg (std::string (begin, end))
78  << error::pos (error::get_pos (err)));
79  }
80  return *this;
81 }
82 
83 int
84 Component::compare (const Component &other) const
85 {
86  if (size () < other.size ())
87  return -1;
88 
89  if (size () > other.size ())
90  return +1;
91 
92  // now we know that sizes are equal
93 
94  std::pair<const_iterator, const_iterator> diff = mismatch (begin (), end (), other.begin ());
95  if (diff.first == end ()) // components are actually equal
96  return 0;
97 
98  return (std::lexicographical_compare (diff.first, end (), diff.second, other.end ())) ? -1 : +1;
99 }
100 
101 Component &
102 Component::fromNumber (uint64_t number)
103 {
104  while (number > 0)
105  {
106  this->push_back (static_cast<unsigned char> (number & 0xFF));
107  number >>= 8;
108  }
109  std::reverse (this->begin (), this->end ());
110  return *this;
111 }
112 
113 Component &
114 Component::fromNumberWithMarker (uint64_t number, unsigned char marker)
115 {
116  this->push_back (marker);
117 
118  while (number > 0)
119  {
120  this->push_back (static_cast<unsigned char> (number & 0xFF));
121  number >>= 8;
122  }
123 
124  std::reverse (this->begin () + 1, this->end ());
125  return *this;
126 }
127 
128 std::string
129 Component::toBlob () const
130 {
131  return std::string (begin (), end ());
132 }
133 
134 void
135 Component::toBlob (std::ostream &os) const
136 {
137  os.write (buf (), size ());
138 }
139 
140 std::string
141 Component::toUri () const
142 {
143  std::ostringstream os;
144  toUri (os);
145  return os.str ();
146 }
147 
148 void
149 Component::toUri (std::ostream &os) const
150 {
151  const uint8_t* valuePtr = reinterpret_cast<const uint8_t*>(buf());
152  size_t valueSize = size();
153 
154  bool gotNonDot = false;
155  for (unsigned i = 0; i < valueSize; ++i) {
156  if (valuePtr[i] != 0x2e) {
157  gotNonDot = true;
158  break;
159  }
160  }
161  if (!gotNonDot) {
162  // Special case for component of zero or more periods. Add 3 periods.
163  os << "...";
164  for (size_t i = 0; i < valueSize; ++i)
165  os << '.';
166  }
167  else {
168  // In case we need to escape, set to upper case hex and save the previous flags.
169  std::ios::fmtflags saveFlags = os.flags(std::ios::hex | std::ios::uppercase);
170 
171  for (size_t i = 0; i < valueSize; ++i) {
172  uint8_t x = valuePtr[i];
173  // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
174  if ((x >= 0x30 && x <= 0x39) || (x >= 0x41 && x <= 0x5a) ||
175  (x >= 0x61 && x <= 0x7a) || x == 0x2b || x == 0x2d ||
176  x == 0x2e || x == 0x5f)
177  os << x;
178  else {
179  os << '%';
180  if (x < 16)
181  os << '0';
182  os << static_cast<unsigned int>(x);
183  }
184  }
185 
186  // Restore.
187  os.flags(saveFlags);
188  }
189 }
190 
191 uint64_t
192 Component::toNumber () const
193 {
194  uint64_t ret = 0;
195  for (const_iterator i = begin (); i != end (); i++)
196  {
197  ret <<= 8;
198  ret |= static_cast<unsigned char> (*i);
199  }
200  return ret;
201 }
202 
203 uint64_t
204 Component::toNumberWithMarker (unsigned char marker) const
205 {
206  if (empty () ||
207  static_cast<unsigned char> (*(begin ())) != marker)
208  {
209  BOOST_THROW_EXCEPTION (error::name::Component ()
210  << error::msg ("Name component does not have required marker [" + toUri () + "]"));
211  }
212 
213  uint64_t ret = 0;
214  for (const_iterator i = begin () + 1; i != end (); i++)
215  {
216  ret <<= 8;
217  ret |= static_cast<unsigned char> (*i);
218  }
219  return ret;
220 }
221 
222 } // name
223 
224 NDN_NAMESPACE_END
int get_pos(boost::exception &e)
Helper method to get position of the error from the exception.
Definition: error.h:113
An error with name::Component.
Definition: error.h:50
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.
boost::error_info< struct tag_pos, int > pos
Report of the position of the error (error-specific meaning)
Definition: error.h:105
An error with URI processing.
Definition: error.h:46
Class to representing binary blob of NDN name component.