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