forked from cawka/ndn.cxx
diff --git a/ndn-cpp/fields/name-component.h b/ndn-cpp/fields/name-component.h
new file mode 100644
index 0000000..0bcf862
--- /dev/null
+++ b/ndn-cpp/fields/name-component.h
@@ -0,0 +1,282 @@
+/* -*- 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>
+ */
+
+#ifndef NDN_NAME_COMPONENT_H
+#define NDN_NAME_COMPONENT_H
+
+#include <string>
+#include <vector>
+
+#include "blob.h"
+#include <stdint.h>
+
+namespace ndn {
+
+namespace name {
+
+/**
+ * @brief Class to representing binary blob of NDN name component
+ *
+ * This class is based on std::vector<char> and just provides several helpers
+ * to work with name components, as well as operator to apply canonical
+ * ordering on name components
+ */
+class Component : public Blob
+{
+public:
+  /**
+   * @brief Default constructor an empty exclude
+   */
+  Component ();
+
+  /**
+   * @brief Create component from URI encoded string
+   * @param uri URI encoded name component (convert escaped with % characters)
+   */
+  Component (const std::string &uri);
+
+  /**
+   * @brief Create component from URI encoded string, with string specified by a pair of iterators
+   * @param begin begin iterator pointing to the URI encoded name
+   * @param end end iterator
+   */
+  Component (std::string::const_iterator begin, std::string::const_iterator end);
+  
+  /**
+   * @brief Create component using a binary blob
+   * @param buf pointer to first byte of binary blob to store as a name component
+   * @param length length of the binary blob
+   */
+  Component (const void *buf, size_t length);
+
+  /**
+   * @brief Apply canonical ordering on component comparison
+   * @return 0  They compare equal
+   *         <0 If *this comes before other in the canonical ordering
+   *         >0 If *this comes after in the canonical ordering
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  int
+  compare (const Component &other) const;
+  
+  /**
+   * @brief Apply canonical ordering on component comparison (less or equal)
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  inline bool
+  operator <= (const Component &other) const;
+
+  /**
+   * @brief Apply canonical ordering on component comparison (less)
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  inline bool
+  operator < (const Component &other) const;
+
+  /**
+   * @brief Apply canonical ordering on component comparison (greater or equal)
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  inline bool
+  operator >= (const Component &other) const;
+
+  /**
+   * @brief Apply canonical ordering on component comparison (greater)
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  inline bool
+  operator > (const Component &other) const;
+
+  ////////////////////////////////////
+  // Component construction helpers //
+  ////////////////////////////////////
+
+  /**
+   * @brief Create network-ordered numeric component
+   *
+   * @param number number to be encoded and added as a component
+   *
+   * Number is encoded and added in network order. Tail zero-bytes are not included.
+   * For example, if the number is 1, then 1-byte binary blob will be added  0x01.
+   * If the number is 256, then 2 binary blob will be added: 0x01 0x01
+   *
+   * If the number is zero, an empty component will be created
+   */
+  static Component
+  fromNumber (uint64_t number);
+
+  /**
+   * @brief Create network-ordered numeric component to the name with marker
+   *
+   * @param number number to be encoded and added as a component
+   * @param marker byte marker, specified by the desired naming convention
+   *
+   * Currently defined naming conventions of the marker:
+   * - 0x00  sequence number
+   * - 0xC1  control number
+   * - 0xFB  block id
+   * - 0xFD  version number
+   *
+   * This version is almost exactly as appendNumber, with exception that it adds initial marker.
+   * The number is formatted in the exactly the same way.
+   *
+   * @see fromNumber
+   */
+  static Component
+  fromNumberWithMarker (uint64_t number, unsigned char marker);
+  
+  //////////////////////////////////////////////////////////////////////////////////
+  // helpers
+  //////////////////////////////////////////////////////////////////////////////////
+  
+  /**
+   * @brief Convert binary blob name component to std::string (no conversion is made)
+   * @param comp name component to be converted
+   * @see asUriString
+   */  
+  std::string
+  toBlob () const;
+
+  /**
+   * @brief Write blob of the name component to the specified output stream
+   * @param os output stream
+   */
+  void
+  toBlob (std::ostream &os) const;
+
+  /**
+   * @brief Convert binary blob name component to std::string, escaping all non-printable characters in URI format
+   * @param comp name component to be converted
+   * @see asString
+   */
+  std::string
+  toUri () const;
+
+  /**
+   * @brief Write name as URI to the specified output stream
+   * @param os output stream
+   */
+  void
+  toUri (std::ostream &os) const;
+  
+  /**
+   * @brief Convert binary blob name component (network-ordered number) to number
+   * @param comp name component to be converted
+   */  
+  uint64_t
+  toNumber () const;
+
+  /**
+   * @brief Convert binary blob name component (network-ordered number) to number, using appropriate marker from the naming convention
+   * @param comp name component to be converted
+   * @param marker required marker from the naming convention
+   *
+   * If the required marker does not exist, an exception will be thrown
+   */  
+  uint64_t
+  toNumberWithMarker (unsigned char marker) const;
+
+  /**
+   * @brief Convert binary blob name component, assuming sequence number naming convention (marker = 0x00)
+   * @param comp name component to be converted
+   * @see asNumberWithMarker
+   */
+  inline uint64_t
+  toSeqNum () const;
+  
+  /**
+   * @brief Convert binary blob name component, assuming control number naming convention (marker = 0xC1)
+   * @param comp name component to be converted
+   * @see asNumberWithMarker
+   */
+  inline uint64_t
+  toControlNum () const;
+
+  /**
+   * @brief Convert binary blob name component, assuming block ID naming convention (marker = 0xFB)
+   * @param comp name component to be converted
+   * @see asNumberWithMarker
+   */
+  inline uint64_t
+  toBlkId () const;
+
+  /**
+   * @brief Convert binary blob name component, assuming time-stamping version naming convention (marker = 0xFD)
+   * @param comp name component to be converted
+   * @see asNumberWithMarker
+   */
+  inline uint64_t
+  toVersion () const;
+};
+
+bool
+Component::operator <= (const Component &other) const
+{
+  return (compare (other) <= 0);
+}
+
+bool
+Component::operator < (const Component &other) const
+{
+  return (compare (other) < 0);
+}
+
+bool
+Component::operator >= (const Component &other) const
+{
+  return (compare (other) >= 0);
+}
+
+bool
+Component::operator > (const Component &other) const
+{
+  return (compare (other) > 0);
+}
+
+inline uint64_t
+Component::toSeqNum () const
+{
+  return toNumberWithMarker (0x00);
+}
+  
+inline uint64_t
+Component::toControlNum () const
+{
+  return toNumberWithMarker (0xC1);
+}
+
+inline uint64_t
+Component::toBlkId () const
+{
+  return toNumberWithMarker (0xFB);
+}
+
+inline uint64_t
+Component::toVersion () const
+{
+  return toNumberWithMarker (0xFD);
+}
+
+/**
+ * @brief Stream output operator (output in escaped URI format)
+ */
+std::ostream&
+operator <<(std::ostream &os, const Component &name);
+
+} // name
+
+} // ndn
+
+#endif // NDN_EXCLUDE_H