model: Slight modification with wire format processing

Now it is possible to convert Name from/to wire format via ndn::Face
helper method (since Face is getting configured with specific wire
format)

Refs #1008 (http://redmine.named-data.net/issues/1008)
diff --git a/apps/ndn-consumer-cbr.cc b/apps/ndn-consumer-cbr.cc
index 431f9ba..9a0a638 100644
--- a/apps/ndn-consumer-cbr.cc
+++ b/apps/ndn-consumer-cbr.cc
@@ -27,6 +27,7 @@
 #include "ns3/string.h"
 #include "ns3/boolean.h"
 #include "ns3/uinteger.h"
+#include "ns3/integer.h"
 #include "ns3/double.h"
 
 #include "ns3/ndn-app-face.h"
diff --git a/apps/ndn-consumer.cc b/apps/ndn-consumer.cc
index b6dba28..adbce0f 100644
--- a/apps/ndn-consumer.cc
+++ b/apps/ndn-consumer.cc
@@ -27,6 +27,7 @@
 #include "ns3/string.h"
 #include "ns3/boolean.h"
 #include "ns3/uinteger.h"
+#include "ns3/integer.h"
 #include "ns3/double.h"
 
 #include "ns3/ndn-app-face.h"
diff --git a/model/ndn-face.cc b/model/ndn-face.cc
index 9434ed8..a408dc4 100644
--- a/model/ndn-face.cc
+++ b/model/ndn-face.cc
@@ -35,7 +35,9 @@
 #include "ns3/ndn-header-helper.h"
 #include "ns3/ndnSIM/utils/ndn-fw-hop-count-tag.h"
 #include "ns3/ndnSIM/model/wire/ndnsim.h"
+#include "ns3/ndnSIM/model/wire/ndnsim/wire-ndnsim.h"
 #include "ns3/ndnSIM/model/wire/ccnb.h"
+#include "ns3/ndnSIM/model/wire/ccnb/wire-ccnb.h"
 
 #include <boost/ref.hpp>
 
@@ -311,6 +313,56 @@
   return os;
 }
 
+uint32_t
+Face::NameToWireSize (Ptr<Name> name) const
+{
+  if (m_wireFormat == WIRE_FORMAT_NDNSIM)
+    return wire::NdnSim::SerializedSizeName (*name);
+  else if (m_wireFormat == WIRE_FORMAT_CCNB)
+    return wire::Ccnb::SerializedSizeName (*name);
+  else
+    {
+      NS_FATAL_ERROR ("Unsupported format requested");
+    }
+  return 0;
+}
+  
+/**
+ * @brief Convert name to wire format
+ */
+void
+Face::NameToWire (Buffer::Iterator start, Ptr<const Name> name) const
+{
+  if (m_wireFormat == WIRE_FORMAT_NDNSIM)
+    wire::NdnSim::SerializedSizeName (*name);
+  else if (m_wireFormat == WIRE_FORMAT_CCNB)
+    wire::Ccnb::SerializedSizeName (*name);
+  else
+    {
+      NS_FATAL_ERROR ("Unsupported format requested");
+    }
+}
+
+/**
+ * @brief Convert name from wire format
+ */
+Ptr<Name>
+Face::NameFromWire (Buffer::Iterator start) const
+{
+  if (m_wireFormat == WIRE_FORMAT_NDNSIM)
+    return wire::NdnSim::DeserializeName (start);
+  else if (m_wireFormat == WIRE_FORMAT_CCNB)
+    {
+      return wire::Ccnb::DeserializeName (start);
+    }
+  else
+    {
+      NS_FATAL_ERROR ("Unsupported format requested");
+    }
+  return 0;
+}
+
+
 } // namespace ndn
 } // namespace ns3
 
diff --git a/model/ndn-face.h b/model/ndn-face.h
index 1fba08f..86003ff 100644
--- a/model/ndn-face.h
+++ b/model/ndn-face.h
@@ -29,7 +29,7 @@
 #include "ns3/nstime.h"
 #include "ns3/type-id.h"
 #include "ns3/traced-callback.h"
