model: Another major change: switching to NDN.cxx API for ndn::Name

NDN.cxx code is almost exactly the same, with minor NS-3 specific customizations

Refs #1011 (http://redmine.named-data.net/issues/1011)
diff --git a/ndn.cxx/name.cc b/ndn.cxx/name.cc
new file mode 100644
index 0000000..3bb2416
--- /dev/null
+++ b/ndn.cxx/name.cc
@@ -0,0 +1,272 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *         Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ */
+
+#include "name.h"
+
+#include "detail/error.h"
+#include <boost/algorithm/string.hpp>
+
+#include <ctype.h>
+
+using namespace std;
+
+NDN_NAMESPACE_BEGIN
+
+ATTRIBUTE_HELPER_CPP (Name);
+
+///////////////////////////////////////////////////////////////////////////////
+//                              CONSTRUCTORS                                 //
+///////////////////////////////////////////////////////////////////////////////
+
+Name::Name ()
+{
+}
+
+Name::Name (const string &uri)
+{ 
+  string::const_iterator i = uri.begin ();
+  string::const_iterator end = uri.end ();
+
+  string::const_iterator firstSlash = std::find (i, end, '/');
+  if (firstSlash == end)
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("Name should include at least one slash (did you forget to specify initial /?)"));
+    }
+
+  if (firstSlash != i)
+    {
+      string schema (i, firstSlash);
+      if (*schema.rbegin () != ':')
+        {
+          BOOST_THROW_EXCEPTION (error::Name ()
+                                 << error::msg ("First component of the name does not start with a slash (did you forget to specify initial /?)"));
+        }
+
+      i = firstSlash;
+
+      if (!boost::iequals (schema, "ccnx:") &&
+          !boost::iequals (schema, "ndn:"))
+        {
+          BOOST_THROW_EXCEPTION (error::Name ()
+                                 << error::msg ("URI schema is not supported (only ccnx: or ndn: is allowed)")
+                                 << error::msg (schema));
+        }
+    }
+
+  string::const_iterator secondSlash = i;
+  secondSlash ++;
+  if (secondSlash != end && *secondSlash == '/')
+    {
+      // The authority component (the part after the initial "//" in the familiar http and ftp URI schemes) is present,
+      // but it is not relevant to NDN name.
+      // skipping it
+      secondSlash ++;
+      i = std::find (secondSlash, end, '/');
+    }
+  
+  if (i == end)
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("Invalid URI")
+                             << error::msg (uri));
+    }
+
+  while (i != end)
+    {
+      // skip any extra slashes
+      while (i != end && *i == '/')
+        {
+          i ++;
+        }
+      if (i == end)
+        break;
+      
+      string::const_iterator endOfComponent = std::find (i, end, '/');
+      append (name::Component (i, endOfComponent));
+
+      i = endOfComponent;
+    }
+}
+
+Name::Name (const Name &other)
+{
+  m_comps = other.m_comps;
+}
+
+Name &
+Name::operator= (const Name &other)
+{
+  m_comps = other.m_comps;
+  return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//                                SETTERS                                    //
+///////////////////////////////////////////////////////////////////////////////
+
+Name &
+Name::appendVersion (uint64_t version/* = Name::nversion*/)
+{
+  if (version != Name::nversion)
+    return appendNumberWithMarker (version, 0xFD);
+  else
+    {
+      TimeInterval now = time::NowUnixTimestamp ();
+#ifdef NDNSIM_MODE
+      int64_t seconds = now.GetSeconds ();
+      int64_t microseconds = now.GetMicroSeconds () - seconds * 1000000;
+      
+      version = (seconds << 12) | (0xFFF & (microseconds / 244 /*( 1000,000 microseconds / 4096.0 resolution = last 12 bits)*/));
+#else
+      version = (now.total_seconds () << 12) | (0xFFF & (now.fractional_seconds () / 244 /*( 1000,000 microseconds / 4096.0 resolution = last 12 bits)*/));
+#endif
+      return appendNumberWithMarker (version, 0xFD);
+    }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//                                GETTERS                                    //
+///////////////////////////////////////////////////////////////////////////////
+
+const name::Component &
+Name::get (int index) const
+{
+  if (index < 0)
+    {
+      index = size () - (-index);
+    }
+
+  if (static_cast<unsigned int> (index) >= size ())
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("Index out of range")
+                             << error::pos (index));
+    }
+  return m_comps [index];
+}
+
+name::Component &
+Name::get (int index)
+{
+  if (index < 0)
+    {
+      index = size () - (-index);
+    }
+
+  if (static_cast<unsigned int> (index) >= size())
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("Index out of range")
+                             << error::pos (index));
+    }
+  return m_comps [index];
+}
+
+
+/////
+///// Static helpers to convert name component to appropriate value
+/////
+
+
+Name
+Name::getSubName (size_t pos/* = 0*/, size_t len/* = Name::npos*/) const
+{
+  Name retval;
+
+  if (len == npos)
+    {
+      len = size () - pos;
+    }
+
+  if (pos + len > size ())
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("getSubName parameter out of range")
+                             << error::pos (pos)
+                             << error::pos (len));
+    }
+
+  for (size_t i = pos; i < pos + len; i++)
+    {
+      retval.append (get (i));
+    }
+
+  return retval;
+}
+
+Name
+Name::operator+ (const Name &name) const
+{
+  Name newName;
+  newName
+    .append (*this)
+    .append (name);
+
+  return newName;
+}
+
+std::string
+Name::toUri () const
+{
+  ostringstream os;
+  toUri (os);
+  return os.str ();
+}
+
+void
+Name::toUri (std::ostream &os) const
+{
+  for (Name::const_iterator comp = begin (); comp != end (); comp++)
+    {
+      os << "/";
+      comp->toUri (os);
+    }
+  if (size () == 0)
+    os << "/";
+}
+
+// ostream &
+// operator << (ostream &os, const Name &name)
+// {
+//   for (Name::const_iterator comp = name.begin (); comp != name.end (); comp++)
+//     {
+//       os << "/" << *comp;
+//     }
+//   if (name.size () == 0)
+//     os << "/";
+//   return os;
+// }
+
+int
+Name::compare (const Name &name) const
+{
+  Name::const_iterator i = this->begin ();
+  Name::const_iterator j = name.begin ();
+
+  for (; i != this->end () && j != name.end (); i++, j++)
+    {
+      int res = i->compare (*j);
+      if (res == 0)
+        continue;
+      else
+        return res;
+    }
+
+  if (i == this->end () && j == name.end ())
+    return 0; // prefixes are equal
+
+  return (i == this->end ()) ? -1 : +1;
+}
+
+NDN_NAMESPACE_END