model: Initial attempt to optimize Interest/Data encoding/decoding via a custom packet format
diff --git a/model/ndn-content-object-header.cc b/model/ndn-content-object-header.cc
index 1a31abb..3688a89 100644
--- a/model/ndn-content-object-header.cc
+++ b/model/ndn-content-object-header.cc
@@ -22,20 +22,6 @@
 #include "ndn-content-object-header.h"
 
 #include "ns3/log.h"
-#include "../helper/ndn-encoding-helper.h"
-#include "../helper/ndn-decoding-helper.h"
-
-#include "../helper/ccnb-parser/common.h"
-#include "../helper/ccnb-parser/visitors/void-depth-first-visitor.h"
-#include "../helper/ccnb-parser/visitors/name-components-visitor.h"
-#include "../helper/ccnb-parser/visitors/non-negative-integer-visitor.h"
-#include "../helper/ccnb-parser/visitors/timestamp-visitor.h"
-#include "../helper/ccnb-parser/visitors/string-visitor.h"
-#include "../helper/ccnb-parser/visitors/uint32t-blob-visitor.h"
-#include "../helper/ccnb-parser/visitors/content-type-visitor.h"
-
-#include "../helper/ccnb-parser/syntax-tree/block.h"
-#include "../helper/ccnb-parser/syntax-tree/dtag.h"
 
 #include <boost/foreach.hpp>
 
