checkpoint after adding readOptionalUnsignedIntegerDTagElement
diff --git a/ndn-cpp/c/encoding/BinaryXMLDecoder.c b/ndn-cpp/c/encoding/BinaryXMLDecoder.c
index 62300ff..8f74ced 100644
--- a/ndn-cpp/c/encoding/BinaryXMLDecoder.c
+++ b/ndn-cpp/c/encoding/BinaryXMLDecoder.c
@@ -25,6 +25,32 @@
   return (unsigned int)(self->input[self->offset] & 0xff);  
 }
 
+/**
+ * Parse the value as a decimal unsigned integer.  This does not check for whitespace or + sign.
+ * If valueLength is 0, this succeeds with resultOut 0.
+ * @param value
+ * @param valueLength
+ * @param resultOut output the parsed integer.
+ * @return 0 for success, else an error string, including if an element of value is not a decimal digit.
+ */
+static char *parseUnsignedDecimalInt(unsigned char *value, unsigned int valueLength, unsigned int *resultOut)
+{
+  unsigned int result = 0;
+  
+  unsigned int i;
+  for (i = 0; i < valueLength; ++i) {
+    unsigned char digit = value[i];
+    if (!(digit >= '0' && digit <= '9'))
+      return "parseUnsignedDecimalInt: element of value is not a decimal digit";
+
+    result *= 10;
+    result += (unsigned int)(digit - '0');
+  }
+    
+  *resultOut = result;
+  return 0;
+}
+
 char *ndn_BinaryXMLDecoder_decodeTypeAndValue(struct ndn_BinaryXMLDecoder *self, unsigned int *type, unsigned int *valueOut) 
 {
   unsigned int value = 0;
@@ -144,3 +170,60 @@
   
   return 0;
 }
+
+char *ndn_BinaryXMLDecoder_readUDataDTagElement
+  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, unsigned char **value, unsigned int *valueLen)
+{
+  char *error;
+  if (error = ndn_BinaryXMLDecoder_readElementStartDTag(self, expectedTag))
+    return error;
+    
+  unsigned int itemType;
+  if (error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &itemType, valueLen))
+    return error;
+  if (itemType != ndn_BinaryXML_UDATA)
+    return "ndn_BinaryXMLDecoder_readUDataDTagElement: item is not UDATA";
+  *value = self->input + self->offset;
+  self->offset += *valueLen;
+  
+  if (error = ndn_BinaryXMLDecoder_readElementClose(self))
+    return error;
+  
+  return 0;
+}
+
+char *ndn_BinaryXMLDecoder_readUnsignedIntegerDTagElement
+  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, unsigned int *value)
+{
+  unsigned char *udataValue;
+  unsigned int udataValueLength;
+  char *error;
+  if (error = ndn_BinaryXMLDecoder_readUDataDTagElement(self, expectedTag, &udataValue, &udataValueLength))
+    return error;
+  
+  if (error = parseUnsignedDecimalInt(udataValue, udataValueLength, value))
+    return error;
+  
+  return 0;
+}
+
+char *ndn_BinaryXMLDecoder_readOptionalUnsignedIntegerDTagElement
+  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *value)
+{
+  int gotExpectedTag;
+  char *error;
+  if (error = ndn_BinaryXMLDecoder_peekDTag(self, expectedTag, &gotExpectedTag))
+    return error;
+    
+  if (!gotExpectedTag) {
+    value = -1;
+    return 0;
+  }
+
+  unsigned int unsignedValue;
+  if (error = ndn_BinaryXMLDecoder_readUnsignedIntegerDTagElement(self, expectedTag, &unsignedValue))
+    return error;
+  
+  *value = (int)unsignedValue;
+  return 0;
+}
diff --git a/ndn-cpp/c/encoding/BinaryXMLDecoder.h b/ndn-cpp/c/encoding/BinaryXMLDecoder.h
index fc151a4..0c70c0b 100644
--- a/ndn-cpp/c/encoding/BinaryXMLDecoder.h
+++ b/ndn-cpp/c/encoding/BinaryXMLDecoder.h
@@ -78,6 +78,44 @@
   (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int allowNull, unsigned char **value, unsigned int *valueLen);
 
 /**
+ * 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 expecting it to be type UDATA, and return the item's value and length.
+ * Finally, read the element close.  Update offset.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @param expectedTag the expected value for DTAG
+ * @param value output a pointer to the binary data inside self's input buffer.
+ * @param valueLen output the length of the binary data.
+ * @return 0 for success, else an error string, including an error if not the expected tag, or if the item is not UDATA.
+ */
+char *ndn_BinaryXMLDecoder_readUDataDTagElement
+  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, unsigned char **value, unsigned int *valueLen);
+
+/**
+ * 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 expecting it to be type UDATA, parse it as an unsigned decimal integer and return the integer.
+ * Finally, read the element close.  Update offset.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @param expectedTag the expected value for DTAG
+ * @param value output the unsigned integer
+ * @return 0 for success, else an error string, including an error if not the expected tag, or if the item is not UDATA,
+ * or can't parse the integer
+ */
+char *ndn_BinaryXMLDecoder_readUnsignedIntegerDTagElement
+  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, unsigned int *value);
+
+/**
+ * Peek at the next element, and if it has the expectedTag then call ndn_BinaryXMLDecoder_readUnsignedIntegerDTagElement.
+ * Otherwise, set value to -1.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @param expectedTag the expected value for DTAG
+ * @param value output the unsigned integer cast to int, or -1 if the next element doesn't have expectedTag.
+ * @return 0 for success, else an error string, including an error if the item is not UDATA,
+ * or can't parse the integer
+ */
+char *ndn_BinaryXMLDecoder_readOptionalUnsignedIntegerDTagElement
+  (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *value);
+
+/**
  * Set the offset into the input, used for the next read.
  * @param self pointer to the ndn_BinaryXMLDecoder struct
  * @param offset the new offset