Added readBinaryDTagElement
diff --git a/ndn-cpp/encoding/BinaryXMLDecoder.c b/ndn-cpp/encoding/BinaryXMLDecoder.c
index 89f6a9c..f9a1f3a 100644
--- a/ndn-cpp/encoding/BinaryXMLDecoder.c
+++ b/ndn-cpp/encoding/BinaryXMLDecoder.c
@@ -7,6 +7,24 @@
 #include "BinaryXML.h"
 #include "BinaryXMLDecoder.h"
 
+/**
+ * Return the octet at self->offset, converting to unsigned int.  Increment self->offset.
+ * This does not check for reading past the end of the input, so this is called "unsafe".
+ */
+static inline unsigned int unsafeReadOctet(struct ndn_BinaryXMLDecoder *self) 
+{
+  return (unsigned int)(self->input[self->offset++] & 0xff);  
+}
+
+/**
+ * Return the octet at self->offset, converting to unsigned int.  Do not increment self->offset.
+ * This does not check for reading past the end of the input, so this is called "unsafe".
+ */
+static inline unsigned int unsafeGetOctet(struct ndn_BinaryXMLDecoder *self) 
+{
+  return (unsigned int)(self->input[self->offset] & 0xff);  
+}
+
 char *ndn_BinaryXMLDecoder_decodeTypeAndValue(struct ndn_BinaryXMLDecoder *self, unsigned int *type, unsigned int *valueOut) 
 {
   unsigned int value = 0;
@@ -15,7 +33,7 @@
     if (self->offset >= self->inputLength)
       return "ndn_BinaryXMLDecoder_decodeTypeAndVal read past the end of the input";
     
-		unsigned int octet = (unsigned int)(self->input[self->offset++] & 0xff);
+		unsigned int octet = unsafeReadOctet(self);
 		
 		if (octet & ndn_BinaryXML_TT_FINAL) {
       // Finished.
@@ -28,7 +46,7 @@
 	}
 
 	*valueOut = value;
-  return (char *)0;
+  return 0;
 }
 
 char *ndn_BinaryXMLDecoder_readDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag)
@@ -45,7 +63,7 @@
   if (value != expectedTag)
     return "ndn_BinaryXMLDecoder_readDTag: did not get the expected DTAG";
   
-  return (char *)0;
+  return 0;
 }
 
 char *ndn_BinaryXMLDecoder_readElementClose(struct ndn_BinaryXMLDecoder *self)
@@ -53,12 +71,10 @@
   if (self->offset >= self->inputLength)
     return "ndn_BinaryXMLDecoder_readElementClose read past the end of the input";
   
-  unsigned int octet = (unsigned int)(self->input[self->offset++] & 0xff);
-
-  if (octet != ndn_BinaryXML_CLOSE)
+  if (unsafeReadOctet(self) != ndn_BinaryXML_CLOSE)
     return "ndn_BinaryXMLDecoder_readDTag: did not get the expected element close";
   
-  return (char *)0;
+  return 0;
 }
 
 char *ndn_BinaryXMLDecoder_peekDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *gotExpectedTag)
@@ -70,6 +86,7 @@
   unsigned int value;
   unsigned int saveOffset = self->offset;
   char *error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &type, &value);
+  // Restore offset.
   self->offset = saveOffset;
   
   if (error)
@@ -78,5 +95,38 @@
   if (type == ndn_BinaryXML_DTAG && value == expectedTag)
     *gotExpectedTag = 1;
   
-  return (char *)0;
-}
\ No newline at end of file
+  return 0;
+}
+
+char *ndn_BinaryXMLDecoder_readBinaryDTagElement
+  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int allowNull, unsigned char **value, unsigned int *valueLen)
+{
+  char *error;
+  if (error = ndn_BinaryXMLDecoder_readDTag(self, expectedTag))
+    return error;
+  
+  if (allowNull) {
+    if (self->offset >= self->inputLength)
+      return "ndn_BinaryXMLDecoder_readBinaryDTagElement read past the end of the input";
+  
+    if (unsafeGetOctet(self) == ndn_BinaryXML_CLOSE) {
+      // The binary item is missing, and this is allowed, so read the element close and return a null value.
+      ++self->offset;
+      *value = 0;
+      *valueLen = 0;
+      return 0;
+    }
+  }
+  
+  unsigned int itemType;
+  if (error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &itemType, valueLen))
+    return error;
+  // Ignore itemType.
+  *value = self->input + self->offset;
+  self->offset += *valueLen;
+  
+  if (error = ndn_BinaryXMLDecoder_readElementClose(self))
+    return error;
+  
+  return 0;
+}
diff --git a/ndn-cpp/encoding/BinaryXMLDecoder.h b/ndn-cpp/encoding/BinaryXMLDecoder.h
index ed24df7..7696541 100644
--- a/ndn-cpp/encoding/BinaryXMLDecoder.h
+++ b/ndn-cpp/encoding/BinaryXMLDecoder.h
@@ -61,6 +61,24 @@
 char *ndn_BinaryXMLDecoder_peekDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *gotExpectedTag);
 
 /**
+ * Decode the header from self's input starting at offset, expecting the type to be DTAG and the value to be expectedTag.
+ * Then read one item of any type (presumably BLOB, UDATA, TAG or ATTR) and return the item's value and length.
+ * However, if allowNull is 1, then the item may be absent.
+ * Finally, read the element close.  Update offset.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @param expectedTag the expected value for DTAG
+ * @param allowNull 1 if the binary item may be missing
+ * @param value output a pointer to the binary data inside self's input buffer. However, if allowNull is 1 and the
+ * binary data item is absent, then return 0.
+ * @param valueLen output the length of the binary data. However, if allowNull is 1 and the
+ * binary data item is absent, then return 0.
+ * @return 0 for success, else an error string, including an error if not the expected tag, or if allowNull is 0
+ * and the binary data is absent
+ */
+char *ndn_BinaryXMLDecoder_readBinaryDTagElement
+  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int allowNull, unsigned char **value, unsigned int *valueLen);
+
+/**
  * Set the offset into the input, used for the next read.
  * @param self pointer to the ndn_BinaryXMLDecoder struct
  * @param offset the new offset