-#include "ns3/ndn-limits.h"
+#include "ns3/ndn-name.h"
 
 namespace ns3 {
 
@@ -248,6 +248,27 @@
   bool
   operator< (const Face &face) const;
 
+  ///////////////////////////////////////////////////////////////////////////////
+  // Helpers to create wire-formatted data in default wire format, since settings about
+  // the wire format belong to the face
+  /*
+   * @brief Get size of buffer to fit wire-formatted name object
+   */
+  uint32_t
+  NameToWireSize (Ptr<Name> name) const;
+  
+  /**
+   * @brief Convert name to wire format
+   */
+  void
+  NameToWire (Buffer::Iterator start, Ptr<const Name> name) const;
+
+  /**
+   * @brief Convert name from wire format
+   */
+  Ptr<Name>
+  NameFromWire (Buffer::Iterator start) const;
+  
 protected:
   /**
    * @brief Send packet down to the stack (towards app or network)
diff --git a/model/ndn-interest.cc b/model/ndn-interest.cc
index 134cd01..7364701 100644
--- a/model/ndn-interest.cc
+++ b/model/ndn-interest.cc
@@ -55,6 +55,17 @@
 {
 }
 
+Interest::Interest (Ptr<const Interest> interest)
+  : m_name             (Create<Name> (interest->GetName ()))
+  , m_scope            (interest->m_scope)
+  , m_interestLifetime (interest->m_interestLifetime)
+  , m_nonce            (interest->m_nonce)
+  , m_nackType         (interest->m_nackType)
+  , m_payload          (interest->GetPayload ()->Copy ())
+  , m_wire             (0)
+{
+}
+
 void
 Interest::SetName (Ptr<Name> name)
 {
diff --git a/model/ndn-interest.h b/model/ndn-interest.h
index d0959a9..050cc9f 100644
--- a/model/ndn-interest.h
+++ b/model/ndn-interest.h
@@ -55,6 +55,11 @@
   Interest (const Interest &interest);
 
   /**
+   * @brief Another version of copy constructor
+   */
+  Interest (Ptr<const Interest> interest);  
+
+  /**
    * \brief Set interest name
    *
    * @param name smart pointer to Name
diff --git a/model/wire/ccnb/ccnb-parser/visitors/name-visitor.cc b/model/wire/ccnb/ccnb-parser/visitors/name-visitor.cc
index 13043d3..965b320 100644
--- a/model/wire/ccnb/ccnb-parser/visitors/name-visitor.cc
+++ b/model/wire/ccnb/ccnb-parser/visitors/name-visitor.cc
@@ -50,8 +50,7 @@
                                                                                       )));
       break;
     default:
-      // ignore any other components
-      // when parsing Exclude, there could be <Any /> and <Bloom /> tags
+      VoidDepthFirstVisitor::visit (n, param);
       break;
     }
 }
diff --git a/model/wire/ccnb/wire-ccnb-data.cc b/model/wire/ccnb/wire-ccnb-data.cc
index 767d57b..0770c3d 100644
--- a/model/wire/ccnb/wire-ccnb-data.cc
+++ b/model/wire/ccnb/wire-ccnb-data.cc
@@ -194,8 +194,8 @@
   Ccnb::AppendCloser (start);                                    // </Signature>
 
   Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG);    // <Name>
-  Ccnb::AppendName (start, m_data->GetName()); //   <Component>...</Component>...
-  Ccnb::AppendCloser (start);                                  // </Name>
+  Ccnb::SerializeName (start, m_data->GetName());                                      //   <Component>...</Component>...
+  Ccnb::AppendCloser (start);                                                          // </Name>
 
   // fake signature
   Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_SignedInfo, CcnbParser::CCN_DTAG); // <SignedInfo>
@@ -234,7 +234,7 @@
         Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_KeyName, CcnbParser::CCN_DTAG);    // <KeyName>
         {
           Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG);       // <Name>
-          Ccnb::AppendName (start, *m_data->GetKeyLocator ());   //   <Component>...</Component>...
+          Ccnb::SerializeName (start, *m_data->GetKeyLocator ());         //   <Component>...</Component>...
           Ccnb::AppendCloser (start);                                     // </Name>
         }
         Ccnb::AppendCloser (start);                                     // </KeyName>
@@ -270,7 +270,7 @@
   written += 1;                                    // </Signature>
 
   written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name);    // <Name>
-  written += Ccnb::EstimateName (m_data->GetName ()); //   <Component>...</Component>...
+  written += Ccnb::SerializedSizeName (m_data->GetName ()); //   <Component>...</Component>...
   written += 1;                                  // </Name>
 
   // fake signature
@@ -307,7 +307,7 @@
         written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_KeyName);    // <KeyName>
         {
           written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name);       // <Name>
-          written += Ccnb::EstimateName (*m_data->GetKeyLocator ());        //   <Component>...</Component>...
+          written += Ccnb::SerializedSizeName (*m_data->GetKeyLocator ());        //   <Component>...</Component>...
           written += 1;                                               // </Name>
         }
         written += 1;                                               // </KeyName>
@@ -353,11 +353,7 @@
         {
           // process name components
           Ptr<Name> name = Create<Name> ();
-
-          BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
-            {
-              block->accept (nameVisitor, &(*name));
-            }
+          n.accept (nameVisitor, GetPointer (name));
           contentObject.SetName (name);
           break;
         }
@@ -454,17 +450,9 @@
           if (n.m_nestedTags.size ()!=1) // should be exactly one nested tag
             throw CcnbParser::CcnbDecodingException ();
 
-          Ptr<CcnbParser::BaseTag> nameTag = DynamicCast<CcnbParser::BaseTag>(n.m_nestedTags.front ());
-          if (nameTag == 0)
-            throw CcnbParser::CcnbDecodingException ();
-
           // process name components
           Ptr<Name> name = Create<Name> ();
-
-          BOOST_FOREACH (Ptr<CcnbParser::Block> block, nameTag->m_nestedTags)
-            {
-              block->accept (nameVisitor, &(*name));
-            }
+          n.accept (nameVisitor, GetPointer (name));
           contentObject.SetKeyLocator (name);
           break;
         }
diff --git a/model/wire/ccnb/wire-ccnb-interest.cc b/model/wire/ccnb/wire-ccnb-interest.cc
index 8a0ec3b..8d622a4 100644
--- a/model/wire/ccnb/wire-ccnb-interest.cc
+++ b/model/wire/ccnb/wire-ccnb-interest.cc
@@ -116,7 +116,7 @@
   Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Interest, CcnbParser::CCN_DTAG); // <Interest>
   
   Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG); // <Name>
-  Ccnb::AppendName (start, m_interest->GetName());                // <Component>...</Component>...
+  Ccnb::SerializeName (start, m_interest->GetName());                // <Component>...</Component>...
   Ccnb::AppendCloser (start);                               // </Name>
 
   // if (m_interest->GetMinSuffixComponents() >= 0)
@@ -183,7 +183,7 @@
   written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Interest); // <Interest>
   
   written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name); // <Name>
-  written += Ccnb::EstimateName (m_interest->GetName()); // <Component>...</Component>...
+  written += Ccnb::SerializedSizeName (m_interest->GetName()); // <Component>...</Component>...
   written += 1; // </Name>
 
   // if (m_interest->GetMinSuffixComponents() >= 0)
@@ -281,11 +281,7 @@
 
         // process name components
         Ptr<Name> name = Create<Name> ();
-        
-        BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
-          {
-            block->accept (nameVisitor, &(*name));
-          }
+        n.accept (nameVisitor, GetPointer (name));
         interest.SetName (name);
         break;
       }
diff --git a/model/wire/ccnb/wire-ccnb.cc b/model/wire/ccnb/wire-ccnb.cc
index 4f4f695..9033d3f 100644
--- a/model/wire/ccnb/wire-ccnb.cc
+++ b/model/wire/ccnb/wire-ccnb.cc
@@ -23,6 +23,8 @@
 #include <sstream>
 #include <boost/foreach.hpp>
 #include "ccnb-parser/common.h"
+#include "ccnb-parser/visitors/name-visitor.h"
+#include "ccnb-parser/syntax-tree/block.h"
 
 NDN_NAMESPACE_BEGIN
 
@@ -99,29 +101,6 @@
 }
 
 size_t
-Ccnb::AppendName (Buffer::Iterator &start, const Name &name)
-{
-  size_t written = 0;
-  BOOST_FOREACH (const std::string &component, name.GetComponents())
-    {
-      written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Component,
-                                   reinterpret_cast<const uint8_t*>(component.c_str()), component.size());
-    }
-  return written;
-}
-
-size_t
-Ccnb::EstimateName (const Name &name)
-{
-  size_t written = 0;
-  BOOST_FOREACH (const std::string &component, name.GetComponents())
-    {
-      written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Component, component.size());
-    }
-  return written;
-}
-
-size_t
 Ccnb::AppendTimestampBlob (Buffer::Iterator &start, const Time &time)
 {
   // the original function implements Markers... thought not sure what are these markers for...
@@ -208,6 +187,41 @@
   return EstimateBlockHeader (dtag) + EstimateBlockHeader (string.size ()) + string.size () + 1;
 }
 
+size_t
+Ccnb::SerializeName (Buffer::Iterator &start, const Name &name)
+{
+  size_t written = 0;
+  BOOST_FOREACH (const std::string &component, name.GetComponents())
+    {
+      written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Component,
+                                   reinterpret_cast<const uint8_t*>(component.c_str()), component.size());
+    }
+  return written;
+}
+
+size_t
+Ccnb::SerializedSizeName (const Name &name)
+{
+  size_t written = 0;
+  BOOST_FOREACH (const std::string &component, name.GetComponents())
+    {
+      written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Component, component.size());
+    }
+  return written;
+}
+
+Ptr<Name>
+Ccnb::DeserializeName (Buffer::Iterator &i)
+{
+  Ptr<Name> name = Create<Name> ();
+  CcnbParser::NameVisitor nameVisitor;
+
+  Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
+  root->accept (nameVisitor, GetPointer (name));
+
+  return name;
+}
+
 } // wire
 
 NDN_NAMESPACE_END
diff --git a/model/wire/ccnb/wire-ccnb.h b/model/wire/ccnb/wire-ccnb.h
index 42764c4..91d3d9e 100644
--- a/model/wire/ccnb/wire-ccnb.h
+++ b/model/wire/ccnb/wire-ccnb.h
@@ -85,24 +85,6 @@
   AppendCloser (Buffer::Iterator &start);
 
   /**
-   * @brief Append Name in CCNB encoding
-   * @param start Buffer to store serialized Interest
-   * @param name constant reference to Name object
-   *
-   * @returns written length
-   */
-  static size_t
-  AppendName (Buffer::Iterator &start, const Name &name);
-
-  /**
-   * @brief Estimate size of Name in CCNB encoding
-   * @param name constant reference to Name object
-   * @returns estimated length
-   */
-  static size_t
-  EstimateName (const Name &name);
-
-  /**
    * Append a binary timestamp as a BLOB using the ccn binary
    * Timestamp representation (12-bit fraction).
    *
@@ -187,6 +169,36 @@
    */
   static size_t
   EstimateString (uint32_t dtag, const std::string &string);
+
+  ////////////////////////////////
+  // General use wire formatters
+  ////////////////////////////////
+  
+  /**
+   * @brief Append Name in CCNB encoding
+   * @param start Buffer to store serialized Interest
+   * @param name constant reference to Name object
+   *
+   * @returns written length
+   */
+  static size_t
+  SerializeName (Buffer::Iterator &start, const Name &name);
+
+  /**
+   * @brief Estimate size of Name in CCNB encoding
+   * @param name constant reference to Name object
+   * @returns estimated length
+   */
+  static size_t
+  SerializedSizeName (const Name &name);
+
+  /**
+   * @brief Deserialize Name from CCNB encodeing
+   * @param start Buffer that stores serialized Interest
+   * @param name Name object
+   */
+  static Ptr<Name>
+  DeserializeName (Buffer::Iterator &start);
 }; // Ccnb
 
 
