model: Returning back support for CCNb wire format
Refs #1008 (http://redmine.named-data.net/)
diff --git a/model/wire/ccnb/wire-ccnb-interest.cc b/model/wire/ccnb/wire-ccnb-interest.cc
new file mode 100644
index 0000000..8a0ec3b
--- /dev/null
+++ b/model/wire/ccnb/wire-ccnb-interest.cc
@@ -0,0 +1,451 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "../ccnb.h"
+
+#include "wire-ccnb.h"
+
+#include "ns3/log.h"
+#include "ns3/unused.h"
+#include "ns3/packet.h"
+
+#include "ccnb-parser/visitors/name-visitor.h"
+#include "ccnb-parser/visitors/non-negative-integer-visitor.h"
+#include "ccnb-parser/visitors/timestamp-visitor.h"
+#include "ccnb-parser/visitors/uint32t-blob-visitor.h"
+
+#include "ccnb-parser/syntax-tree/block.h"
+#include "ccnb-parser/syntax-tree/dtag.h"
+
+#include <boost/foreach.hpp>
+
+NS_LOG_COMPONENT_DEFINE ("ndn.wire.Ccnb.Interest");
+
+NDN_NAMESPACE_BEGIN
+
+namespace wire {
+namespace ccnb {
+
+NS_OBJECT_ENSURE_REGISTERED (Interest);
+
+TypeId
+Interest::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::ndn::Interest::Ccnb")
+ .SetGroupName ("Ndn")
+ .SetParent<Header> ()
+ .AddConstructor<Interest> ()
+ ;
+ return tid;
+}
+
+TypeId
+Interest::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+Interest::Interest ()
+ : m_interest (Create<ndn::Interest> ())
+{
+}
+
+Interest::Interest (Ptr<ndn::Interest> interest)
+ : m_interest (interest)
+{
+}
+
+Ptr<ndn::Interest>
+Interest::GetInterest ()
+{
+ return m_interest;
+}
+
+Ptr<Packet>
+Interest::ToWire (Ptr<const ndn::Interest> interest)
+{
+ Ptr<const Packet> p = interest->GetWire ();
+ if (!p)
+ {
+ Ptr<Packet> packet = Create<Packet> (*interest->GetPayload ());
+ Interest wireEncoding (ConstCast<ndn::Interest> (interest));
+ packet->AddHeader (wireEncoding);
+ interest->SetWire (packet);
+
+ p = packet;
+ }
+
+ return p->Copy ();
+}
+
+Ptr<ndn::Interest>
+Interest::FromWire (Ptr<Packet> packet)
+{
+ Ptr<ndn::Interest> interest = Create<ndn::Interest> ();
+ interest->SetWire (packet->Copy ());
+
+ Interest wireEncoding (interest);
+ packet->RemoveHeader (wireEncoding);
+
+ interest->SetPayload (packet);
+
+ return interest;
+}
+
+void
+Interest::Serialize (Buffer::Iterator start) const
+{
+ 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::AppendCloser (start); // </Name>
+
+ // if (m_interest->GetMinSuffixComponents() >= 0)
+ // {
+ // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_MinSuffixComponents, CcnbParser::CCN_DTAG);
+ // Ccnb::AppendNumber (start, m_interest->GetMinSuffixComponents ());
+ // Ccnb::AppendCloser (start);
+ // }
+ // if (m_interest->GetMaxSuffixComponents() >= 0)
+ // {
+ // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_MaxSuffixComponents, CcnbParser::CCN_DTAG);
+ // Ccnb::AppendNumber (start, m_interest->GetMaxSuffixComponents ());
+ // Ccnb::AppendCloser (start);
+ // }
+ // if (m_interest->IsEnabledExclude() && m_interest->GetExclude().size() > 0)
+ // {
+ // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Exclude, CcnbParser::CCN_DTAG); // <Exclude>
+ // Ccnb::AppendName (start, m_interest->GetExclude()); // <Component>...</Component>...
+ // Ccnb::AppendCloser (start); // </Exclude>
+ // }
+ // if (m_interest->IsEnabledChildSelector())
+ // {
+ // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_ChildSelector, CcnbParser::CCN_DTAG);
+ // Ccnb::AppendNumber (start, 1);
+ // Ccnb::AppendCloser (start);
+ // }
+ // if (m_interest->IsEnabledAnswerOriginKind())
+ // {
+ // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_AnswerOriginKind, CcnbParser::CCN_DTAG);
+ // Ccnb::AppendNumber (start, 1);
+ // Ccnb::AppendCloser (start);
+ // }
+ if (m_interest->GetScope() >= 0)
+ {
+ Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Scope, CcnbParser::CCN_DTAG);
+ Ccnb::AppendNumber (start, m_interest->GetScope ());
+ Ccnb::AppendCloser (start);
+ }
+ if (!m_interest->GetInterestLifetime().IsZero())
+ {
+ Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_InterestLifetime, CcnbParser::CCN_DTAG);
+ Ccnb::AppendTimestampBlob (start, m_interest->GetInterestLifetime ());
+ Ccnb::AppendCloser (start);
+ }
+ if (m_interest->GetNonce()>0)
+ {
+ uint32_t nonce = m_interest->GetNonce();
+ Ccnb::AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Nonce, nonce);
+ }
+
+ if (m_interest->GetNack ()>0)
+ {
+ Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Nack, CcnbParser::CCN_DTAG);
+ Ccnb::AppendNumber (start, m_interest->GetNack ());
+ Ccnb::AppendCloser (start);
+ }
+ Ccnb::AppendCloser (start); // </Interest>
+}
+
+uint32_t
+Interest::GetSerializedSize () const
+{
+ size_t written = 0;
+ 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 += 1; // </Name>
+
+ // if (m_interest->GetMinSuffixComponents() >= 0)
+ // {
+ // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_MinSuffixComponents);
+ // written += Ccnb::EstimateNumber (m_interest->GetMinSuffixComponents ());
+ // written += 1;
+ // }
+ // if (m_interest->GetMaxSuffixComponents() >= 0)
+ // {
+ // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_MaxSuffixComponents);
+ // written += Ccnb::EstimateNumber (m_interest->GetMaxSuffixComponents ());
+ // written += 1;
+ // }
+ // if (m_interest->IsEnabledExclude() && m_interest->GetExclude().size() > 0)
+ // {
+ // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Exclude);
+ // written += Ccnb::EstimateName (m_interest->GetExclude()); // <Component>...</Component>...
+ // written += 1; // </Exclude>
+ // }
+ // if (m_interest->IsEnabledChildSelector())
+ // {
+ // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_ChildSelector);
+ // written += Ccnb::EstimateNumber (1);
+ // written += 1;
+ // }
+ // if (m_interest->IsEnabledAnswerOriginKind())
+ // {
+ // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_AnswerOriginKind);
+ // written += Ccnb::EstimateNumber (1);
+ // written += 1;
+ // }
+ if (m_interest->GetScope() >= 0)
+ {
+ written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Scope);
+ written += Ccnb::EstimateNumber (m_interest->GetScope ());
+ written += 1;
+ }
+ if (!m_interest->GetInterestLifetime().IsZero())
+ {
+ written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_InterestLifetime);
+ written += Ccnb::EstimateTimestampBlob (m_interest->GetInterestLifetime());
+ written += 1;
+ }
+ if (m_interest->GetNonce()>0)
+ {
+ written += Ccnb::EstimateTaggedBlob (CcnbParser::CCN_DTAG_Nonce, sizeof(uint32_t));
+ }
+ if (m_interest->GetNack ()>0)
+ {
+ written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Nack);
+ written += Ccnb::EstimateNumber (m_interest->GetNack ());
+ written += 1;
+ }
+
+ written += 1; // </Interest>
+
+ return written;
+}
+
+class InterestVisitor : public CcnbParser::VoidDepthFirstVisitor
+{
+public:
+ virtual void visit (CcnbParser::Dtag &n, boost::any param/*should be CcnxInterest* */);
+};
+
+// We don't care about any other fields
+void
+InterestVisitor::visit (CcnbParser::Dtag &n, boost::any param/*should be Interest* */)
+{
+ // uint32_t n.m_dtag;
+ // std::list<Ptr<Block> > n.m_nestedBlocks;
+
+ static CcnbParser::NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
+ static CcnbParser::NameVisitor nameVisitor;
+ static CcnbParser::TimestampVisitor timestampVisitor;
+ static CcnbParser::Uint32tBlobVisitor nonceVisitor;
+
+ ndn::Interest &interest = *(boost::any_cast<ndn::Interest*> (param));
+
+ switch (n.m_dtag)
+ {
+ case CcnbParser::CCN_DTAG_Interest:
+ NS_LOG_DEBUG ("Interest");
+
+ // process nested blocks
+ BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
+ {
+ block->accept (*this, param);
+ }
+ break;
+ case CcnbParser::CCN_DTAG_Name:
+ {
+ NS_LOG_DEBUG ("Name");
+
+ // process name components
+ Ptr<Name> name = Create<Name> ();
+
+ BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
+ {
+ block->accept (nameVisitor, &(*name));
+ }
+ interest.SetName (name);
+ break;
+ }
+ // case CcnbParser::CCN_DTAG_MinSuffixComponents:
+ // NS_LOG_DEBUG ("MinSuffixComponents");
+ // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+ // throw CcnbParser::CcnbDecodingException ();
+ // interest.SetMinSuffixComponents (
+ // boost::any_cast<uint32_t> (
+ // (*n.m_nestedTags.begin())->accept(
+ // nonNegativeIntegerVisitor
+ // )));
+ // break;
+ // case CcnbParser::CCN_DTAG_MaxSuffixComponents:
+ // NS_LOG_DEBUG ("MaxSuffixComponents");
+ // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+ // throw CcnbParser::CcnbDecodingException ();
+ // interest.SetMaxSuffixComponents (
+ // boost::any_cast<uint32_t> (
+ // (*n.m_nestedTags.begin())->accept(
+ // nonNegativeIntegerVisitor
+ // )));
+ // break;
+ // case CcnbParser::CCN_DTAG_Exclude:
+ // {
+ // NS_LOG_DEBUG ("Exclude");
+ // // process exclude components
+ // Ptr<Name> exclude = Create<Name> ();
+
+ // BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
+ // {
+ // block->accept (nameVisitor, &(*exclude));
+ // }
+ // interest.SetExclude (exclude);
+ // break;
+ // }
+ // case CcnbParser::CCN_DTAG_ChildSelector:
+ // NS_LOG_DEBUG ("ChildSelector");
+ // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+ // throw CcnbParser::CcnbDecodingException ();
+
+ // interest.SetChildSelector (
+ // 1 == boost::any_cast<uint32_t> (
+ // (*n.m_nestedTags.begin())->accept(
+ // nonNegativeIntegerVisitor
+ // )));
+ // break;
+ // case CCN_DTAG_AnswerOriginKind:
+ // NS_LOG_DEBUG ("AnswerOriginKind");
+ // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+ // throw CcnbParser::CcnbDecodingException ();
+ // interest.SetAnswerOriginKind (
+ // 1 == boost::any_cast<uint32_t> (
+ // (*n.m_nestedTags.begin())->accept(
+ // nonNegativeIntegerVisitor
+ // )));
+ // break;
+ case CcnbParser::CCN_DTAG_Scope:
+ NS_LOG_DEBUG ("Scope");
+ if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+ throw CcnbParser::CcnbDecodingException ();
+ interest.SetScope (
+ boost::any_cast<uint32_t> (
+ (*n.m_nestedTags.begin())->accept(
+ nonNegativeIntegerVisitor
+ )));
+ break;
+ case CcnbParser::CCN_DTAG_InterestLifetime:
+ NS_LOG_DEBUG ("InterestLifetime");
+ if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+ throw CcnbParser::CcnbDecodingException ();
+
+ interest.SetInterestLifetime (
+ boost::any_cast<Time> (
+ (*n.m_nestedTags.begin())->accept(
+ timestampVisitor
+ )));
+ break;
+ case CcnbParser::CCN_DTAG_Nonce:
+ NS_LOG_DEBUG ("Nonce");
+ if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+ throw CcnbParser::CcnbDecodingException ();
+
+ interest.SetNonce (
+ boost::any_cast<uint32_t> (
+ (*n.m_nestedTags.begin())->accept(
+ nonceVisitor
+ )));
+ break;
+
+
+ case CcnbParser::CCN_DTAG_Nack:
+ NS_LOG_DEBUG ("Nack");
+ if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+ throw CcnbParser::CcnbDecodingException ();
+
+ interest.SetNack (
+ boost::any_cast<uint32_t> (
+ (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
+ break;
+ }
+}
+
+
+uint32_t
+Interest::Deserialize (Buffer::Iterator start)
+{
+ static InterestVisitor interestVisitor;
+
+ Buffer::Iterator i = start;
+ Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
+ root->accept (interestVisitor, GetPointer (m_interest));
+
+ return i.GetDistanceFrom (start);
+}
+
+void
+Interest::Print (std::ostream &os) const
+{
+ os << "I: " << m_interest->GetName ();
+
+ return;
+ // os << "<Interest>\n <Name>" << GetName () << "</Name>\n";
+ // if (GetNack ()>0)
+ // {
+ // os << " <NACK>";
+ // switch (GetNack ())
+ // {
+ // case NACK_LOOP:
+ // os << "loop";
+ // break;
+ // case NACK_CONGESTION:
+ // os << "congestion";
+ // break;
+ // default:
+ // os << "unknown";
+ // break;
+ // }
+ // os << "</NACK>\n";
+ // }
+ // if (GetMinSuffixComponents () >= 0)
+ // os << " <MinSuffixComponents>" << GetMinSuffixComponents () << "</MinSuffixComponents>\n";
+ // if (GetMaxSuffixComponents () >= 0)
+ // os << " <MaxSuffixComponents>" << m_maxSuffixComponents << "</MaxSuffixComponents>\n";
+ // if (IsEnabledExclude () && GetExclude ().size()>0)
+ // os << " <Exclude>" << GetExclude () << "</Exclude>\n";
+ // if (IsEnabledChildSelector ())
+ // os << " <ChildSelector />\n";
+ // if (IsEnabledAnswerOriginKind ())
+ // os << " <AnswerOriginKind />\n";
+ // if (GetScope () >= 0)
+ // os << " <Scope>" << GetScope () << "</Scope>\n";
+ // if ( !GetInterestLifetime ().IsZero() )
+ // os << " <InterestLifetime>" << GetInterestLifetime () << "</InterestLifetime>\n";
+ // if (GetNonce ()>0)
+ // os << " <Nonce>" << GetNonce () << "</Nonce>\n";
+ // os << "</Interest>";
+}
+
+} // ccnb
+} // wire
+
+NDN_NAMESPACE_END