@@ -44,10 +30,6 @@
 namespace ns3 {
 namespace ndn {
 
-using namespace CcnbParser;
-
-const std::string ContentObjectHeader::Signature::DefaultDigestAlgorithm = "2.16.840.1.101.3.4.2.1";
-
 NS_OBJECT_ENSURE_REGISTERED (ContentObjectHeader);
 NS_OBJECT_ENSURE_REGISTERED (ContentObjectTail);
 
@@ -85,323 +67,78 @@
   return m_name;
 }
 
-#define CCNB EncodingHelper // just to simplify writing
+uint32_t
+ContentObjectHeader::GetSerializedSize () const
+{
+  uint32_t size = 2 + ((2 + 1) + (m_name->GetSerializedSize ()) + (2 + 2 + 4 + 2 + 2 + (2 + 0)));
+  NS_LOG_INFO ("Serialize size = " << size);
+  return size;
+}
 
 void
 ContentObjectHeader::Serialize (Buffer::Iterator start) const
 {
-  size_t written = 0;
-  written += CCNB::AppendBlockHeader (start, CCN_DTAG_ContentObject, CCN_DTAG); // <ContentObject>
+  start.WriteU8 (0x80); // version
+  start.WriteU8 (0x01); // packet type
 
-  // fake signature
-  written += CCNB::AppendBlockHeader (start, CCN_DTAG_Signature, CCN_DTAG); // <Signature>
-  // Signature ::= √DigestAlgorithm? 
-  //               Witness?         
-  //               √SignatureBits
-  if (GetSignature ().GetDigestAlgorithm () != Signature::DefaultDigestAlgorithm)
-    {
-      written += CCNB::AppendString (start, CCN_DTAG_DigestAlgorithm, GetSignature ().GetDigestAlgorithm ());
-    }
-  written += CCNB::AppendTaggedBlob (start, CCN_DTAG_SignatureBits, GetSignature ().GetSignatureBits ()); // <SignatureBits />
-  written += CCNB::AppendCloser (start);                                    // </Signature>  
+  start.WriteU16 (2); // signature length
+  start.WriteU16 (0); // empty signature
 
-  written += CCNB::AppendBlockHeader (start, CCN_DTAG_Name, CCN_DTAG);    // <Name>
-  written += CCNB::AppendNameComponents (start, GetName()); //   <Component>...</Component>...
-  written += CCNB::AppendCloser (start);                                  // </Name>  
+  // name
+  uint32_t offset = m_name->Serialize (start);
+  start.Next (offset);
 
-  // fake signature
-  written += CCNB::AppendBlockHeader (start, CCN_DTAG_SignedInfo, CCN_DTAG); // <SignedInfo>
-  // SignedInfo ::= √PublisherPublicKeyDigest
-  //                √Timestamp
-  //                √Type?
-  //                √FreshnessSeconds?
-  //                FinalBlockID?
-  //                KeyLocator?
-  written += CCNB::AppendTaggedBlob (start, CCN_DTAG_PublisherPublicKeyDigest,         // <PublisherPublicKeyDigest>...
-                                     GetSignedInfo ().GetPublisherPublicKeyDigest ());
-  
-  written += CCNB::AppendBlockHeader (start, CCN_DTAG_Timestamp, CCN_DTAG);            // <Timestamp>...
-  written += CCNB::AppendTimestampBlob (start, GetSignedInfo ().GetTimestamp ());
-  written += CCNB::AppendCloser (start);
+  // content
+  // for now assume that contentdata length is zero
+  start.WriteU16 (2 + 4 + 2 + 2 + (2 + 0));
+  start.WriteU16 (4 + 2 + 2 + (2 + 0));
+  start.WriteU32 (static_cast<uint32_t> (m_timestamp.ToInteger (Time::S)));
+  start.WriteU16 (static_cast<uint16_t> (m_freshness.ToInteger (Time::S)));
+  start.WriteU16 (0); // reserved 
+  start.WriteU16 (0); // Length (ContentInfoOptions)
 
-  if (GetSignedInfo ().GetContentType () != DATA)
-    {
-      uint8_t type[3];
-      type[0] = (GetSignedInfo ().GetContentType () >> 16) & 0xFF;
-      type[1] = (GetSignedInfo ().GetContentType () >> 8 ) & 0xFF;
-      type[2] = (GetSignedInfo ().GetContentType ()      ) & 0xFF;
-      
-      written += CCNB::AppendTaggedBlob (start, CCN_DTAG_Type, type, 3);
-    }
-  if (GetSignedInfo ().GetFreshness () > Seconds(0))
-    {
-      written += CCNB::AppendBlockHeader (start, CCN_DTAG_FreshnessSeconds, CCN_DTAG);
-      written += CCNB::AppendNumber (start, GetSignedInfo ().GetFreshness ().ToInteger (Time::S));
-      written += CCNB::AppendCloser (start);
-    }
-  if (GetSignedInfo ().GetKeyLocator () != 0)
-    {
-      written += CCNB::AppendBlockHeader (start, CCN_DTAG_KeyLocator, CCN_DTAG); // <KeyLocator>
-      {
-        written += CCNB::AppendBlockHeader (start, CCN_DTAG_KeyName, CCN_DTAG);    // <KeyName>
-        {
-          written += CCNB::AppendBlockHeader (start, CCN_DTAG_Name, CCN_DTAG);       // <Name>
-          written += CCNB::AppendNameComponents (start, GetName());                  //   <Component>...</Component>...
-          written += CCNB::AppendCloser (start);                                     // </Name>
-        }
-        written += CCNB::AppendCloser (start);                                     // </KeyName>
-      }
-      written += CCNB::AppendCloser (start);                                     // </KeyLocator>
-    }
-  
-  written += CCNB::AppendCloser (start);                                     // </SignedInfo>
-
-  written += CCNB::AppendBlockHeader (start, CCN_DTAG_Content, CCN_DTAG); // <Content>
-
-  // there are no closing tags !!!
-  // The closing tag is handled by ContentObjectTail
+  // that's it folks
 }
 
-uint32_t
-ContentObjectHeader::GetSerializedSize () const
-{
-  size_t written = 0;
-  written += CCNB::EstimateBlockHeader (CCN_DTAG_ContentObject); // <ContentObject>
-
-  // fake signature
-  written += CCNB::EstimateBlockHeader (CCN_DTAG_Signature); // <Signature>
-  // Signature ::= DigestAlgorithm? 
-  //               Witness?         
-  //               SignatureBits   
-  if (GetSignature ().GetDigestAlgorithm () != Signature::DefaultDigestAlgorithm)
-    {
-      written += CCNB::EstimateString (CCN_DTAG_DigestAlgorithm, GetSignature ().GetDigestAlgorithm ());
-    }
-  written += CCNB::EstimateTaggedBlob (CCN_DTAG_SignatureBits,
-                                       sizeof (GetSignature ().GetSignatureBits ()));      // <SignatureBits />
-  written += 1;                                    // </Signature>  
-
-  written += CCNB::EstimateBlockHeader (CCN_DTAG_Name);    // <Name>
-  written += CCNB::EstimateNameComponents (GetName()); //   <Component>...</Component>...
-  written += 1;                                  // </Name>  
-
-  // fake signature
-  written += CCNB::EstimateBlockHeader (CCN_DTAG_SignedInfo); // <SignedInfo>
-  // SignedInfo ::= √PublisherPublicKeyDigest
-  //                √Timestamp
-  //                √Type?
-  //                √FreshnessSeconds?
-  //                FinalBlockID?
-  //                KeyLocator?
-  
-  written += CCNB::EstimateTaggedBlob (CCN_DTAG_PublisherPublicKeyDigest,                          // <PublisherPublicKeyDigest>...
-                                       sizeof (GetSignedInfo ().GetPublisherPublicKeyDigest ()));
-  
-  written += CCNB::EstimateBlockHeader (CCN_DTAG_Timestamp);                  // <Timestamp>...
-  written += CCNB::EstimateTimestampBlob (GetSignedInfo ().GetTimestamp ());
-  written += 1;
-
-  if (GetSignedInfo ().GetContentType () != DATA)
-    {
-      written += CCNB::EstimateTaggedBlob (CCN_DTAG_Type, 3);
-    }
-  if (GetSignedInfo ().GetFreshness () > Seconds(0))
-    {
-      written += CCNB::EstimateBlockHeader (CCN_DTAG_FreshnessSeconds);
-      written += CCNB::EstimateNumber (GetSignedInfo ().GetFreshness ().ToInteger (Time::S));
-      written += 1;
-    }
-
-  if (GetSignedInfo ().GetKeyLocator () != 0)
-    {
-      written += CCNB::EstimateBlockHeader (CCN_DTAG_KeyLocator); // <KeyLocator>
-      {
-        written += CCNB::EstimateBlockHeader (CCN_DTAG_KeyName);    // <KeyName>
-        {
-          written += CCNB::EstimateBlockHeader (CCN_DTAG_Name);       // <Name>
-          written += CCNB::EstimateNameComponents (GetName());        //   <Component>...</Component>...
-          written += 1;                                               // </Name>
-        }
-        written += 1;                                               // </KeyName>
-      }
-      written += 1;                                               // </KeyLocator>
-    }
-  
-  written += 1; // </SignedInfo>
-
-  written += CCNB::EstimateBlockHeader (CCN_DTAG_Content); // <Content>
-
-  // there are no closing tags !!!
-  // The closing tag is handled by ContentObjectTail
-  return written;
-}
-#undef CCNB
-
-class ContentObjectVisitor : public VoidDepthFirstVisitor
-{
-public:
-  virtual void visit (Dtag &n, boost::any param/*should be ContentObjectHeader* */)
-  {
-    // uint32_t n.m_dtag;
-    // std::list<Ptr<Block> > n.m_nestedBlocks;
-    static NameComponentsVisitor nameComponentsVisitor;
-    static NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
-    static TimestampVisitor          timestampVisitor;
-    static StringVisitor     stringVisitor;
-    static Uint32tBlobVisitor uint32tBlobVisitor;
-    static ContentTypeVisitor contentTypeVisitor;
-  
-    ContentObjectHeader &contentObject = *(boost::any_cast<ContentObjectHeader*> (param));
-  
-    switch (n.m_dtag)
-      {
-      case CCN_DTAG_ContentObject:
-        // process nested blocks
-        BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
-          {
-            block->accept (*this, param);
-          }
-        break;
-      case CCN_DTAG_Name:
-        {
-          // process name components
-          Ptr<NameComponents> name = Create<NameComponents> ();
-        
-          BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
-            {
-              block->accept (nameComponentsVisitor, &(*name));
-            }
-          contentObject.SetName (name);
-          break;
-        }
-
-      case CCN_DTAG_Signature: 
-        // process nested blocks
-        BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
-          {
-            block->accept (*this, param);
-          }      
-        break;
-
-      case CCN_DTAG_DigestAlgorithm:
-        NS_LOG_DEBUG ("DigestAlgorithm");
-        if (n.m_nestedTags.size ()!=1) // should be exactly one UDATA inside this tag
-          throw CcnbDecodingException ();
-        
-        contentObject.GetSignature ().SetDigestAlgorithm
-          (boost::any_cast<std::string> ((*n.m_nestedTags.begin())->accept
-                                         (stringVisitor)));
-        break;
-
-      case CCN_DTAG_SignatureBits:
-        NS_LOG_DEBUG ("SignatureBits");
-        if (n.m_nestedTags.size ()!=1) // should be only one nested tag
-          throw CcnbDecodingException ();
-
-        contentObject.GetSignature ().SetSignatureBits
-          (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
-                                      (uint32tBlobVisitor)));
-        break;
-
-      case CCN_DTAG_SignedInfo:
-        // process nested blocks
-        BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
-          {
-            block->accept (*this, param);
-          }      
-        break;
-      
-      case CCN_DTAG_PublisherPublicKeyDigest:
-        NS_LOG_DEBUG ("PublisherPublicKeyDigest");
-        if (n.m_nestedTags.size ()!=1) // should be only one nested tag
-          throw CcnbDecodingException ();
-
-        contentObject.GetSignedInfo ().SetPublisherPublicKeyDigest
-          (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
-                                      (uint32tBlobVisitor)));
-        break;
-
-      case CCN_DTAG_Timestamp:
-        NS_LOG_DEBUG ("Timestamp");
-        if (n.m_nestedTags.size()!=1) // should be exactly one nested tag
-          throw CcnbDecodingException ();
-
-        contentObject.GetSignedInfo ().SetTimestamp
-          (boost::any_cast<Time> ((*n.m_nestedTags.begin())->accept
-                                  (timestampVisitor)));
-        break;
-
-      case CCN_DTAG_Type:
-        NS_LOG_DEBUG ("Type");
-        if (n.m_nestedTags.size ()!=1) // should be only one nested tag
-          throw CcnbDecodingException ();
-
-        contentObject.GetSignedInfo ().SetContentType
-          (static_cast<ContentObjectHeader::ContentType>
-           (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
-                                       (contentTypeVisitor))));
-        break;
-        
-      case CCN_DTAG_FreshnessSeconds:
-        NS_LOG_DEBUG ("FreshnessSeconds");
-      
-        if (n.m_nestedTags.size()!=1) // should be exactly one nested tag
-          throw CcnbDecodingException ();
-        
-        contentObject.GetSignedInfo ().SetFreshness
-          (Seconds
-           (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
-                                       (nonNegativeIntegerVisitor))));
-        break;
-      
-      case CCN_DTAG_KeyLocator:
-        // process nested blocks
-        BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
-          {
-            block->accept (*this, param);
-          }      
-        break;
-
-      case CCN_DTAG_KeyName:
-        {
-          if (n.m_nestedTags.size ()!=1) // should be exactly one nested tag
-            throw CcnbDecodingException ();
-
-          Ptr<BaseTag> nameTag = DynamicCast<BaseTag>(n.m_nestedTags.front ());
-          if (nameTag == 0)
-            throw CcnbDecodingException ();
-
-          // process name components
-          Ptr<NameComponents> name = Create<NameComponents> ();
-        
-          BOOST_FOREACH (Ptr<Block> block, nameTag->m_nestedTags)
-            {
-              block->accept (nameComponentsVisitor, &(*name));
-            }
-          contentObject.GetSignedInfo ().SetKeyLocator (name);
-          break;
-        }
-
-      case CCN_DTAG_Content: // !!! HACK
-        // This hack was necessary for memory optimizations (i.e., content is virtual payload)
-        NS_ASSERT_MSG (n.m_nestedTags.size() == 0, "Parser should have stopped just after processing <Content> tag");
-        break;
-      
-      default: // ignore all other stuff
-        break;
-      }
-  }
-};
 
 uint32_t
 ContentObjectHeader::Deserialize (Buffer::Iterator start)
 {
-  static ContentObjectVisitor contentObjectVisitor;
-
   Buffer::Iterator i = start;
-  Ptr<Block> root = Block::ParseBlock (i);
-  root->accept (contentObjectVisitor, this);
 
+  if (i.ReadU8 () != 0x80)
+    throw new ContentObjectHeaderException ();
+
+  if (i.ReadU8 () != 0x01)
+    throw new ContentObjectHeaderException ();
+
+  if (i.ReadU16 () != 2) // signature length
+    throw new ContentObjectHeaderException ();
+  
+  if (i.ReadU16 () != 0) // signature type
+    throw new ContentObjectHeaderException ();
+
+  m_name = Create<NameComponents> ();
+  uint32_t offset = m_name->Deserialize (start);
+  i.Next (offset);
+
+  if (i.ReadU16 () != (2 + 4 + 2 + 2 + (2 + 0))) // content length
+    throw new ContentObjectHeaderException ();
+
+  if (i.ReadU16 () != (4 + 2 + 2 + (2 + 0))) // Length (content Info)
+    throw new ContentObjectHeaderException ();
+
+  m_timestamp = Seconds (i.ReadU32 ());
+  m_freshness = Seconds (i.ReadU16 ());
+
+  if (i.ReadU16 () != 0) // Reserved
+    throw new ContentObjectHeaderException ();
+  if (i.ReadU16 () != 0) // Length (ContentInfoOptions)
+    throw new ContentObjectHeaderException ();
+
+  NS_ASSERT_MSG (i.GetDistanceFrom (start) != GetSerializedSize (),
+                 "Something wrong with ContentObjectHeader::Deserialize");
+  
   return i.GetDistanceFrom (start);
 }
   
