Debugging and resolving problems with interest serialization/deserialization
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 ();
}
}