diff --git a/model/wire/ndnsim.cc b/model/wire/ndnsim.cc
index 2152d99..75aaf1e 100644
--- a/model/wire/ndnsim.cc
+++ b/model/wire/ndnsim.cc
@@ -3,7 +3,7 @@
  * Copyright (c) 2013, Regents of the University of California
  *                     Alexander Afanasyev
  * 
- * BSD license, See the doc/LICENSE file for more information
+ * GNU 3.0 license, See the LICENSE file for more information
  * 
  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
@@ -16,6 +16,8 @@
 #include <ns3/packet.h>
 #include <ns3/log.h>
 
+#include "ndnsim/wire-ndnsim.h"
+
 NS_LOG_COMPONENT_DEFINE ("ndn.wire.ndnSIM");
 
 NDN_NAMESPACE_BEGIN
@@ -26,84 +28,6 @@
 NS_OBJECT_ENSURE_REGISTERED (Interest);
 NS_OBJECT_ENSURE_REGISTERED (Data);
 
-
-class Name
-{
-public:
-  Name ()
-    : m_name (Create<ndn::Name> ())
-  {
-  }
-  
-  Name (Ptr<ndn::Name> name)
-    : m_name (name)
-  {
-  }
-
-  Ptr<ndn::Name>
-  GetName ()
-  {
-    return m_name;
-  }
-  
-  size_t
-  GetSerializedSize () const
-  {
-    size_t nameSerializedSize = 2;
-
-    for (std::list<std::string>::const_iterator i = m_name->begin ();
-         i != m_name->end ();
-         i++)
-      {
-        nameSerializedSize += 2 + i->size ();
-      }
-    NS_ASSERT_MSG (nameSerializedSize < 30000, "Name is too long (> 30kbytes)");
-
-    return nameSerializedSize;
-  }
-
-  uint32_t
-  Serialize (Buffer::Iterator start) const
-  {
-    Buffer::Iterator i = start;
-
-    i.WriteU16 (static_cast<uint16_t> (GetSerializedSize ()-2));
-
-    for (std::list<std::string>::const_iterator item = m_name->begin ();
-         item != m_name->end ();
-         item++)
-      {
-        i.WriteU16 (static_cast<uint16_t> (item->size ()));
-        i.Write (reinterpret_cast<const uint8_t*> (item->c_str ()), item->size ());
-      }
-
-    return i.GetDistanceFrom (start);
-  }
-
-  uint32_t
-  Deserialize (Buffer::Iterator start)
-  {
-    Buffer::Iterator i = start;
-
-    uint16_t nameLength = i.ReadU16 ();
-    while (nameLength > 0)
-      {
-        uint16_t length = i.ReadU16 ();
-        nameLength = nameLength - 2 - length;
-
-        uint8_t tmp[length];
-        i.Read (tmp, length);
-
-        m_name->Add (string (reinterpret_cast<const char*> (tmp), length));
-      }
-
-    return i.GetDistanceFrom (start);
-  }
-
-private:
-  Ptr<ndn::Name> m_name;
-};
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -179,7 +103,7 @@
   size_t size =
     1/*version*/ + 1 /*type*/ + 2/*length*/ +
     (4/*nonce*/ + 1/*scope*/ + 1/*nack type*/ + 2/*timestamp*/ +
-     (Name (ConstCast<ndn::Name> (m_interest->GetNamePtr ())).GetSerializedSize ()) +
+     NdnSim::SerializedSizeName (m_interest->GetName ()) +
      (2 + 0)/* selectors */ +
      (2 + 0)/* options */);
   
