Debugging and resolving problems with interest serialization/deserialization
diff --git a/helper/ccnb-parser/ccnx-decoding-helper.h b/helper/ccnb-parser/ccnx-decoding-helper.h
deleted file mode 100644
index 375a57a..0000000
--- a/helper/ccnb-parser/ccnx-decoding-helper.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- 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: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef _CCNX_DECODING_HELPER_H_
-#define _CCNX_DECODING_HELPER_H_
-
-namespace ns3 {
-
-class CcnxInterestHeader;
-class CcnxContentObjectHeader;
-
-/**
- * \brief Helper class to decode ccnb formatted CCNx message
- */
-class CcnxDecodingHelper
-{
-public:
- static size_t
- Deserialize (Buffer::Iterator start, const CcnxInterestHeader &interest);
-
- static size_t
- Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
-
-private:
-};
-
-} // namespace ns3
-
-#endif // _CCNX_DECODING_HELPER_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc
index 397e940..e4baf54 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc
@@ -28,10 +28,13 @@
Attr::Attr (Buffer::Iterator &start, uint32_t length)
{
m_attr.reserve (length+2); // extra byte for potential \0 at the end
- for (uint32_t i = 0; i < (length+1); i++)
+ uint32_t i = 0;
+ for (; !start.IsEnd () && i < (length+1); i++)
{
m_attr.push_back (start.ReadU8 ());
}
+ if (i < (length+1) && start.IsEnd ())
+ throw CcnbDecodingException ();
m_value = DynamicCast<Udata> (Block::ParseBlock (start));
if (m_value == 0)
throw CcnbDecodingException (); // "ATTR must be followed by UDATA field"
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
index 4467891..a0a112c 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
@@ -18,15 +18,30 @@
* Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
-#include "ccnb-parser-blob.h"
+#include "ns3/ccnb-parser-blob.h"
namespace ns3 {
namespace CcnbParser {
Blob::Blob (Buffer::Iterator &start, uint32_t length)
{
- m_blob = Buffer (length);
- start.Read (m_blob.Begin (), length);
+ m_blobSize = length;
+ m_blob = new char[length];
+ if (m_blob == 0 )
+ throw CcnbDecodingException (); // memory problem
+
+ uint32_t i = 0;
+ for (; !start.IsEnd () && i < length; i++)
+ {
+ m_blob[i] = start.ReadU8 ();
+ }
+ if (i < length && start.IsEnd ())
+ throw CcnbDecodingException ();
+}
+
+Blob::~Blob ()
+{
+ delete [] m_blob;
}
}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h
index 4b22d62..f2ede3d 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h
@@ -22,7 +22,6 @@
#define _CCNB_PARSER_BLOB_H_
#include "ccnb-parser-block.h"
-#include "ns3/buffer.h"
namespace ns3 {
namespace CcnbParser {
@@ -45,13 +44,15 @@
* \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
*/
Blob (Buffer::Iterator &start, uint32_t length);
+ ~Blob ();
virtual void accept( VoidNoArguVisitor &v ) { v.visit( *this ); }
virtual void accept( VoidVisitor &v, boost::any param ) { v.visit( *this, param ); }
virtual boost::any accept( NoArguVisitor &v ) { return v.visit( *this ); }
virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
- Buffer m_blob; ///< \brief field holding a parsed BLOB value of the block
+ char* m_blob; ///< \brief field holding a parsed BLOB value of the block
+ uint32_t m_blobSize;
};
}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
index e1e09fd..2af8aef 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
@@ -42,31 +42,38 @@
// We will have problems if length field is more than 32 bits. Though it's really impossible
uint8_t byte = 0;
- while (!(byte & CCN_TT_HBIT))
+ while (!start.IsEnd() && !(byte & CCN_TT_HBIT))
{
value <<= 8;
value += byte;
byte = start.ReadU8 ();
}
+ if (start.IsEnd())
+ CcnbDecodingException ();
+
value <<= 4;
value += ( (byte&(~CCN_TT_HBIT)) >> 3);
+ /**
+ * Huh. After fighting with NS-3, it became apparent that Create<T>(...) construct
+ * doesn't work with references. Just simply doesn't work. wtf?
+ */
switch (byte & CCN_TT_MASK)
{
case CCN_BLOB:
- return Create<Blob> (start, value);
+ return Ptr<Blob> (new Blob(start, value));
case CCN_UDATA:
- return Create<Udata> (start, value);
+ return Ptr<Udata> (new Udata(start, value));
case CCN_TAG:
- return Create<Tag> (start, value);
+ return Ptr<Tag> (new Tag(start, value));
case CCN_ATTR:
- return Create<Attr> (start, value);
+ return Ptr<Attr> (new Attr(start, value));
case CCN_DTAG:
- return Create<Dtag> (start, value);
+ return Ptr<Dtag> (new Dtag(start, value));
case CCN_DATTR:
- return Create<Dattr> (start, value);
+ return Ptr<Dattr> (new Dattr(start, value));
case CCN_EXT:
- return Create<Ext> (start, value);
+ return Ptr<Ext> (new Ext(start, value));
default:
throw CcnbDecodingException ();
}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc.~HEAD~ b/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc.~HEAD~
new file mode 100644
index 0000000..8d9ecf7
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc.~HEAD~
@@ -0,0 +1,76 @@
+/* -*- 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: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "ccnb-parser-dtag.h"
+
+#include "ccnb-parser-base-attr.h"
+#include "ccnb-parser-base-tag.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+Dtag::Dtag (Buffer::Iterator &start, uint32_t dtag)
+{
+ m_dtag = dtag;
+
+ /**
+ * Hack
+ *
+ * Stop processing after encountering <Content> dtag. Actual
+ * content (including virtual payload) will be stored in Packet
+ * buffer
+ */
+ if (dtag == CCN_DTAG_Content)
+ return; // hack #1. Do not process nesting block for <Content>
+
+ // parse attributes until first nested block reached
+ while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
+ {
+ Ptr<Block> block = Block::ParseBlock (start);
+ if (DynamicCast<BaseAttr> (block)!=0)
+ m_attrs.push_back (block);
+ else
+ {
+ m_nestedTags.push_back (block);
+ break;
+ }
+ }
+
+ // parse the rest of nested blocks
+ while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
+ {
+ // hack #2. Stop processing nested blocks if last block was <Content>
+ if (m_dtag == CCN_DTAG_ContentObject && // we are in <ContentObject>
+ DynamicCast<Dtag> (m_nestedTags.back())!=0 && // last block is DTAG
+ DynamicCast<Dtag> (m_nestedTags.back())->m_dtag == CCN_DTAG_Content)
+ {
+ return;
+ }
+
+ m_nestedTags.push_back (Block::ParseBlock (start));
+ }
+ if (start.IsEnd ())
+ throw CcnbDecodingException ();
+
+ start.ReadU8 (); // read CCN_CLOSE
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc
index c288be9..5862ad4 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc
@@ -28,10 +28,13 @@
Tag::Tag (Buffer::Iterator &start, uint32_t length)
{
m_tag.reserve (length+2); // extra byte for potential \0 at the end
- for (uint32_t i = 0; i < (length+1); i++)
+ uint32_t i = 0;
+ for (; !start.IsEnd () && i < (length+1); i++)
{
m_tag.push_back (start.ReadU8 ());
}
+ if (i < (length+1) && start.IsEnd ())
+ throw CcnbDecodingException ();
// parse attributes until first nested block reached
while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc
index 39217fd..91cba15 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc
@@ -32,10 +32,14 @@
m_udata.reserve (length+1); //just in case we will need \0 at the end later
// this is actually the way Read method is implemented in network/src/buffer.cc
- for (uint32_t i = 0; i < length; i++)
+ uint32_t i = 0;
+ for (; !start.IsEnd () && i < length; i++)
{
m_udata.push_back (start.ReadU8 ());
}
+
+ if (i < length && start.IsEnd ())
+ throw CcnbDecodingException ();
}
}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
index 8548598..d562695 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
@@ -35,13 +35,13 @@
// We don't really care about any other fields
void
-ContentObjectVisitor::visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader&*/)
+ContentObjectVisitor::visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader* */)
{
// uint32_t n.m_dtag;
// std::list<Ptr<Block> > n.m_nestedBlocks;
static NameComponentsVisitor nameComponentsVisitor;
- CcnxContentObjectHeader &contentObject = boost::any_cast<CcnxContentObjectHeader&> (param);
+ CcnxContentObjectHeader &contentObject = *(boost::any_cast<CcnxContentObjectHeader*> (param));
switch (n.m_dtag)
{
@@ -59,7 +59,7 @@
BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
{
- block->accept (nameComponentsVisitor, *name);
+ block->accept (nameComponentsVisitor, &(*name));
}
contentObject.SetName (name);
break;
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h
index e15e290..ae6fe9b 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h
@@ -41,7 +41,7 @@
class ContentObjectVisitor : public VoidDepthFirstVisitor
{
public:
- virtual void visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader&*/);
+ virtual void visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader* */);
};
}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
index 052cb8c..0bd0e46 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
@@ -39,7 +39,7 @@
// We don't care about any other fields
void
-InterestVisitor::visit (Dtag &n, boost::any param/*should be CcnxInterestHeader&*/)
+InterestVisitor::visit (Dtag &n, boost::any param/*should be CcnxInterestHeader* */)
{
// uint32_t n.m_dtag;
// std::list<Ptr<Block> > n.m_nestedBlocks;
@@ -49,7 +49,7 @@
static TimestampVisitor timestampVisitor;
static NonceVisitor nonceVisitor;
- CcnxInterestHeader &interest = boost::any_cast<CcnxInterestHeader&> (param);
+ CcnxInterestHeader &interest = *(boost::any_cast<CcnxInterestHeader*> (param));
switch (n.m_dtag)
{
@@ -67,7 +67,7 @@
BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
{
- block->accept (nameComponentsVisitor, *name);
+ block->accept (nameComponentsVisitor, &(*name));
}
interest.SetName (name);
break;
@@ -97,7 +97,7 @@
BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
{
- block->accept (nameComponentsVisitor, *exclude);
+ block->accept (nameComponentsVisitor, &(*exclude));
}
interest.SetExclude (exclude);
break;
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h
index 136b173..35a1e13 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h
@@ -41,7 +41,7 @@
class InterestVisitor : public VoidDepthFirstVisitor
{
public:
- virtual void visit (Dtag &n, boost::any param/*should be CcnxInterestHeader&*/);
+ virtual void visit (Dtag &n, boost::any param/*should be CcnxInterestHeader* */);
};
}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc
index 08bfe2e..314cb68 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc
@@ -28,13 +28,13 @@
namespace CcnbParser {
void
-NameComponentsVisitor::visit (Dtag &n, boost::any param/*should be CcnxNameComponents&*/)
+NameComponentsVisitor::visit (Dtag &n, boost::any param/*should be CcnxNameComponents* */)
{
// uint32_t n.m_dtag;
// std::list<Ptr<Block> > n.m_nestedBlocks;
static StringVisitor stringVisitor;
- CcnxNameComponents &components = boost::any_cast<CcnxNameComponents&> (param);
+ CcnxNameComponents &components = *(boost::any_cast<CcnxNameComponents*> (param));
switch (n.m_dtag)
{
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h
index e4b92cf..70257c5 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h
@@ -33,7 +33,7 @@
class NameComponentsVisitor : public VoidDepthFirstVisitor
{
public:
- virtual void visit (Dtag &n, boost::any param/*should be CcnxNameComponents&*/);
+ virtual void visit (Dtag &n, boost::any param/*should be CcnxNameComponents* */);
};
}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
index 7492adf..931f2fa 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
@@ -28,10 +28,10 @@
NonceVisitor::visit (Blob &n)
{
// Buffer n.m_blob;
- if (n.m_blob.GetSize ()<4)
+ if (n.m_blobSize < 4)
throw CcnbDecodingException ();
- return boost::any (n.m_blob.Begin ().ReadU32 ());
+ return boost::any (*(reinterpret_cast<uint32_t*> (n.m_blob)));
}
boost::any
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
index 33c9465..dfc61ed 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
@@ -20,6 +20,7 @@
#include "ccnb-parser-string-visitor.h"
#include "ns3/ccnb-parser-udata.h"
+#include "ns3/ccnb-parser-blob.h"
namespace ns3 {
namespace CcnbParser {
@@ -28,7 +29,7 @@
StringVisitor::visit (Blob &n)
{
// Buffer n.m_blob;
- throw CcnbDecodingException ();
+ return std::string (n.m_blob, n.m_blobSize);
}
boost::any
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h
index b2a2a29..2a1e8ed 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h
@@ -35,7 +35,7 @@
class StringVisitor : public NoArguDepthFirstVisitor
{
public:
- virtual boost::any visit (Blob &n); ///< Throws parsing error if BLOB object is encountered
+ virtual boost::any visit (Blob &n);
virtual boost::any visit (Udata &n);
};
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
index 4724bb4..22965aa 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
@@ -30,26 +30,27 @@
TimestampVisitor::visit (Blob &n)
{
// Buffer n.m_blob;
- if (n.m_blob.GetSize ()<2)
+ if (n.m_blobSize < 2)
throw CcnbDecodingException ();
- Buffer::Iterator start = n.m_blob.Begin ();
+ const char *start = n.m_blob;
intmax_t seconds = 0;
intmax_t nanoseconds = 0;
- for (uint32_t i=0; i < n.m_blob.GetSize ()-2; i++)
+ for (uint32_t i=0; i < n.m_blobSize-2; i++)
{
- seconds = (seconds << 8) | start.ReadU8 ();
+ seconds = (seconds << 8) | (uint8_t)start[i];
}
- uint8_t combo = start.ReadU8 (); // 4 most significant bits hold 4 least significant bits of number of seconds
- seconds = (seconds << 8) | (combo >> 4);
+ uint8_t combo = start[n.m_blobSize-2]; // 4 most significant bits hold 4 least significant bits of number of seconds
+ seconds = (seconds << 4) | (combo >> 4);
+ std::cout << std::hex << (int) start[n.m_blobSize-2] << "\n";
nanoseconds = combo & 0x0F; /*00001111*/ // 4 least significant bits hold 4 most significant bits of number of
- nanoseconds = (nanoseconds << 8) | start.ReadU8 ();
- nanoseconds = (intmax_t) ((nanoseconds / 4096.0/*2^12*/) * 1000000000 /*up-convert nanoseconds*/);
+ nanoseconds = (nanoseconds << 8) | start[n.m_blobSize-1];
+ nanoseconds = (intmax_t) ((nanoseconds / 4096.0/*2^12*/) * 1000000 /*up-convert useconds*/);
- return boost::any (Time::FromInteger (seconds, Time::S) + Time::FromInteger (nanoseconds, Time::NS));
+ return boost::any (Time::FromInteger (seconds, Time::S) + Time::FromInteger (nanoseconds, Time::US));
}
boost::any
diff --git a/helper/ccnx-decoding-helper.cc b/helper/ccnx-decoding-helper.cc
index 1ebb0e8..cb38f98 100644
--- a/helper/ccnx-decoding-helper.cc
+++ b/helper/ccnx-decoding-helper.cc
@@ -30,25 +30,25 @@
namespace ns3 {
size_t
-CcnxDecodingHelper::Deserialize (Buffer::Iterator start, const CcnxInterestHeader &interest)
+CcnxDecodingHelper::Deserialize (Buffer::Iterator start, CcnxInterestHeader &interest)
{
static CcnbParser::InterestVisitor interestVisitor;
Buffer::Iterator i = start;
Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
- root->accept (interestVisitor, interest);
+ root->accept (interestVisitor, &interest);
return i.GetDistanceFrom (start);
}
size_t
-CcnxDecodingHelper::Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject)
+CcnxDecodingHelper::Deserialize (Buffer::Iterator start, CcnxContentObjectHeader &contentObject)
{
static CcnbParser::ContentObjectVisitor contentObjectVisitor;
Buffer::Iterator i = start;
Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
- root->accept (contentObjectVisitor, contentObject);
+ root->accept (contentObjectVisitor, &contentObject);
return i.GetDistanceFrom (start);
}
diff --git a/helper/ccnx-decoding-helper.h b/helper/ccnx-decoding-helper.h
index 2e41769..8ebfcc5 100644
--- a/helper/ccnx-decoding-helper.h
+++ b/helper/ccnx-decoding-helper.h
@@ -36,10 +36,10 @@
{
public:
static size_t
- Deserialize (Buffer::Iterator start, const CcnxInterestHeader &interest);
+ Deserialize (Buffer::Iterator start, CcnxInterestHeader &interest);
static size_t
- Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
+ Deserialize (Buffer::Iterator start, CcnxContentObjectHeader &contentObject);
private:
};
diff --git a/helper/ccnx-encoding-helper.cc b/helper/ccnx-encoding-helper.cc
index 3dd7ad6..ded1627 100644
--- a/helper/ccnx-encoding-helper.cc
+++ b/helper/ccnx-encoding-helper.cc
@@ -29,107 +29,6 @@
namespace ns3 {
-#define CCN_TT_BITS 3
-#define CCN_TT_MASK ((1 << CCN_TT_BITS) - 1)
-#define CCN_MAX_TINY ((1 << (7-CCN_TT_BITS)) - 1)
-#define CCN_TT_HBIT ((unsigned char)(1 << 7))
-
-size_t
-CcnxEncodingHelper::AppendBlockHeader (Buffer::Iterator start, size_t val, CcnbParser::ccn_tt tt)
-{
- unsigned char buf[1+8*((sizeof(val)+6)/7)];
- unsigned char *p = &(buf[sizeof(buf)-1]);
- size_t n = 1;
- p[0] = (CCN_TT_HBIT & ~CcnbParser::CCN_CLOSE) |
- ((val & CCN_MAX_TINY) << CCN_TT_BITS) |
- (CCN_TT_MASK & tt);
- val >>= (7-CCN_TT_BITS);
- while (val != 0) {
- (--p)[0] = (((unsigned char)val) & ~CCN_TT_HBIT) | CcnbParser::CCN_CLOSE;
- n++;
- val >>= 7;
- }
- start.Write (p,n);
- return n;
-}
-
-size_t
-CcnxEncodingHelper::AppendNumber (Buffer::Iterator start, uint32_t number)
-{
- std::ostringstream os;
- os << number;
-
- size_t written = 0;
- written += AppendBlockHeader (start, os.str().size(), CcnbParser::CCN_UDATA);
- written += os.str().size();
- start.Write (reinterpret_cast<const unsigned char*>(os.str().c_str()), os.str().size());
-
- return written;
-}
-
-
-size_t
-CcnxEncodingHelper::CcnxEncodingHelper::AppendCloser (Buffer::Iterator start)
-{
- start.WriteU8 (CcnbParser::CCN_CLOSE);
- return 1;
-}
-
-size_t
-CcnxEncodingHelper::AppendNameComponents (Buffer::Iterator start, const CcnxNameComponents &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
-CcnxEncodingHelper::AppendTimestampBlob (Buffer::Iterator start, Time time)
-{
- // the original function implements Markers... thought not sure what are these markers for...
-
- // Determine miminal number of bytes required to store the timestamp
- int required_bytes = 2; // 12 bits for fractions of a second, 4 bits left for seconds. Sometimes it is enough
- intmax_t ts = time.ToInteger (Time::S) >> 4;
- for (; required_bytes < 7 && ts != 0; ts >>= 8) // not more than 6 bytes?
- required_bytes++;
-
- size_t len = AppendBlockHeader(start, required_bytes, CcnbParser::CCN_BLOB);
-
- // write part with seconds
- ts = time.ToInteger (Time::S) >> 4;
- for (int i = 0; i < required_bytes - 2; i++)
- start.WriteU8 ( ts >> (8 * (required_bytes - 3 - i)) );
-
- /* arithmetic contortions are to avoid overflowing 31 bits */
- ts = ((time.ToInteger (Time::S) & 15) << 12) + ((time.ToInteger (Time::NS) / 5 * 8 + 195312) / 390625);
- for (int i = required_bytes - 2; i < required_bytes; i++)
- start.WriteU8 ( ts >> (8 * (required_bytes - 1 - i)) );
-
- return len + required_bytes;
-}
-
-size_t
-CcnxEncodingHelper::AppendTaggedBlob (Buffer::Iterator start, CcnbParser::ccn_dtag dtag,
- const uint8_t *data, size_t size)
-{
- size_t written = AppendBlockHeader (start, dtag, CcnbParser::CCN_DTAG);
- if (size>0)
- {
- written += AppendBlockHeader (start, size, CcnbParser::CCN_BLOB);
- start.Write (data, size);
- written += size;
- }
- written += AppendCloser (start);
-
- return written;
-}
-
-
size_t
CcnxEncodingHelper::Serialize (Buffer::Iterator start, const CcnxInterestHeader &interest)
{
@@ -152,7 +51,7 @@
written += AppendNumber (start, interest.GetMaxSuffixComponents ());
written += AppendCloser (start);
}
- if (interest.GetExclude().size() > 0)
+ if (interest.IsEnabledExclude() && interest.GetExclude().size() > 0)
{
written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Exclude, CcnbParser::CCN_DTAG); // <Exclude>
written += AppendNameComponents (start, interest.GetExclude()); // <Component>...</Component>...
@@ -195,6 +94,67 @@
}
size_t
+CcnxEncodingHelper::GetSerializedSize (const CcnxInterestHeader &interest)
+{
+ size_t written = 0;
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Interest); // <Interest>
+
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Name); // <Name>
+ written += EstimateNameComponents (interest.GetName()); // <Component>...</Component>...
+ written += 1; // </Name>
+
+ if (interest.GetMinSuffixComponents() >= 0)
+ {
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_MinSuffixComponents);
+ written += EstimateNumber (interest.GetMinSuffixComponents ());
+ written += 1;
+ }
+ if (interest.GetMaxSuffixComponents() >= 0)
+ {
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_MaxSuffixComponents);
+ written += EstimateNumber (interest.GetMaxSuffixComponents ());
+ written += 1;
+ }
+ if (interest.IsEnabledExclude() && interest.GetExclude().size() > 0)
+ {
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Exclude);
+ written += EstimateNameComponents (interest.GetExclude()); // <Component>...</Component>...
+ written += 1; // </Exclude>
+ }
+ if (interest.IsEnabledChildSelector())
+ {
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_ChildSelector);
+ written += EstimateNumber (1);
+ written += 1;
+ }
+ if (interest.IsEnabledAnswerOriginKind())
+ {
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_AnswerOriginKind);
+ written += EstimateNumber (1);
+ written += 1;
+ }
+ if (interest.GetScope() >= 0)
+ {
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Scope);
+ written += EstimateNumber (interest.GetScope ());
+ written += 1;
+ }
+ if (!interest.GetInterestLifetime().IsZero())
+ {
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_InterestLifetime);
+ written += EstimateTimestampBlob (interest.GetInterestLifetime());
+ written += 1;
+ }
+ if (interest.GetNonce()>0)
+ {
+ written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Nonce, sizeof(uint32_t));
+ }
+ written += 1; // </Interest>
+
+ return written;
+}
+
+size_t
CcnxEncodingHelper::Serialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject)
{
size_t written = 0;
@@ -229,4 +189,197 @@
return written;
}
+size_t
+CcnxEncodingHelper::GetSerializedSize (const CcnxContentObjectHeader &contentObject)
+{
+ size_t written = 0;
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_ContentObject); // <ContentObject>
+
+ // fake signature
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Signature); // <Signature>
+ // Signature ::= DigestAlgorithm?
+ // Witness?
+ // SignatureBits
+ written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_SignatureBits, 0); // <SignatureBits />
+ written += 1; // </Signature>
+
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Name); // <Name>
+ written += EstimateNameComponents (contentObject.GetName()); // <Component>...</Component>...
+ written += 1; // </Name>
+
+ // fake signature
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_SignedInfo); // <SignedInfo>
+ // SignedInfo ::= PublisherPublicKeyDigest
+ // Timestamp
+ // Type?
+ // FreshnessSeconds?
+ // FinalBlockID?
+ // KeyLocator?
+ written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_PublisherPublicKeyDigest, 0); // <PublisherPublicKeyDigest />
+ written += 1; // </SignedInfo>
+
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Content); // <Content>
+
+ // there is no closing tag !!!
+ return written;
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+#define CCN_TT_BITS 3
+#define CCN_TT_MASK ((1 << CCN_TT_BITS) - 1)
+#define CCN_MAX_TINY ((1 << (7-CCN_TT_BITS)) - 1)
+#define CCN_TT_HBIT ((unsigned char)(1 << 7))
+
+size_t
+CcnxEncodingHelper::AppendBlockHeader (Buffer::Iterator &start, size_t val, CcnbParser::ccn_tt tt)
+{
+ unsigned char buf[1+8*((sizeof(val)+6)/7)];
+ unsigned char *p = &(buf[sizeof(buf)-1]);
+ size_t n = 1;
+ p[0] = (CCN_TT_HBIT & ~CcnbParser::CCN_CLOSE) |
+ ((val & CCN_MAX_TINY) << CCN_TT_BITS) |
+ (CCN_TT_MASK & tt);
+ val >>= (7-CCN_TT_BITS);
+ while (val != 0) {
+ (--p)[0] = (((unsigned char)val) & ~CCN_TT_HBIT) | CcnbParser::CCN_CLOSE;
+ n++;
+ val >>= 7;
+ }
+ start.Write (p,n);
+ return n;
+}
+
+size_t
+CcnxEncodingHelper::EstimateBlockHeader (size_t value)
+{
+ value >>= (7-CCN_TT_BITS);
+ size_t n = 1;
+ while (value>0)
+ {
+ value >>= 7;
+ n++;
+ }
+ return n;
+}
+
+size_t
+CcnxEncodingHelper::AppendNumber (Buffer::Iterator &start, uint32_t number)
+{
+ std::ostringstream os;
+ os << number;
+
+ size_t written = 0;
+ written += AppendBlockHeader (start, os.str().size(), CcnbParser::CCN_UDATA);
+ written += os.str().size();
+ start.Write (reinterpret_cast<const unsigned char*>(os.str().c_str()), os.str().size());
+
+ return written;
+}
+
+size_t
+CcnxEncodingHelper::EstimateNumber (uint32_t number)
+{
+ std::ostringstream os;
+ os << number;
+ return EstimateBlockHeader (os.str ().size ()) + os.str ().size ();
+}
+
+size_t
+CcnxEncodingHelper::AppendCloser (Buffer::Iterator &start)
+{
+ start.WriteU8 (CcnbParser::CCN_CLOSE);
+ return 1;
+}
+
+size_t
+CcnxEncodingHelper::AppendNameComponents (Buffer::Iterator &start, const CcnxNameComponents &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
+CcnxEncodingHelper::EstimateNameComponents (const CcnxNameComponents &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
+CcnxEncodingHelper::AppendTimestampBlob (Buffer::Iterator &start, const Time &time)
+{
+ // the original function implements Markers... thought not sure what are these markers for...
+
+ // Determine miminal number of bytes required to store the timestamp
+ int required_bytes = 2; // 12 bits for fractions of a second, 4 bits left for seconds. Sometimes it is enough
+ intmax_t ts = time.ToInteger (Time::S) >> 4;
+ for (; required_bytes < 7 && ts != 0; ts >>= 8) // not more than 6 bytes?
+ required_bytes++;
+
+ size_t len = AppendBlockHeader(start, required_bytes, CcnbParser::CCN_BLOB);
+
+ // write part with seconds
+ ts = time.ToInteger (Time::S) >> 4;
+ for (int i = 0; i < required_bytes - 2; i++)
+ start.WriteU8 ( ts >> (8 * (required_bytes - 3 - i)) );
+
+ /* arithmetic contortions are to avoid overflowing 31 bits */
+ ts = ((time.ToInteger (Time::S) & 15) << 12) +
+ (((time.ToInteger (Time::NS) % 1000000000) / 5 * 8 + 195312) / 390625);
+ for (int i = required_bytes - 2; i < required_bytes; i++)
+ start.WriteU8 ( ts >> (8 * (required_bytes - 1 - i)) );
+
+ return len + required_bytes;
+}
+
+size_t
+CcnxEncodingHelper::EstimateTimestampBlob (const Time &time)
+{
+ int required_bytes = 2; // 12 bits for fractions of a second, 4 bits left for seconds. Sometimes it is enough
+ intmax_t ts = time.ToInteger (Time::S) >> 4;
+ for (; required_bytes < 7 && ts != 0; ts >>= 8) // not more than 6 bytes?
+ required_bytes++;
+
+ return EstimateBlockHeader (required_bytes) + required_bytes;
+}
+
+size_t
+CcnxEncodingHelper::AppendTaggedBlob (Buffer::Iterator &start, CcnbParser::ccn_dtag dtag,
+ const uint8_t *data, size_t size)
+{
+ size_t written = AppendBlockHeader (start, dtag, CcnbParser::CCN_DTAG);
+ /* 2 */
+ if (size>0)
+ {
+ written += AppendBlockHeader (start, size, CcnbParser::CCN_BLOB);
+ start.Write (data, size);
+ written += size;
+ /* size */
+ }
+ written += AppendCloser (start);
+ /* 1 */
+
+ return written;
+}
+
+size_t
+CcnxEncodingHelper::EstimateTaggedBlob (CcnbParser::ccn_dtag dtag, size_t size)
+{
+ return EstimateBlockHeader (dtag) + EstimateBlockHeader (size) + size + 1;
+}
+
+
+
} // namespace ns3
diff --git a/helper/ccnx-encoding-helper.h b/helper/ccnx-encoding-helper.h
index 6e3c1c4..bea5087 100644
--- a/helper/ccnx-encoding-helper.h
+++ b/helper/ccnx-encoding-helper.h
@@ -46,20 +46,35 @@
Serialize (Buffer::Iterator start, const CcnxInterestHeader &interest);
static size_t
+ GetSerializedSize (const CcnxInterestHeader &interest);
+
+ static size_t
Serialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
+ static size_t
+ GetSerializedSize (const CcnxContentObjectHeader &contentObject);
+
private:
static size_t
- AppendBlockHeader (Buffer::Iterator start, size_t value, CcnbParser::ccn_tt block_type);
+ AppendBlockHeader (Buffer::Iterator &start, size_t value, CcnbParser::ccn_tt block_type);
static size_t
- AppendNumber (Buffer::Iterator start, uint32_t number);
+ EstimateBlockHeader (size_t value);
static size_t
- AppendCloser (Buffer::Iterator start);
+ AppendNumber (Buffer::Iterator &start, uint32_t number);
static size_t
- AppendNameComponents (Buffer::Iterator start, const CcnxNameComponents &name);
+ EstimateNumber (uint32_t number);
+
+ static size_t
+ AppendCloser (Buffer::Iterator &start);
+
+ static size_t
+ AppendNameComponents (Buffer::Iterator &start, const CcnxNameComponents &name);
+
+ static size_t
+ EstimateNameComponents (const CcnxNameComponents &name);
/**
* Append a binary timestamp as a BLOB using the ccn binary
@@ -71,7 +86,10 @@
* @returns written length
*/
static size_t
- AppendTimestampBlob (Buffer::Iterator start, Time time);
+ AppendTimestampBlob (Buffer::Iterator &start, const Time &time);
+
+ static size_t
+ EstimateTimestampBlob (const Time &time);
/**
* Append a tagged BLOB
@@ -86,9 +104,11 @@
* @returns written length
*/
static size_t
- AppendTaggedBlob (Buffer::Iterator start, CcnbParser::ccn_dtag dtag,
+ AppendTaggedBlob (Buffer::Iterator &start, CcnbParser::ccn_dtag dtag,
const uint8_t *data, size_t size);
+ static size_t
+ EstimateTaggedBlob (CcnbParser::ccn_dtag dtag, size_t size);
};
} // namespace ns3
diff --git a/helper/ndn_stupidinterestgenerator_helper.cc b/helper/ndn_stupidinterestgenerator_helper.cc
deleted file mode 100644
index 8fde311..0000000
--- a/helper/ndn_stupidinterestgenerator_helper.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-//
-// ndn_stupidinterestgenerator_helper.cpp
-// Abstraction
-//
-// Created by Ilya Moiseenko on 05.08.11.
-// Copyright 2011 UCLA. All rights reserved.
-//w
-
-#include "ndn_stupidinterestgenerator_helper.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/packet-socket-address.h"
-#include "ns3/string.h"
-#include "ns3/names.h"
-
-
-namespace ns3 {
-
-StupidInterestGeneratorHelper::StupidInterestGeneratorHelper (std::string protocol, Address address)
-{
- m_factory.SetTypeId ("ns3::StupidInterestGenerator");
- m_factory.Set ("Protocol", StringValue (protocol));
- m_factory.Set ("Remote", AddressValue (address));
-}
-
-void
-StupidInterestGeneratorHelper::SetAttribute (std::string name, const AttributeValue &value)
-{
- m_factory.Set (name, value);
-}
-
-ApplicationContainer
-StupidInterestGeneratorHelper::Install (Ptr<Node> node) const
-{
- return ApplicationContainer (InstallPriv (node));
-}
-
-ApplicationContainer
-StupidInterestGeneratorHelper::Install (std::string nodeName) const
-{
- Ptr<Node> node = Names::Find<Node> (nodeName);
- return ApplicationContainer (InstallPriv (node));
-}
-
-ApplicationContainer
-StupidInterestGeneratorHelper::Install (NodeContainer c) const
-{
- ApplicationContainer apps;
- for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
- {
- apps.Add (InstallPriv (*i));
- }
-
- return apps;
-}
-
-Ptr<Application>
-StupidInterestGeneratorHelper::InstallPriv (Ptr<Node> node) const
-{
- Ptr<Application> app = m_factory.Create<Application> ();
- node->AddApplication (app);
-
- return app;
-}
-
-} // namespace ns3
diff --git a/helper/ndn_stupidinterestgenerator_helper.h b/helper/ndn_stupidinterestgenerator_helper.h
deleted file mode 100644
index b8a39ca..0000000
--- a/helper/ndn_stupidinterestgenerator_helper.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; c-set-offset 'innamespace 0; -*- */
-//
-// ndn_stupidinterestgenerator_helper.h
-// Abstraction
-//
-// Created by Ilya Moiseenko on 05.08.11.
-// Copyright 2011 UCLA. All rights reserved.
-//
-
-#include "ns3/object-factory.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/node-container.h"
-#include "ns3/application-container.h"
-
-namespace ns3 {
-
- /**
- * \brief A helper to make it easier to instantiate an ns3::OnOffApplication
- * on a set of nodes.
- */
- class StupidInterestGeneratorHelper
- {
- public:
- /**
- * Create an OnOffHelper to make it easier to work with OnOffApplications
- *
- * \param protocol the name of the protocol to use to send traffic
- * by the applications. This string identifies the socket
- * factory type used to create sockets for the applications.
- * A typical value would be ns3::UdpSocketFactory.
- * \param address the address of the remote node to send traffic
- * to.
- */
- StupidInterestGeneratorHelper (std::string protocol, Address address);
-
- /**
- * Helper function used to set the underlying application attributes.
- *
- * \param name the name of the application attribute to set
- * \param value the value of the application attribute to set
- */
- void SetAttribute (std::string name, const AttributeValue &value);
-
- /**
- * Install an ns3::OnOffApplication on each node of the input container
- * configured with all the attributes set with SetAttribute.
- *
- * \param c NodeContainer of the set of nodes on which an OnOffApplication
- * will be installed.
- * \returns Container of Ptr to the applications installed.
- */
- ApplicationContainer Install (NodeContainer c) const;
-
- /**
- * Install an ns3::OnOffApplication on the node configured with all the
- * attributes set with SetAttribute.
- *
- * \param node The node on which an OnOffApplication will be installed.
- * \returns Container of Ptr to the applications installed.
- */
- ApplicationContainer Install (Ptr<Node> node) const;
-
- /**
- * Install an ns3::OnOffApplication on the node configured with all the
- * attributes set with SetAttribute.
- *
- * \param nodeName The node on which an OnOffApplication will be installed.
- * \returns Container of Ptr to the applications installed.
- */
- ApplicationContainer Install (std::string nodeName) const;
-
- private:
- /**
- * \internal
- * Install an ns3::OnOffApplication on the node configured with all the
- * attributes set with SetAttribute.
- *
- * \param node The node on which an OnOffApplication will be installed.
- * \returns Ptr to the application installed.
- */
- Ptr<Application> InstallPriv (Ptr<Node> node) const;
- std::string m_protocol;
- Address m_remote;
- ObjectFactory m_factory;
- };
-
-} // namespace ns3