@@ -443,112 +180,24 @@
 void
 ContentObjectTail::Print (std::ostream &os) const
 {
-  os << "</Content></ContentObject>";
+  // os << "</Content></ContentObject>";
 }
 
 uint32_t
 ContentObjectTail::GetSerializedSize (void) const
 {
-  return 2;
+  return 0;
 }
 
 void
 ContentObjectTail::Serialize (Buffer::Iterator start) const
 {
-  Buffer::Iterator i = start;
-  i.Prev (2); // Trailer interface requires us to go backwards
-  
-  i.WriteU8 (0x00); // </Content>
-  i.WriteU8 (0x00); // </ContentObject>
 }
 
 uint32_t
 ContentObjectTail::Deserialize (Buffer::Iterator start)
 {
-  Buffer::Iterator i = start;
-  i.Prev (2); // Trailer interface requires us to go backwards
-
-  uint8_t closing_tag_content = i.ReadU8 ();
-  NS_ASSERT_MSG (closing_tag_content==0, "Should be a closing tag </Content> (0x00)");
-
-  uint8_t closing_tag_content_object = i.ReadU8 ();
-  NS_ASSERT_MSG (closing_tag_content_object==0, "Should be a closing tag </ContentObject> (0x00)");
-
-  return 2;
-}
-
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-
-ContentObjectHeader::SignedInfo::SignedInfo ()
-  : m_publisherPublicKeyDigest (0)
-  // ,  m_timestamp
-  , m_type (DATA)
-  // , m_freshness
-  // , FinalBlockID
-  // , KeyLocator
-{
-}
-
-void
-ContentObjectHeader::SignedInfo::SetPublisherPublicKeyDigest (uint32_t digest)
-{
-  m_publisherPublicKeyDigest = digest;
-}
-
-uint32_t
-ContentObjectHeader::SignedInfo::GetPublisherPublicKeyDigest () const
-{
-  return m_publisherPublicKeyDigest;
-}
-
-void
-ContentObjectHeader::SignedInfo::SetTimestamp (const Time &timestamp)
-{
-  m_timestamp = timestamp;
-}
-
-Time
-ContentObjectHeader::SignedInfo::GetTimestamp () const
-{
-  return m_timestamp;
-}
-
-void
-ContentObjectHeader::SignedInfo::SetContentType (ContentObjectHeader::ContentType type)
-{
-  m_type = type;
-}
-
-ContentObjectHeader::ContentType
-ContentObjectHeader::SignedInfo::GetContentType () const
-{
-  return m_type;
-}
-
-void
-ContentObjectHeader::SignedInfo::SetFreshness (const Time &freshness)
-{
-  m_freshness = freshness;
-}
-
-Time
-ContentObjectHeader::SignedInfo::GetFreshness () const
-{
-  return m_freshness;
-}
-
-void
-ContentObjectHeader::SignedInfo::SetKeyLocator (Ptr<const NameComponents> keyLocator)
-{
-  m_keyLocator = keyLocator;
-}
-
-Ptr<const NameComponents>
-ContentObjectHeader::SignedInfo::GetKeyLocator () const
-{
-  return m_keyLocator;
+  return 0;
 }
 
 } // namespace ndn