@@ -205,8 +129,7 @@
   // rounding timestamp value to seconds
   start.WriteU16 (static_cast<uint16_t> (m_interest->GetInterestLifetime ().ToInteger (Time::S)));
 
-  uint32_t offset = Name (ConstCast<ndn::Name> (m_interest->GetNamePtr ())).Serialize (start);
-  start.Next (offset);
+  NdnSim::SerializeName (start, m_interest->GetName ());
   
   start.WriteU16 (0); // no selectors
   start.WriteU16 (0); // no options
@@ -231,10 +154,7 @@
 
   m_interest->SetInterestLifetime (Seconds (i.ReadU16 ()));
 
-  Name name;
-  uint32_t offset = name.Deserialize (i);
-  m_interest->SetName (name.GetName ());
-  i.Next (offset);
+  m_interest->SetName (NdnSim::DeserializeName (i));
   
   i.ReadU16 ();
   i.ReadU16 ();
@@ -324,7 +244,9 @@
 Data::GetSerializedSize () const
 {
   uint32_t size = 1 + 1 + 2 +
-    ((2 + 2) + (Name (ConstCast<ndn::Name> (m_data->GetNamePtr ())).GetSerializedSize ()) + (2 + 2 + 4 + 2 + 2 + (2 + 0)));
+    ((2 + 2) +
+     NdnSim::SerializedSizeName (m_data->GetName ()) +
+     (2 + 2 + 4 + 2 + 2 + (2 + 0)));
   if (m_data->GetSignature () != 0)
     size += 4;
   
@@ -352,8 +274,7 @@
     }
 
   // name
