forked from cawka/ndn.cxx
diff --git a/ndn-cpp/fields/name-component.cc b/ndn-cpp/fields/name-component.cc
new file mode 100644
index 0000000..ecc87b1
--- /dev/null
+++ b/ndn-cpp/fields/name-component.cc
@@ -0,0 +1,170 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "name-component.h"
+
+#include "ndn-cpp/error.h"
+#include "ndn-cpp/helpers/uri.h"
+
+using namespace std;
+
+namespace ndn
+{
+namespace name
+{
+
+Component::Component ()
+{
+}
+
+Component::Component (const std::string &uri)
+{
+ try
+ {
+ Uri::fromEscaped (uri.begin (), uri.end (), back_inserter (*this));
+ }
+ catch (error::Uri &err)
+ {
+ // re-throwing different exception
+ BOOST_THROW_EXCEPTION (error::name::Component ()
+ << error::msg (uri)
+ << error::pos (error::get_pos (err)));
+ }
+}
+
+Component::Component (std::string::const_iterator begin, std::string::const_iterator end)
+{
+ try
+ {
+ Uri::fromEscaped (begin, end, back_inserter (*this));
+ }
+ catch (error::Uri &err)
+ {
+ // re-throwing different exception
+ BOOST_THROW_EXCEPTION (error::name::Component ()
+ << error::msg (string (begin, end))
+ << error::pos (error::get_pos (err)));
+ }
+}
+
+Component::Component (const void *buf, size_t length)
+{
+ copy (static_cast<const char*> (buf),
+ static_cast<const char*> (buf)+length,
+ back_inserter (*this));
+}
+
+int
+Component::compare (const Component &other) const
+{
+ if (size () < other.size ())
+ return -1;
+
+ if (size () > other.size ())
+ return +1;
+
+ // now we know that sizes are equal
+
+ pair<const_iterator, const_iterator> diff = mismatch (begin (), end (), other.begin ());
+ if (diff.first == end ()) // components are actually equal
+ return 0;
+
+ return (std::lexicographical_compare (diff.first, end (), diff.second, other.end ())) ? -1 : +1;
+}
+
+Component
+Component::fromNumber (uint64_t number)
+{
+ Component comp;
+ while (number > 0)
+ {
+ comp.push_back (static_cast<unsigned char> (number & 0xFF));
+ number >>= 8;
+ }
+ std::reverse (comp.begin (), comp.end ());
+ return comp;
+}
+
+Component
+Component::fromNumberWithMarker (uint64_t number, unsigned char marker)
+{
+ Component comp;
+ comp.push_back (marker);
+
+ while (number > 0)
+ {
+ comp.push_back (static_cast<unsigned char> (number & 0xFF));
+ number >>= 8;
+ }
+
+ std::reverse (comp.begin () + 1, comp.end ());
+ return comp;
+}
+
+std::string
+Component::toBlob () const
+{
+ return std::string (begin (), end ());
+}
+
+void
+Component::toBlob (std::ostream &os) const
+{
+ os.write (buf (), size ());
+}
+
+std::string
+Component::toUri () const
+{
+ ostringstream os;
+ toUri (os);
+ return os.str ();
+}
+
+void
+Component::toUri (std::ostream &os) const
+{
+ Uri::toEscaped (begin (), end (), ostream_iterator<char> (os));
+}
+
+uint64_t
+Component::toNumber () const
+{
+ uint64_t ret = 0;
+ for (const_iterator i = begin (); i != end (); i++)
+ {
+ ret <<= 8;
+ ret |= static_cast<unsigned char> (*i);
+ }
+ return ret;
+}
+
+uint64_t
+Component::toNumberWithMarker (unsigned char marker) const
+{
+ if (empty () ||
+ static_cast<unsigned char> (*(begin ())) != marker)
+ {
+ BOOST_THROW_EXCEPTION (error::name::Component ()
+ << error::msg ("Name component does not have required marker [" + toUri () + "]"));
+ }
+
+ uint64_t ret = 0;
+ for (const_iterator i = begin () + 1; i != end (); i++)
+ {
+ ret <<= 8;
+ ret |= static_cast<unsigned char> (*i);
+ }
+ return ret;
+}
+
+
+} // name
+} // ndn