-  uint32_t offset = Name (ConstCast<ndn::Name> (m_data->GetNamePtr ())).Serialize (start);
-  start.Next (offset);
+  NdnSim::SerializeName (start, m_data->GetName ());
 
   // content
   // for now assume that contentdata length is zero
@@ -396,10 +317,7 @@
   else
     throw new ContentObjectException ();
 
-  Name name;
-  uint32_t offset = name.Deserialize (i);
-  m_data->SetName (name.GetName ());
-  i.Next (offset);
+  m_data->SetName (NdnSim::DeserializeName (i));
 
   if (i.ReadU16 () != (2 + 4 + 2 + 2 + (2 + 0))) // content length
     throw new ContentObjectException ();
diff --git a/model/wire/ndnsim.h b/model/wire/ndnsim.h
index 5e50a32..186335e 100644
--- a/model/wire/ndnsim.h
+++ b/model/wire/ndnsim.h
@@ -3,7 +3,7 @@
  * Copyright (c) 2013, Regents of the University of California
  *                     Alexander Afanasyev
  * 
- * BSD license, See the doc/LICENSE file for more information
+ * GNU 3.0 license, See the LICENSE file for more information
  * 
  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
diff --git a/model/wire/ndnsim/wire-ndnsim.cc b/model/wire/ndnsim/wire-ndnsim.cc
new file mode 100644
index 0000000..7d383a4
--- /dev/null
+++ b/model/wire/ndnsim/wire-ndnsim.cc
@@ -0,0 +1,78 @@
+/** -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/* 
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ * 
+ * GNU 3.0 license, See the LICENSE file for more information
+ * 
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "wire-ndnsim.h"
+#include <boost/foreach.hpp>
+
+NDN_NAMESPACE_BEGIN
+
+namespace wire {
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+size_t
+NdnSim::SerializeName (Buffer::Iterator &i, const Name &name)
+{
+  Buffer::Iterator start = i;
+
+  i.WriteU16 (static_cast<uint16_t> (SerializedSizeName (name)-2));
+
+  for (std::list<std::string>::const_iterator item = name.begin ();
+       item != name.end ();
+       item++)
+    {
+      i.WriteU16 (static_cast<uint16_t> (item->size ()));
+      i.Write (reinterpret_cast<const uint8_t*> (item->c_str ()), item->size ());
+    }
+
+  return i.GetDistanceFrom (start);
+}
+
+size_t
+NdnSim::SerializedSizeName (const Name &name)
+{
+  size_t nameSerializedSize = 2;
+
+  for (std::list<std::string>::const_iterator i = name.begin ();
+       i != name.end ();
+       i++)
+    {
+      nameSerializedSize += 2 + i->size ();
+    }
+  NS_ASSERT_MSG (nameSerializedSize < 30000, "Name is too long (> 30kbytes)");
+
+  return nameSerializedSize;
+}
+
+Ptr<Name>
+NdnSim::DeserializeName (Buffer::Iterator &i)
+{
+  Ptr<Name> name = Create<Name> ();
+
+  uint16_t nameLength = i.ReadU16 ();
+  while (nameLength > 0)
+    {
+      uint16_t length = i.ReadU16 ();
+      nameLength = nameLength - 2 - length;
+
+      uint8_t tmp[length];
+      i.Read (tmp, length);
+
+      name->Add (std::string (reinterpret_cast<const char*> (tmp), length));
+    }
+
+  return name;
+}
+
+} // wire
+
+NDN_NAMESPACE_END
diff --git a/model/wire/ndnsim/wire-ndnsim.h b/model/wire/ndnsim/wire-ndnsim.h
new file mode 100644
index 0000000..6e4b1e5
--- /dev/null
+++ b/model/wire/ndnsim/wire-ndnsim.h
@@ -0,0 +1,62 @@
+/** -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/* 
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ * 
+ * GNU 3.0 license, See the LICENSE file for more information
+ * 
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_WIRE_NDNSIM_SYNTAX_H
+#define NDN_WIRE_NDNSIM_SYNTAX_H
+
+#include "ns3/ptr.h"
+#include "ns3/nstime.h"
+#include "ns3/buffer.h"
+
+#include "ns3/ndn-common.h"
+#include "ns3/ndn-name.h"
+
+NDN_NAMESPACE_BEGIN
+
+namespace wire {
+
+/**
+ * \brief Helper to encode ndnSIM wire elements
+ */
+class NdnSim
+{
+public:
+  /**
+   * @brief Append Name in ndnSIM encoding
+   * @param start Buffer to store serialized Interest
+   * @param name constant reference to Name object
+   *
+   * @returns written length
+   */
+  static size_t
+  SerializeName (Buffer::Iterator &start, const Name &name);
+
+  /**
+   * @brief Estimate size of Name in ndnSIM encoding
+   * @param name constant reference to Name object
+   * @returns estimated length
+   */
+  static size_t
+  SerializedSizeName (const Name &name);
+
+  /**
+   * @brief Deserialize Name from ndnSIM encodeing
+   * @param start Buffer that stores serialized Interest
+   * @param name Name object
+   */
+  static Ptr<Name>
+  DeserializeName (Buffer::Iterator &start);
+}; // NdnSim
+
+} // wire
+
+NDN_NAMESPACE_END
+
+#endif // NDN_WIRE_NDNSIM_SYNTAX_H